
RS232 in bit banging quindi senza l'utilizzo della periferica uart (o usart). Ideale per applicazioni con microcontrollori a basso costo (low cost application). Ovviamente in full duplex 😉
RS232 senza UART
Gestire la comunicazione seriale (del tipo RS232) è abbastanza semplice, a patto che il microcontrollore utilizzato abbia la periferica interna, e questa sia disponibile (non utilizzata per altre comunicazioni). Con semplici istruzioni è possibile trasmettere e ricevere sfruttando i registri della periferica. A volte però per motivi di spazio, o di costo, potremmo non avere a disposizione la uart, e quindi come si fa?
Codice per la comunicazione seriale RS232 (senza uso della uart)
; Receive Routine ; receive routine = 11 instruction cycles ; including call to DelayFullBit routine Receive clrf RXTX_REG ; Clear receive register movlw BITS ; Number of bits to receive movwf COUNTER ; Load number of bits into counter register ReceiveStartBit btfsc PORTA,RX ; Test for start bit goto ReceiveStartBit ; Startbit not found call DelayHalfBit ; Wait until middle of start bit call DelayFullBit ; Ignore start-bit and sample first ; data bit in the middle of the bit ReceiveNext btfsc PORTA, RX ; Is bit a zero or a one bsf STATUS,C ; bit is a one => set carry bit btfss PORTA, RX ; Is bit a one or a zero bcf STATUS,C ; bit is a zero => clear carry bit rrf RXTX_REG, f ; Rotate receive register call DelayFullBit ; Call Delay routine decfszCOUNTER, f ; decrement receive count register by one goto ReceiveNext ; Receive next bit retlw 0x00 ; back to operation system
Questa sopra è la routine di ricezione e di seguito la routine di trasmissione
(tratte dall'application note AN712 di Microchip Technology)
; Transmit routine ; Transmits LSB first ; Software overhead =10 instruction cycles inc. call ; to DelayFullBit routine, return from ; delay routine not included) Transmit movlw BITS ; Number of bits to transmit movwf COUNTER ; Initialize count register bcf PORTA, TX ; Generate start-bit call DelayFullBit ; Generate Delay for one bit-time TransmitNext rrf RXTX_REG, f ; Rotate receive register btfsc STATUS, C ; Test bit to be transmitted bsf PORTA, TX ; Transmit one btfss STATUS, C ; Check carry bit if set bcf PORTA, TX ; Transmit a zero call DelayFullBit ; call Delay routine decfszCOUNTER, f ; Decrement count register goto TransmitNext ; Transmit next bit bsf PORTA, TX ; Generate Stop bit call DelayFullBit ; Delay for Stop bit retlw 0x00 ; Return to operating system
Come potete osservare, la ricezione seriale è molto semplice, basta fare un loop infinito nel main dove si testa sempre l'ingresso RX (polling) e quando cambia stato, chiamare (call) la relativa routine (Receive). Alla fine della ricezione, il dato sarà disponibile nel registro RXTX_REG.
Per trasmettere invece, basta fare una chiamata (call) alla relativa routine (Transmit) avendo prima caricato il dato da trasmettere nel registro.... RXTX_REG.
MA... è lo stesso registro!
Appunto, non serve utilizzare un altro registro, in quanto la comunicazione, in questo caso, potrà essere soltanto half-duplex. Quando trasmetto non posso ricevere e quando ricevo non posso trasmettere!
Come simulare via software una seriale RS232 full-duplex
Sfruttando l'interrupt del microcontrollore ed utilizzando i principi base della "macchina a stati" (multitasking) è possibile trasmettere e ricevere contemporaneamente senza utilizzare la uart (uart simulata via software)!
La comunicazione seriale simulata in Full_Duplex a 9600 BAUD con il microcontroller con ciclo macchina di 1us è possibile, eseguendo le operazioni da svolgere in interrupt e la ricezione in rolling.
La trasmissione a 9600 concede un tempo di 104us a Bit, le operazioni da svolgere vengono eseguite sotto interrupt isocrono a cicli di 25us quindi se T=104us e T/4=26us (possibile tolleranza) viene garantito il riconoscimento del byte in ricezione.
Esempio pratico: acquisire costantemente dati analogici e digitali per poi trasmetterli sulla seriale RS232 quando vengono richiesti.
In questo esempio possiamo interrogare il dispositivo e 'chiedere' il valore di un pin digitale (0 o 1) e quello di un pin analogico (da 0 a 255).
Il microcontrollore usato è un PIC12CE674. Senza periferica Uart ma con AD converter ed una eeprom interna che potrà essere eventualmente utilizzata per memorizzare i dati.

Con un protocollo facilmente configurabile, è possibile richiedere al microcontroller lo stato degli ingressi (analogico + digitale).

Il PIC 12CE674 possiede solo 1 timer (Tmr0) quindi il watchdog dovrà essere disabilitato ma, lavorando in multitask, il firmware si 'autocontrolla'.
Il funzionamento Full_Duplex è stato testato anche su piattaforma hardware con un PIC16F877 verificando la ricezione di un dato anche durante la trasmissione (full duplex).
Il campionamento degli ingressi avviene a step di 1mS alternando l'analogico e il digitale per 16 volte poi viene effettuata la media analogica e il 'debounce' digitale.
Il firmware è stato realizzato in assembler quindi facilmente adattabile a tutti i microcontrollori Microchip e di facile 'porting' anche su altri microcontroller.
ALLEGATI (per fare il download devi essere un utente registrato)
