Come configurare la porta seriale di un 8051 per selezionare una delle quattro modalità di funzionamento.
La periferica di comunicazione seriale del microcontrollore 8051 prevede quattro diverse modalità di funzionamento, le più impiegate sono quelle che consentono di utilizzare il baudrate variabile:
- Modo1, il formato del dato trasmesso è 1bit start + 8bit data +1 bit stop.
- Modo3, il formato del dato trasmesso è 1bit start + 9bit data +1 bit stop.
In entrambi i casi i bit di start e stop sono aggiunti automaticamente dalla periferica rispettivamente all’inizio e alla fine di ogni byte inviato. Il registro SFR di configurazione della periferica è S0CON (figura 1), i bit TB8 e RB8 di questo registro sono utilizzati rispettivamente come nono bit trasmesso e nono bit ricevuto in Modo3. La periferica non prevede la gestione hardware del bit di parità, o la comunicazione con due bit di stop oppure con formato 7databit, queste funzioni perciò si devono rispettivamente il numero di databit e il numero dei bit di stop utilizzati nella comunicazione. Se si desidera aggiungere il bit di parità o un secondo bit di stop al dato inviato/ricevuto nella comunicazione con 8databit si deve configurare la periferica in modo3 comunicazione a 9bit, mentre se si utilizzano solo 7databit si può aggiungere il bit di parità o il secondo bit di stop come bit più significativo del byte inviato/ricevuto e configurare la periferica per comunicazione a 8bit, Modo1.
Utilizzare due bit di stop è relativamente semplice: nella comunicazione a 7databit prima di trasmettere un byte si deve eseguire l’operazione Or txbyte,#80h ed eventualmente controllare in ricezione il bit più significativo del byte ricevuto. Si ricordi che l’hardware della periferica controlla sempre e solo 1 bit di stop. La tabella 1 elenca tutte le possibili configurazioni della porta seriale che si possono realizzare con il firmware del listato 1. Nella prima colonna della tabella viene riportata la stringa di codifica della configurazione della porta. BAUD indica la velocità di comunicazione (es. 9600), la seconda lettera la parità e i due numeri finali 8databit il bit TB8 = 1 è il bit di stop aggiuntivo trasmesso mentre il bit RB8 è il bit di stop aggiuntivo ricevuto. Il discorso è analogo per il bit di parità che una volta calcolato dovrà essere aggiunto come bit più significativo del byte inviato nel caso di comunicazione a 7databit e come nono bit in TB8/RB8 per comunicazione a 8databit.
La periferica UART prevede quattro possibili configurazioni per il bit di parità: Even (pari) il bit di parità è 1 se il byte inviato contiene un numero dispari di bit a 1 Odd (dispari) il bit di parità è 1 se il byte inviato contiene un numero pari di bit a 1 Mark il bit di parità è sempre 1 Space il bit di parità è sempre 0 Le parità mark e space si applicano facilmente in modo analogo a quanto descritto per il doppio bit di stop. Negli altri due casi si deve calcolare il bit di parità contando i bit a 1 di ogni byte inviato/ricevuto. Per fare questo si ricorre al flag P del registro PSW (Program Status Word) del microcontrollore 8051. Il bit P è 1 se l’accumulatore contiene un numero dispari di bit a 1 e viceversa P=0 se l’accumulatore contiene un numero pari di bit a 1. Il flag P corrisponde quindi alla parità Even mentre il suo negato corrisponde alla parità Odd. Per calcolare il valore del bit di parità basterà quindi spostare il dato da trasmettere o il dato ricevuto nell’accumulatore per aggior nare il flag P ed eventualmente negare il suo valore per parità Odd. Un’ultima osservazione utilizzando solo 7databit, quando si riceve un byte il bit di parità viene trasferito nell’accumulatore assieme al dato, perciò per verificare la parità basta controllare il valore del flag P che sarà P=0 per comunicazione con parità even e viceversa P=1 per comunicazione con parità odd.
#define PARITYNONE 0 #define PARITYODD 1 #define PARITEVEN 2 #define PARITYMARK 3 #define PARITYSPACE 4 #define PARITY PARITYNONE #define DATABIT 8 #define STOPBIT 1 unsigned char data ch ; unsigned char bdata errflags sbit FERRPY = errflags ^ 1 ; sbit FERRFR = errflags ^ 2 ; void MBUSisr() interrupt UARTISR { //////////// Uart RX char if (URI) { URI = 0 ; ch = USBUF ; // read char from uart // parity ODD #if (PARITY == PARITYODD) #pragma asm mov A,ch #pragma endasm #if (DATABIT == 8) if (!(P ^ URB8)) FEERPY = 1; #else if (P == 0) FEERPY = 1; ch &= 0x7F ; #endif #endif // if parity EVEN #if (PARITY == PARITYEVEN) #pragma asm mov A,ch #pragma endasm #if (DATABIT == 8) if (P ^ URB8) FERRPY = 1 ; #else if (P == 1) FERRPY = 1 ; ch &= 0x7F ; #endif #endif // if parity MARK #if (PARITY == PARITYMARK) #if (DATABIT == 8) if (URB8 == 0) FERRPY = 1 ; #else if ((ch & 0x80) == 0) FERRPY = 1 ; #endif #endif // if parity SPACE #if (PARITY == PARITYSPACE) #if (DATABIT == 8) if (URB8 == 1) FERRPY = 1; #else if ((ch & 0x80) != 0) FERRPY = 1; #endif #endif // check frame error #if (STOPBIT == 2) #if (DATABIT == 8) if (URB8 == 0) FERRFR = 1 ; #else if (PARITY == PARITYNONE) if ((ch & 0x80) == 0) FERRFR = 1; #else if (URB8 == 0) FERRFR = 1 ; #endif #endif } if (UTI) { UTI = 0 ; // ch next tx char // parity ODD #if (PARITY == PARITYODD) #pragma asm mov A,ch #pragma endasm #if (MBUScfg_BIT == 8) UTB8 = !P ; #else if (!P) ch |= 0x80 ; #endif // if parity EVEN #if (PARITY == PARITYEVEN) #pragma asm mov A,ch #pragma endasm #if (MBUScfg_BIT == 8) UTB8 = P ; #else if (P) ch |= 0x80 ; #endif // if parity MARK #if (PARITY == PARITYMARK) #if (MBUScfg_BIT == 8) UTB8 = 1 ; #else ch |= 0x80 ; #endif // if parity SPACE #if (PARITY == PARITYSPACE) #if (MBUScfg_BIT == 8) UTB8 = 0 ; #else ch &= 0x7F ; #endif #endif #if (STOPBIT == 2) #if (DATABIT == 8) URB8 = 1 ; #else if (PARITY == PARITYNONE) ch |= 0x80 ; #else URB8 = 1 ; #endif #endif USBUF = ch ; // OK to send }
Listato 1 |
A proposito di RS232 vi segnalo questo articolo http://it.emcelettronica.com/alla-scoperta-dellrs232