Autor Tema: MikroC 4.6, PIC16F88 y módulo LCD 2x24 HD44780  (Leído 2116 veces)

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

Desconectado 0x00

  • PIC10
  • *
  • Mensajes: 1
MikroC 4.6, PIC16F88 y módulo LCD 2x24 HD44780
« en: 17 de Julio de 2011, 17:03:59 »
¡Hola!

Estoy intentando sacar lo que me llega por la UART por el módulo LCD usando la función Lcd_Chr_CP(). El primer problema con el que me encontré es que mikroC parece trabajar bien sólo con módulos de 40 caracteres de ancho. Digo esto porque después de escribir 24 caracteres tengo que escribir 16 más (que no se muestran) para que salte de línea. Esto lo he solventado llevando manualmente la posición del cursor.

He descubierto que tengo un problema. Después de encender el montaje, cuando mando un array de bytes al PIC, sólo recibe los tres primeros, independientemente de cuantos mande. Cuando vuelvo a mandar datos ya los recibe todos. Sé que es un problema de la recepción en la UART y no a la hora de mostrarlo en el LCD porque llevo la cuenta de caracteres recibidos.

Un ejemplo. Pongamos que mando "xxxx" (sin '\n' al final). El LCD muestra "xxx". A continuación mando "xxxxxx" y el LCD muestra "xxxxxxxxx". Con el código modificado que adjunto a continuación, que muestra la cuenta de caracteres recibidos, mandando lo mismo se mostraría "123" y "123456789". Con lo que claramente hay un byte sin recibir. Lo curioso es que no me pasa sólo tras inicializar la UART, sino también al cambiar de línea en el display con Lcd_Cmd(_LCD_SECOND_ROW).

Código: [Seleccionar]
#define NROWS 2
#define NCOLS 24

sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RA0_bit;
sbit LCD_D5 at RA1_bit;
sbit LCD_D6 at RA2_bit;
sbit LCD_D7 at RA3_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISA0_bit;
sbit LCD_D5_Direction at TRISA1_bit;
sbit LCD_D6_Direction at TRISA2_bit;
sbit LCD_D7_Direction at TRISA3_bit;

void main() {
     char character;
     unsigned char col=0;
     unsigned char row=0;
     unsigned char recibidos=0;

     OSCCON=0x7E;
     ANSEL=0;
     TRISA=0;

     UART1_Init(9600);

     Lcd_Init();
     Lcd_Cmd(_LCD_CURSOR_OFF);
     Lcd_Cmd(_LCD_CLEAR);
     while(1) {
         if(UART1_Data_Ready()) {
             character = UART1_Read();
             if (0xFE !=character) {
                 if('\n'!=character) {
                     recibidos++;
                     if(0==col) {
                         if(0==row) {
                             Lcd_Cmd(_LCD_CLEAR);
                         }
                         else
                             Lcd_Cmd(_LCD_SECOND_ROW);
                     }
                    
                     Lcd_Chr_CP(recibidos+48);
                 }
                 else
                     col=NCOLS-1;

                 col++;
                 if(NCOLS==col) {
                     col=0;
                     row++;
                     if(NROWS==row)
                         row=0;
                 }
             }
             else {
                 while(!UART1_Data_Ready());
                 character = UART1_Read();
                 switch (character) {
                     case 1: Lcd_Cmd(_LCD_CLEAR); row=0; col=0; break;
                     case 2: Lcd_Cmd(_LCD_RETURN_HOME); break;
                     case 12: Lcd_Cmd(_LCD_CURSOR_OFF); break;
                     case 13: Lcd_Cmd(_LCD_BLINK_CURSOR_ON); break;
                     case 14: Lcd_Cmd(_LCD_UNDERLINE_ON); break;
                     case 16: Lcd_Cmd(_LCD_MOVE_CURSOR_LEFT);
                              col--;
                              if(NCOLS<col) {
                                  col=NCOLS-1;
                                  row--;
                                  if(NROWS<row)
                                      row=0;
                              }
                              break;
                     case 20: Lcd_Cmd(_LCD_MOVE_CURSOR_RIGHT);
                              col++;
                              if(NCOLS==col) {
                                  col=0;
                                  row++;
                                  if(NROWS==row)
                                      row=0;
                              }
                              break;
                     case 24: Lcd_Cmd(_LCD_SHIFT_LEFT); break;
                     case 28: Lcd_Cmd(_LCD_SHIFT_RIGHT); break;
                     case 192: Lcd_Cmd(_LCD_SECOND_ROW); row=1; col=0; break;
                 }
             }
         }
     }
}

En un primer momento pensé que fuera que el buffer de recepción de la UART desbordara, pero no se explica que lo de recibir sólo tres bytes sea sólo en la primera transmisión y no en las demás.

Por si sirve de algo, así es como mando los datos:

Código: [Seleccionar]
echo -n xxxx >/dev/ttyS1
echo -n xxxxxx >/dev/ttyS1

Y esta es la configuración de la UART de mi PC según stty:

Código: [Seleccionar]
$ stty -F /dev/ttyS1
speed 9600 baud; line = 0;
min = 1; time = 0;
-brkint -icrnl ixoff -imaxbel
-opost -onlcr
-isig -icanon -iexten -echo -echoe

Ya sé que igual usando interrupciones en vez de polling me quitaría de problemas, pero quisiera saber por qué ocurre esto.

Desconectado tannke

  • PIC16
  • ***
  • Mensajes: 176
Re: MikroC 4.6, PIC16F88 y módulo LCD 2x24 HD44780
« Respuesta #1 en: 21 de Julio de 2011, 08:36:10 »
Muy buenas, sobre tu 1er problema a mi entender no es problema de mikroC sino de los LCD, me imagino que es para utilizar el mismo hard en todos. Por otro lado el tema de la USART lo mas probable es que sea un problema de tiempos, ya que las operaciones de lcd en algunos casos son algo largas, a esto la solución podria ser o leer todo lo que vayas a recibir en un buffer (matriz) y luego procesarlo, o enviar los bytes algo separados entre ellos.

Un saludo


 

anything