Autor Tema: Explicação sobre SOFT_UART no Mikrobasic!!!  (Leído 3422 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado ivan braga

  • PIC12
  • **
  • Mensajes: 77
Explicação sobre SOFT_UART no Mikrobasic!!!
« en: 24 de Noviembre de 2007, 04:00:20 »
     Gostaria de compartilhar com os amigos do fórum uma excelente explicação sobre UART que achei no fórum do Mikrobasic, poderia publicar no tópico do MK aqui do forum porem alguns que passam por aqui e não usam esse software não olham muito para esse tópico. Porem os moderadores podem ficar a vontade para movê-lo se acharem melhor.

    A única coisa que fiz foi traduzir para o português e adapta-lo ao meu idioma, mais pelo seu conteúdo quero compartilhar com vocês.

    Esta explicação pode facilmente ser adaptada ate mesmo para o Proton e Pic Basic

    Espero que gostem e ajude aqueles que tenham duvidas como eu.

    Esta todo traduzido e o programa todo comentado.


     O original esta neste endereço. http://www.mikroe.com/forum/viewtopic.php?t=9280

     
   
Citar
programa Soft_Uart_GPIO

      Por Warren Schrorder
                                             traduzido por Ivan Braga

Usando mikroBasic 5.02 .. March 11, 2007
 
Repordução somente com a permissão do autor
           
   Abaixo está uma curta explicação para ajudar a um programador a criar uma versão por SOFT_UART para series microcontrollers PIC12.  Isto foi eleborado como um guia e sendo uma aproximação à teoria e à aplicação do UART.

   O código exemplo foi escritos para um 12F683 @ 4MHz.  O Baud rate da UART esta a 19200.
Os conceitos básicos dos seguintes exemplos podem ser executados com algumas mudanças para todas as famílias de PIC.
         
   O UART é um método de comunicação assíncrono que necessita de um transmissor e receptor e que tenham uma taxa comum de velocidade para comunicação, também conhecida como o baud rate, ou bit rate.

   Exige somente 2 linhas de interconexão entre o transmissor e receptor.  Desde que não haja nenhuma linha comum de sincronização, como encontrado em “comunicações sincrônicas”, o receptor deve testar o estado de sua linha de RX para cada um dos 8 “bits de dados” (um byte simples) de informação no mesmo baud rate que está sendo transmitido.
   
    Como o receptor sabe quando começar testar para os bits de dados? 
   
    Um método engenhoso é primeiro detectar um BIT de STAR, e depois seguido por 8 ou 9 bits de dados, e finalmente um BIT de STOP. A linha RX do receptor é uma linha de entrada que esta sempre HIGH pela linha de saída TX do transmissor quando não houver nenhuma comunicação.
   
    Quando o transmissor vai enviar algum dado a ele coloca a linha de transmissão em baixo “low” um bit-rate para medir o período de tempo.  Isto é o BIT START.  Na primeira detecção do BIT START o receptor é alertado e deve começar a testar a entrada de RX no baud rate esperado para cada um dos seguintes 8 ou 9 bits de dados (LSBit, primeiro bit menos significante), e sequencialmente o BIT STOP.
   
    O BIT STOP é obrigatoriamente colocado em nível elevado “HIGH” depois de ler os 8 ou 9 bits de dados.  Se o de nível elevado “HIGH” não é detectado, isto é uma indicação de um erro na transmissão.
     
    Desde que foi bit transmitido houve um período de tempo específico, é ideal testar a linha de RX no meio deste período.  Por exemplo, um baud rate 19.200 é o mesmo que 19200 bits por o segundo, ou 1 bit cada 52us (1/19200).  Como é esperado o byte de 8 bits de dados, e também os BITS de START e de STOP, então 10 testes totais de bit são executados pelo receptor “RX” durante 10 x 52us = 520us = .52ms.  Para teste no meio de um período de teste é então o mesmo que 1/2 período de bit-rate. Em nosso exemplo, 1/2 de 52us = 26us.
 
   Criar leituras confiáveis do UART, e otimiza-las aproveitando-se da caraterística como edge-triggered GP2/INT interrupção encontrada no pino de entrada do PIC12. A "interrupt-on-change”, característica esta que também está disponível em todos os pinos GPIO, exceto no MCLR.
   
   Se as interrupções não forem usadas o programador teria que estar atento e verificar o pino RX para procurar o BIT START pelo menos uma vez que cada 1 período de bit-rate, quanto antes melhor.
   
    Neste exemplo a interrupção GP2 edge-triggered é executada captando o high-to-low da transmissão.  Quando esta interrupção for habilitada e esta interrupção ocorrer->(flag = 0), ou seja, a transmissão do BIT STAR provocará o salto ao ISR  (Interrupt Service Routine). Quando dentro do ISR você pode ler o dado da transmissão.
     
        Esta é a seqüência que testará o pino RX, será uma transmissão de 8 bits de dados:
'
'       1.  Testa a linha RX para encontrar o BIT START... detecta um ponto baixo
'       2.  Período de espera 1 bit-rate
'       3.  Agora no primeiro bit de dados mas espera por um período de 1/2 bit-rate a mais ao teste.
'       4.  Testa o nível do bit 0 de dados, move à direita do buffer RX, e coloca o valor no 7ºbit do buffer de RX
'       5.  Período de espera 1 bit-rate
'       6.  Testa o nível do bit 1 de dados, move à direita do buffer RX, e coloca o valor no 7ºbit do buffer de RX
'       7.  Período de espera 1 bit-rate
'       8.  Testa o nível do bit 2 de dados, move à direita do buffer RX, e coloca o valor no 7ºbit do buffer de RX
        9.  Período de espera 1 bit-rate
'      10.  Testa o nível do bit 3 de dados, move à direita do buffer RX, e coloca o valor no 7ºbit do buffer de RX
'      11.  Período de espera 1 bit-rate
'      12.  Testa o nível do bit 4 de dados, move à direita do buffer RX, e coloca o valor no 7ºbit do buffer de RX
'      13.  Período de espera 1 bit-rate
'      14.  Testa o nível do bit 5 de dados, move à direita do buffer RX, e coloca o valor no 7ºbit do buffer de RX
'      15.  Período de espera 1 bit-rate
'      16.  Testa o nível do bit 6 de dados, move à direita do buffer RX, e coloca o valor no 7ºbit do buffer de RX
'      17.  Período de espera 1 bit-rate
'      18.  Testa o nível do bit 7 de dados, move à direita do buffer RX, e coloca o valor no 7ºbit do buffer de RX
'      19.  Período de espera 1 bit-rate
'      20.  Testa o BIT de STOP... deve ser HIGH ou é um ERRO
'


     Para a transmissão é quase a mesma a não ser que não haja nenhuma necessidade para o sincronismo de 1/2 bit-rate.

    Esta é a seqüência para enviar 8 bits de dados no pino da saída TX:
'
'       1.  Fazer a pino de TX baixo...inicia com START BIT
'       2.  Período de espera 1 bit-rate
'       3.  Le o bit 0 do buffer de TX... set/reset o pino TX respectivamente
'       4.  Período de espera 1 bit-rate
'       5.  Move à direita o TX Buffer e le bit 0 ... set/reset o pino TX respectivamente
'       6.  Período de espera 1 bit-rate
'       7.  Move à direita o TX Buffer e le bit 0 ... set/reset o pino TX respectivamente
'       8.  Período de espera 1 bit-rate
'       9.  Move à direita o TX Buffer e le bit 0 ... set/reset o pino TX respectivamente
'      10.  Período de espera 1 bit-rate
'      11.  Move à direita o TX Buffer e le bit 0 ... set/reset o pino TX respectivamente
'      12.  Período de espera 1 bit-rate
'      13.  Move à direita o TX Buffer e le bit 0 ... set/reset o pino TX respectivamente
'      14.  Período de espera 1 bit-rate
'      15.  Move à direita o TX Buffer e le bit 0 ... set/reset o pino TX respectivamente
'      16.  Período de espera 1 bit-rate
'      17.  Move à direita o TX Buffer e le bit 0 ... set/reset o pino TX respectivamente
'      18.  Período de espera 1 bit-rate
'      19.  Coloca o pino TX em HIGH... envia o STOP BIT
'
'
' O sincronismo é essencial em comunicações assíncronas.  Isto significa que o tempo para o deslocamento do bit, a leitura do bit, e as operações de bit-writing  é necessário ao cálculos de sincronismo.  Sendo assim, o período bit-rate deve ser ajustado adequadamente. Preste atenção aos comentários no seguinte código
para explanações como estes ajustes são feitos.

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

'  PROGRAMA:

' clock de Instrução é 1us (Fosc/4)
' 19200 Baud é 52us por  bit... or 52 instruções  ciclos de clock
' Importante verificar o RXBuffer aproximadamente à cada 500us

  symbol RXpin = GPIO.2                  ' GP2 tem função especial edge-interrupt
  symbol TXpin = GPIO.1                  ' TX saída
  symbol RX = 2                          ' RX número do pino
  symbol TX = 1                          ' TX número do pino

  dim RXBuffer as byte                   ' UART buffer de recepção
  dim BitCnt as byte                     ' contador do bit de dados
  dim MyByte as byte

  sub procedure interrupt                ' 11 ciclos (11us) usados a este ponto após o BIT START
   BitCnt = 8                          ' isto pode ser ajustado a 9 para transferência de 9 dados do bit
   delay_us(39)                        ' deduzir 13 ciclos (52-13=39us) para a chamada da interrupção e o carregar o "bitcnt"
   delay_us(13)                        ' 1/2 bit-rate tempo … deduz 13 ciclos para troca seguinte da move & bit transfer
   Do
      RXBuffer = RXBuffer >> 1         ' move os dados para a direita para a leitura seguinte
      RXBuffer.7 = RXpin               ' lê o pino RX e o guarda  no bit 7     
     delay_us(33)                     ' deduz 19 ciclos para a troca, a transferência do bit, e o tempo do   loop   
    Loop Until dec(BitCnt) = 0          ' nós recebemos todos os bits dos dados?
      If RX = 0 Then
      RXBuffer = 0                     ' limpa byte RX se o BIT STOP não está presente
   End If
   INTCON.INTF = 0                     ' flag de interrupção limpa... está pronto para o byte seguinte de RX
   end sub

  sub procedure TX_19200(dim TXBuffer as byte)
   INTCON.GIE = 0                      ' desabilita interrupções
   BitCnt = 0
   TXpin = 0                           ' inicia  BIT START
   delay_us(43)                        ' deduzir 9 ciclos para transferência do bit seguinte
   Do
      TXpin = TXBuffer.0               ' lê o buffer LSB e o envia     
      TXBuffer = TXBuffer >> 1         ' move o bit seguinte para posição de leitura     
      delay_us(35)                     ' deduzir 17 ciclos para a troca , a transferência do bit, e o tempo do loop
      Loop Until inc(BitCnt) = 8          ' nós transmitimos todos os bits dos dados?
      TXpin = 1                           ' inciar STOP BIT
      INTCON.GIE = 1                      ' habilita interrupções
  end sub


  sub function Read_RXBuffer as byte     ' retorna o valor de RXBuffer
     result = RXBuffer
     RXBuffer = 0                        ' limpa o buffer de RX
  end sub

  sub procedure Init
   TRISIO.RX = 1                       ' RX é entrada
   TRISIO.TX = 0                       ' TX é saida
   TXpin = 1                           ' manter o pino de TX high
   OPTION_REG = 0                      ' interrupção edge é high-to-low trigger
   ANSEL = 0                           ' ADC's off... all digital I/O
   CMCON0 = 7                          ' Comparators off... all digital I/O
   INTCON = 0                          ' GP2/INT Flag é limpo
   INTCON.GIE = 1                      ' Global interrupções habilitadas
   INTCON.INTE = 1                     ' GP2/INT habilitada
  end sub

  main:

   Init
   While true
      If RXBuffer <> 0 Then
         MyByte = Read_RXBuffer
      End If
      TX_19200($FF)
   Wend

  end.


  NOTA: O autor sugere uma mudança no codigo. Como não conheço muito bem os PICs da familia 12F não realizei esta mudança no codigo. Mas ela esta descrita aqui, qualquer coisa consultem o site original.  

   
Citar
Last line in ISR is wrong:

Citar
Change:
Code:
   INTCON.INTE = 0                     ' clear interrupt flag... be ready for next RX byte


Citar
To:
Code:
   INTCON.INTF = 0                     ' clear interrupt flag... be ready for next RX byte
« Última modificación: 24 de Noviembre de 2007, 13:54:05 por ivan braga »
"Mesmo o objeto mais inanimado tem movimento suficiente para ficar na sua frente e provocar um acidente."
"Incluso el objeto más inanimado tiene suficiente movimiento para interponerse en su camino y provocar un accidente."
"Even the most inanimate object has enough movement to stand in your way and cause an accident."

Desconectado ivan braga

  • PIC12
  • **
  • Mensajes: 77
Re: Explicação sobre SOFT_UART no Mikrobasic!!!
« Respuesta #1 en: 24 de Noviembre de 2007, 21:24:54 »
   Para complementar a explicação feita no post anterior, nada melhor que um grafico!! :mrgreen:


« Última modificación: 24 de Noviembre de 2007, 21:33:11 por ivan braga »
"Mesmo o objeto mais inanimado tem movimento suficiente para ficar na sua frente e provocar um acidente."
"Incluso el objeto más inanimado tiene suficiente movimiento para interponerse en su camino y provocar un accidente."
"Even the most inanimate object has enough movement to stand in your way and cause an accident."

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3510
Re: Explicação sobre SOFT_UART no Mikrobasic!!!
« Respuesta #2 en: 25 de Noviembre de 2007, 08:19:13 »
Esta muy interesante esta info. que estas dejando... :-)
Saludos desde Granada, España.

