Translate

viernes, 22 de junio de 2012

Comunicaciones UART con paridad

En muchos compiladores las rutinas del puerto serie asumen los valores por defecto de comunicación con 8 bits de datos y sin paridad.

Vamos a ver como, con los conocimientos adquiridos, es muy sencillo establecer una comunicación serie usando por ejemplo paridad. esto puede ser muy útil si tenemos que interactuar con un periférico que sólo soporte este tipo de comunicaciones.

Código asociado a esta entrada: uart_paridad.c
------------------------------------------------------------------------------------------------------------

El siguiente programa inicializa el puerto serie a 9600 baudios y manda repetidamente la cadena de texto "ABCD…" usando las rutinas send_byte( ):

void main()
{
 char ch;
 uint8 brgh,sp; 

 brgh=get_usart_speed(9600,20000,&sp);  setup_UART(brgh,sp);  
 //brgh_config=(brgh)? USART_BRGH_HIGH:USART_BRGH_LOW;
 //OpenUSART(USART_ASYNCH_MODE & USART_EIGHT_BIT & brgh_config, sp);
 
 while(1)
  {
   for (ch=65;ch<=90;ch++) send_byte(ch);   // ASCII from A to Z
   send_byte_parity(0x0D); send_byte(0x0A); // LF/CR
   Delay10KTCYx(250);  Delay10KTCYx(250);   // Wait for 1 second
  }
}

Si abrimos HyperTerminal (u otro terminal) y lo configuramos a 9600 veremos llegar la cadena "ABCDE … XYZ" cada segundo. Si ahora reconfiguramos en el terminal estableciendo como propiedades del puerto serie 9600 baudios, 8 bits datos, even parity y volvemos a conectarnos veremos que no se recibe nada (o tal vez algún carácter raro aislado). La razón es que nuestro terminal espera ahora un noveno bit con la correspondiente paridad, y el PIC no lo está enviando.

Una vez que hemos perdido el miedo a usar los SFR de la UART en el PIC podemos restablecer la comunicación con sólo un par de sencillos comandos. El siguiente código añade soporte para transmisión del bit de paridad. Si lo compiláis y volcáis al PIC veréis como la ristra de "ABCD…" vuelven a aparecer en vuestro terminal.

void send_byte_parity(uint8 ch)
{
 uint8 ch_org,p;

 ch_org=ch;
 p=0; while(ch) {p+=(ch&1); ch>>=1;} p&=1;

 TXSTAbits.TX9D=p;
 send_byte(ch_org);
}

void main()
{
 char ch;
 uint8 brgh,sp; 

 brgh=get_usart_speed(9600,20000,&sp);  setup_UART(brgh,sp);     
 TXSTAbits.TX9=1;       // enable ninth bit TX

 while(1)
  {
   for (ch=65;ch<=90;ch++) send_byte_parity(ch);   // ASCII from A to Z
   send_byte_parity(0x0D); send_byte_parity(0x0A); // LF/CR
   Delay10KTCYx(250);  Delay10KTCYx(250);          // Wait for 1 second
  }
}

Apenas hemos cambiado nada:

  • Tras inicializar la UART se habilita la transmisión en formato 9 bits usando el bit TX9 de TXSTA.
  • En vez de usar la antigua rutina send_byte hemos escrito otra send_byte_parity.
  • En la nueva rutina se calcula el bit de paridad (even). El datasheet de Microchip especifica que es responsabilidad del usuario que el noveno bit esté colocado en TXTSTA.TX9D antes de poner los otros 8 bits en TXREG. Por consiguiente primero colocamos el bit de paridad y luego llamamos a la vieja rutina send_byte(), que colocaba el byte dado en TXREG.

En el caso de recepción el funcionamiento sería el mismo. Se habilitaría la recepción de 9 bits (RCSTA.RX9=1) y tras cada recepción encontraríamos el noveno bit esperándonos en RCSTA.RX9D.



No hay comentarios:

Publicar un comentario