domingo, 16 de octubre de 2016

No se muestran correctamente los mensajes en el LCD o puerto serie


Desafortunadamente MikroC (PIC16Fxxxx) al momento de introducir textos para mostrarlos en LCD ej: lcd_out(1,1,”texto1”); o puerto serie ej: uart1_write_text(“texto1”);  la constante “texto1” se almacena en la ram del uC y solamente muestra correctamente aquellos que el compilador aloja en los bancos 0 y 1 de modo que si se tienen varios mensajes y estos son situados en los bancos 2 y 3 no se muestran correctamente.
Ejemplo 1.
sbit LCD_RS at RB2_bit;   sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;   sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;   sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;   sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;   sbit LCD_D7_Direction at TRISB7_bit;
void main()
{
   uart1_init(19200);   //velocidad del puerto serie 19200bps
   lcd_init();
   while(1)
   {
      lcd_out(1,1,"1234546789ABCDEF");
      lcd_out(2,1,"FEDCBA9876543210");
      uart1_write_text("1234567890abcdefghijk\r\n");
      uart1_write_text("1234567890abcdefghijk\r\n");
      uart1_write_text("1234567890abcdefghijk\r\n");
      uart1_write_text("1234567890abcdefghijk\r\n");
      uart1_write_text("1234567890abcdefghijk\r\n");
   }
}
En proteus tenemos.

Se puede observar que el segundo mensaje del lcd (“FEDCBA9876543210”) no es mostrado correctamente y es porque se encuentra situado en el banco 3 de la memoria ram.
Ejemplo 2.
sbit LCD_RS at RB2_bit; sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit; sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit; sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit; sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit; sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit; sbit LCD_D7_Direction at TRISB7_bit;
void main()
{
   uart1_init(19200);   //velocidad del puerto serie 19200bps
   lcd_init();
   while(1)
   {
      lcd_out(1,1,"1234546789ABCDEF");
      lcd_out(2,1,"FEDCBA9876543210");
      uart1_write_text("1234567890abcdefghijk\r\n");
      uart1_write_text("1234567890abcdefghijk\r\n");
      uart1_write_text("1234567890abcdefghijk\r\n");
      uart1_write_text("1234567890abcdefghijk\r\n");
      uart1_write_text("1234567890abcdefghijk\r\n");
      uart1_write_text("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n");
      uart1_write_text("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n");
      uart1_write_text("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n");
      uart1_write_text("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n");
      uart1_write_text("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n");
      uart1_write_text("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n");
   }
}
Aquí se observa que el compilador no informa que el microcontrolador no tiene suficiente memoria ram.
Esta situación nos limita bastante si queremos hacer un programa que contenga varios mensajes, pero a grandes problemas, grandes soluciones.
En este caso la solución está en crear una función que obliga al compilador a que nuestros mensajes sean situados en la rom y que se pasen a la ram solo cuando queramos mostrarlos.
Ejemplo 3.
char *const_ram(const char *msg)
{
   static char msg_ram[30];//reserva 30 bytes en la ram para mostrar los mensajes
   unsigned short n;
   for(n=0;*msg!=0;msg_ram[n++]=*msg++);
   return msg_ram;
}
void main()
{
   uart1_init(19200);   //velocidad del puerto serie 19200bps
   lcd_init();
   while(1)
   {
      lcd_out(1,1,const_ram("1234546789ABCDEF"));
      lcd_out(2,1,const_ram("FEDCBA9876543210"));
      uart1_write_text(const_ram("1234567890abcdefghijk\r\n"));
      uart1_write_text(const_ram("1234567890abcdefghijk\r\n"));
      uart1_write_text(const_ram("1234567890abcdefghijk\r\n"));
      uart1_write_text(const_ram("1234567890abcdefghijk\r\n"));
      uart1_write_text(const_ram("1234567890abcdefghijk\r\n"));
      uart1_write_text(const_ram("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"));
      uart1_write_text(const_ram("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"));
      uart1_write_text(const_ram("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"));
      uart1_write_text(const_ram("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"));
      uart1_write_text(const_ram("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"));
      uart1_write_text(const_ram("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"));
   }
}
Gracias a la función const_ram() y a los punteros logáramos que los mensajes se muestren correctamente sin un excesivo uso de memoria ram.

No hay comentarios.:

Publicar un comentario