Desconectado xocas

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 2312
Re: Explicação sobre SOFT_UART no Mikrobasic!!!
« Respuesta #3 en: 25 de Noviembre de 2007, 10:53:58 »
muito obrigado amigo ivan braga pela informaçao...

Desconectado ivan braga

  • PIC12
  • **
  • Mensajes: 77
Re: Explicação sobre SOFT_UART no Mikrobasic!!!
« Respuesta #4 en: 25 de Noviembre de 2007, 17:22:25 »
   Olá dogflu66   e  xocas06 .

   É que em muitos momentos que estamos desenvolvendo algum programa, pegamos um que já está pronto damos uma olhada entendemos o contesto do programa, porem dificilmente entendemos o que significa  a fundo,  ou seja como hardware e software trabalham juntos.

   Me siento muy  :mrgreen: para dividir esta información aquí con todos del foro  :-/ :-/ :-/ :-/

   Ivan Braga
« Última modificación: 25 de Noviembre de 2007, 17:29:15 por ivan braga »
"Mesmo o objeto mais inanimado tem movimento suficiente para ficar na sua frente e provocar um acidente."
"Incluso el objeto más inanimado tiene suficiente movimiento para interponerse en su camino y provocar un accidente."
"Even the most inanimate object has enough movement to stand in your way and cause an accident."