TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: japifer_22 en 10 de Abril de 2009, 02:53:51

Título: mover frase largas en lcd de 16x2
Publicado por: japifer_22 en 10 de Abril de 2009, 02:53:51
hola como estan bueno les comento que estoy asiendo un programita que tiene que mover una frase de 48 caracteres pero lo raro es que en proteurs me funciona bien pero a la hora que lo programo en el pic y lo veo en pa lcd aparese mal.
bueno estoy usandoel compilador ccs c y trabajo con el pic 16f873a mas una pantalla de 16x2.
bueno les comento un poco mejor.
bueno en la primera columna estoy sacando un valor de medision y en la segunda columna estoy pasando un mensaje que se repite siempre. pero este mensaje se sube a la primera colunma como en la mitad de la frase y se pone ensima del valor de medicion y, no se por que, y  en proteurs no lo hace la rutina para mover la palabra es la siguiente:

signed char x=16;
 while(TRUE)
{

lcd_gotoxy( 1, 1);
  printf(lcd_putc,"%1.2f voltios", voltios );
  printf(lcd_putc,"\b");//retrasa el cursor una posicion
  printf("%1.2f voltios", voltios );

 lcd_gotoxy(x,2) ;      //cursor para escribir mensaje
      printf(lcd_putc,"!Voltimetro **XXXX XXXXX//XXXXXXXXXXXXXX**!    ") ;   //muestra por pantalla el mensaje
      delay_ms(100);//tiempo de rotacion del mensaje         
      x--;               //decrementa indice de filas
      if(x==-48){            //¿ya se ha mostrado mensaje entero por 2ºfila?
      x=16;
      }}

de otra forma lo que pasa es cuando inicia el programa marcha todo bien el mensaje pero cuando esta en la mitad +- se sube este mensaje a la primera columna y no se por que si me pudieran ayudar con el codigo se los agradeseria bueno grasis nos tamos ablando.
Título: Re: mover frase largas en lcd de 16x2
Publicado por: therionx en 10 de Abril de 2009, 03:51:25
yo tenia un problema parecido :D y logre arreglarlo modificando los delays, si dices q te funciona en proteus, solo modifica los delays y en fisico deberia funcionarte
Título: Re: mover frase largas en lcd de 16x2
Publicado por: Nocturno en 10 de Abril de 2009, 04:32:42
Me da la impresión de que el segundo mensaje lo escribes más allá de los límites de los caracteres del LCD, y por eso los que no caben en la pantalla, salen donde pueden. En tu caso están saliendo en la primera fila.

Prueba a enviar sólo los caracteres que quepan, modificando la instrucción siguiente de manera que el string sea de longitud variable.
printf(lcd_putc,"!Voltimetro **XXXX XXXXX//XXXXXXXXXXXXXX**!    ") ;   //muestra por pantalla el mensaje
Título: Re: mover frase largas en lcd de 16x2
Publicado por: MLO__ en 10 de Abril de 2009, 12:39:00
Hola.

El porque sucede esta definido por la capacidad de memoria que tiene la LCD para almacenar los strings que  le envias, cuando sobrepasan los 32 por linea, se visualizara en la segunda linea.

Para mostrar mensajes muy largos lo que hago es almacenar en el PIC el string y enviar a la LCD solo los 16 necesarios para que se vean.

Saludos
Título: Re: mover frase largas en lcd de 16x2
Publicado por: MLO__ en 10 de Abril de 2009, 12:47:56
Algo asi:


Título: Re: mover frase largas en lcd de 16x2
Publicado por: setshomaru en 10 de Abril de 2009, 18:56:45
puedes intentar con el comando 24 que es desplazar a la izquierda o el 28 que es desplazar a la derecha te mando un ejemplo donde despalazo el texto de izquierda a derecha


//por julian alvaran 06_04_09
//en la libreria flex_lcd.c se definen los pines que van al lcd
//este programa muestra un texto desplazandose hacia la derecha
//cuando se desplaza 16 posiciones empieza a desplazarce hacia la izquierda

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)

