La porta seriale del micro 8051

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.

Tabella 1: configurazione porta seriale

#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

Una risposta

Scrivi un commento