#define  sig         6     //0x06
#define  clear       1     //0x01
#define  cursor_no   12    //0x0C
#define  cursor_si   14    //0x0E
#define  cur_blink   15    //0x0F
#define  dezp_izq    24   //comandos de desplazamiento
#define  dezp_der    28
#define  gen_car     64
#define  lin1        133   //0x85
#define  ren1        128   //0x80
#define  ren2        192   //0xC0

#include <flex_lcd.c>

int1  z;
int   i;

void main() {
 

   lcd_init();
 
   lcd_putc("julian   techno   julian   techno    ");
   
   i=0;
   z=0;
   
   do{
   
   delay_ms(400);
   
   if(i==16)
      z=1;
   if(i==0)
      z=0;
   switch (z){
      case 0:
               ++i;
               lcd_send_byte(0,dezp_der);break;
      case 1:
               --i;
               lcd_send_byte(0,dezp_izq);break;
      }
   }while(true);
   
   
Título: Re: mover frase largas en lcd de 16x2
Publicado por: MGLSOFT en 13 de Abril de 2009, 10:14:41
Algo asi:



Cual es el truco para mover solo la segunda linea??? :mrgreen:
Título: Re: mover frase largas en lcd de 16x2
Publicado por: setshomaru en 13 de Abril de 2009, 11:33:14
intenta esto:

do{

     delay_ms(500);
     switch(z){
           case 0:++pos;break;
           case 1:--pos;break;
     }
     if(pos==16)
            z=1;
     if(pos==0)
            z=0;

     lcd_gotoxy(pos,2);
     lcd_putc("     mensaje    ");
     }while(true);


no recuerdo bien la sintaxis de switch pero creo que esta bien recuerda declarar las varibles int1 z; y int pos;
Título: Re: mover frase largas en lcd de 16x2
Publicado por: pajaro en 13 de Abril de 2009, 11:35:06
Hola amigos
es posible el movimiento de arriba abajo y al reves.
"==" se muestra en el LCD "----" menu.

------------------------
===========
-->hola
--- hola
===========
--- hola
-----------------------


------------------------
--- hola
===========
--- hola
-->hola
===========
--- hola
-----------------------


------------------------
--- hola
--- hola
==========
--- hola
-->hola
==========
-----------------------

Título: Re: mover frase largas en lcd de 16x2
Publicado por: MLO__ en 13 de Abril de 2009, 13:46:20
Hola.

Yo lo hago asi:

Código: C#
  1. while(vista_inicial)
  2.                 {
  3.                         lcd_gotoxy(3,1);
  4.                         lcd_putc("ULTRASONIDO 1&3 MHz");
  5.                         mensaje=true;
  6.                         while(mensaje)
  7.                         {
  8.                                 lcd_gotoxy(1,2);
  9.                                 printf(lcd_putc,"%s",mensaje_inicial);
  10.                                 do{cmd=kbd_getc();}while(sweep!=true);
  11.                                 sweep=false;
  12.                                 for(i=0;i<=strlen(mensaje_inicial)-1;i++)
  13.                                 {
  14.                                         mensaje_inicial[i]=mensaje_inicial[i+1];
  15.                                 }
  16.                                 mensaje_inicial[strlen(mensaje_inicial)]=msj_rom[k++];
  17.                                 if(k>=sizeof(msj_rom)-1)
  18.                                         k=0;
  19.                         }
  20.                 }

En donde msj_rom es donde guardo el mensaje largo y mensaje_inicial es el bufer de memoria para la LCD -de unos 24 caracateres para la LCD que yo uso-, la variable sweep la controlo con un timer (para el tiempo de scroll).

Saludos
Título: Re: mover frase largas en lcd de 16x2
Publicado por: MGLSOFT en 13 de Abril de 2009, 14:31:07
Entonces a mi se me corre el mensaje mostrado en linea 1 porque supero el tamaño posible del buffer de la linea 2 ?? :( :(
No veo que vuelvas a copiarlo al mensaje de linea 1 para mantenerlo fijo... :mrgreen:
Título: Re: mover frase largas en lcd de 16x2
Publicado por: MLO__ en 13 de Abril de 2009, 15:21:25
Hola.

No hay necesidada de volver escribir el dato en la primera fila, ese ya queda garabado en la memoria de la LCD. Con respecto a que aparece el mensaje en la primera fila es porque la memoria interna de la LCD se va copando y hace uso de los registros de memoria de visualizacion (en una de 4x20 por ejemplo si el strin es mas largo de 20 caracteres aparece en la primer fila y en la tercera.)

Saludos
Título: Re: mover frase largas en lcd de 16x2
Publicado por: blue_code en 10 de Octubre de 2014, 12:20:07
Hola.

Yo lo hago asi:

Código: C#
  1. while(vista_inicial)
  2.                 {
  3.                         lcd_gotoxy(3,1);
  4.                         lcd_putc("ULTRASONIDO 1&3 MHz");
  5.                         mensaje=true;
  6.                         while(mensaje)
  7.                         {
  8.                                 lcd_gotoxy(1,2);
  9.                                 printf(lcd_putc,"%s",mensaje_inicial);
  10.                                 do{cmd=kbd_getc();}while(sweep!=true);
  11.                                 sweep=false;
  12.                                 for(i=0;i<=strlen(mensaje_inicial)-1;i++)
  13.                                 {
  14.                                         mensaje_inicial[i]=mensaje_inicial[i+1];
  15.                                 }
  16.                                 mensaje_inicial[strlen(mensaje_inicial)]=msj_rom[k++];
  17.                                 if(k>=sizeof(msj_rom)-1)
  18.                                         k=0;
  19.                         }
  20.                 }

En donde msj_rom es donde guardo el mensaje largo y mensaje_inicial es el bufer de memoria para la LCD -de unos 24 caracateres para la LCD que yo uso-, la variable sweep la controlo con un timer (para el tiempo de scroll).

Saludos

Disculpa revivir este viejo tema, pero la verdad soy nuevo programando PICs y la capacidad de memoria de mi LCD me da muchos problemas, la cual es de 20x4. No se si podrías explicarme como hacer para que mi mensaje no se pase a las demás líneas.

Código: [Seleccionar]
#include <16F877A.h>
#fuses XT,NOWDT,NOPUT
#use delay(clock=4000000)
#byte puerto_e=0x09
#byte tris_e=0x89
#use fast_io(B)
#include <lcd.c>

#INT_EXT
ext_isr()
{
 printf(lcd_putc,"\f ");
 delay_ms(150);
 signed int8 c=0;
 for(c=0;c>-40;c--)
 {
 lcd_gotoxy(c,1);
 printf(lcd_putc," LA INTERRUPCION EXTERNA SE HA ACTIVADO ");
 delay_ms(150);
 puerto_e=0x01;
}
}

 signed int8 d=0;

void main ()
{
 
 set_tris_e(0x00);
 set_tris_B(0x01);
 puerto_e=0x00;
 port_b_pullups(TRUE);
 
 enable_interrupts(INT_EXT);
 ext_int_edge(L_TO_H);
 enable_interrupts(GLOBAL);
 
 
while(TRUE)
{
 lcd_init();      //inicializa la LCD
 printf(lcd_putc,"\f ");

  puerto_e=0x00;
  lcd_gotoxy(d,1);
  printf(lcd_putc," PIC16F877A: USO DE LA INTERRUPCION EXTERNA ");
  delay_ms(150);
  lcd_gotoxy(1,2);
  d=d<-45? 0:d-1;
 }
 }

Aquí está lo que me muestra la LCD:
(http://www.todopic.com.ar/foros/imgtiny/2a5kow4.jpg)
Título: Re: mover frase largas en lcd de 16x2
Publicado por: kiuzo en 07 de Marzo de 2015, 01:17:05
hola, para mover la segunda fila a mi me funciona con la misma librería flex_lcd.c  asi:


LCD_GOTOXY(1,2);lcd_putc("*");
for(z=0;z<14;z++){
lcd_send_byte(0,28);
delay_ms(100);} 

con eso muevo el * hacia la derecha.
Título: Re: mover frase largas en lcd de 16x2
Publicado por: Thulsa Doom en 09 de Marzo de 2015, 11:45:08
Hola a todos, yo con C18 lo hago de esta manera

Código: [Seleccionar]
/********************************************************************************************
  Función:
void *Move_Tex_LCD(char linea, char V_ms, char *Array_LCD)

  Sumario:
        Desplaza un texto de un tamaño indeterminado de izquierda a derecha en un
       display de 16x2

  Descripción:
Esta función desplaza un texto (string) de izquierda a derecha en un display
      la suelo utilizar para desplegar menús ya que el tamaño de un display normal
      es muy limitado, a la función le pasamos la línea donde queremos que se despliegue
      el mensaje, la velocidad de desplazamiento y el string a desplegar.
         En la función detectaremos el tamaño del string automáticamente para que no tengamos que
      preocuparnos de nada más, hay un string fijo que es el doble del tamaño de los carácteres
      del display, este tamaño es fijo y es el que da la sensación de desplazamiento

   Precondición:
la librería string.h tiene que estar invocada

   Parámetros:

linea = Línea donde queremos que se muestre el texto

V_ms = Velocidad de desplazamiento del texto

        Array_LCD = Puntero al string del texto a desplegar

   Retorno:
Ninguno

   Ejemplo:
Move_Tex_LCD(1,250,Array);

***************************************************************************************************/

 void *Move_Tex_LCD(char Clear, char linea, char V_ms, char *Array_LCD){
static unsigned char a,b,c,wi,wo; //Variables varias , tienen que ser estáticas si no toma el valor que quiera cada vez que entre
static unsigned char SizeCadena; //Variable donde guardamos el tamaño de la cadena
        static unsigned char cadena[17]; //Cadena que se va a imprimir en el LCD

   if(Clear == 0){ //Si entramos desde otra sección
      b=0;          //Ponemos todos las banderas a 0
      a=0;          //para poder empezar desde 0 con el
      c=0;          //texto en pantalla
      wi=0;
      wo=1;
   }
       
        SizeCadena = strlen(Array_LCD); //Detectamos la longitud de la cadena a imprimir
       

// if(c == 0 || (Key != 0)){           //Preparamos el array para imprimir la cadena
        if(c == 0){
            for(a=0;a<=(18);a++){
cadena[a] = ' ';            //Ósea llenamos el array de espacios            
            }
                c=1;    //Bandera para que entre el bucle que prepara el array solo una vez cada inicio de la cadena
wo=1; //variable para que el dato se mueva por la cadena, la inicializamos a 1 para que haya un desface entre wi y wo
}
for(wi=0;wi<=(17);wi++){
  cadena[wi] = cadena[wo++]; //Dezplazamiento del dato dentro de la cadena
                    if(Key != 0) break; //Para salir del bucle si se pulsa una tecla
                  }

cadena[17] = Array_LCD[b++]; //se añade otro dato en la cola de la cadena
wi=0; //Se inicializan los contadores
wo=1;
#if defined(LCD)
gotoxyXLCD(0,linea); putsXLCD(cadena);  //Se imprime en pantalla la cadena
while( BusyXLCD() ); //wait untill LCD controller is busy
#endif //LCD
Delay10KTCYx(V_ms);                      //Velocidad con que se desplaza la cadena
if(b == (SizeCadena+1)){    //Si se llega al final de la cadena, se inizializa el proceso de 0
b=0;
c=0;
a=0;
}
}

De momento solo la tengo implementada de derecha a izquierda, cambiando dos tonterías se podría hacer para los dos sentidos

espero les sirva de algo
Título: Re: mover frase largas en lcd de 16x2
Publicado por: aldoMO en 06 de Mayo de 2015, 12:39:43
hola, para mover la segunda fila a mi me funciona con la misma librería flex_lcd.c  asi:


LCD_GOTOXY(1,2);lcd_putc("*");
for(z=0;z<14;z++){
lcd_send_byte(0,28);
delay_ms(100);} 

con eso muevo el * hacia la derecha.

Hola kiuzo, yo use tu ejemplo, y me mueve la primera fila también, a que puede deberse esto?
esto es lo que hice:

      printf(lcd_putc,"\f");
      lcd_gotoxy(1,1);
      printf(lcd_putc, "contador=%d",contador);

     
      lcd_gotoxy(16,2);
      printf(lcd_putc, "lluv.Acum=%fmm",lluvia);
         for(z=0;z<16;z++){
         lcd_send_byte(0,24);
         delay_ms(200);}