Autor Tema: LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC  (Leído 7063 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado jo-fe-ar

  • PIC10
  • *
  • Mensajes: 24
LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« en: 25 de Mayo de 2014, 17:51:26 »
Buenas tardes, estoy haciendo un pequeño proyecto, pero en verdad me he quedado un poco trabado. :oops:
Estoy empezando a utilizar MikroC para Pics, en particular, el PIC 16F648A.
Anteriormente he usado LCD 16X2 usando Pic Basic Pro, sin ningun problema ni inconveniente, pero con MikroC, he tenido varios, a cada rato, que en general, lo que sucede es que:

- Se sobreescriben caracteres en el LCD, en sitios que no deben estar, e incluso, a veces signos raros -


En concreto, estaba usando el codigo de ejemplo que brinda la ayuda de MikroC para controlar un sensor de temperatura DS18B20, y eso complicaba bastante la impresion en el LCD, es decir, eran muchos mas los caracteres raros. Disminuyendo algunas cadenas de texto que presentaba, o "arrimandolas" de sitio, a veces, lograba "componerlo" pero realmente el problema persiste, y aunque he buscado muchas soluciones, no encuentro nada, he probado bastantes formas, y tampoco.

E incluso con un codigo mas sencillo, tambien pasa. A continuacion un codigo mas sencillo que hice, que tambien me da el problema:

Código: [Seleccionar]
void luz(void);
void temperatura(void);
void uv (void);
void laser(void);
void luzcuarto (void);

sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RA2_bit;
sbit LCD_D5 at RA3_bit;
sbit LCD_D6 at RA4_bit;
sbit LCD_D7 at RA6_bit;
sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISA2_bit;
sbit LCD_D5_Direction at TRISA3_bit;
sbit LCD_D6_Direction at TRISA4_bit;
sbit LCD_D7_Direction at TRISA6_bit;  // Final de las conexiones del módulo LCD


int i=0, l=0, ok=0, med=0, ilu=0, por=0;
char *ilutxt="000";
const unsigned short TEMP_RESOLUTION = 12;
char *text = "000.0000";
unsigned temp;


void main() {

CMCON=0x07;
l=0;
RB4_bit=0;
RB5_bit=0;
RB6_bit=0;
RB7_bit=0;
RA7_bit=0;
TRISB4_bit=1;
TRISB5_bit=1;
TRISB6_bit=1;
TRISB7_bit=0;
TRISA7_bit=0;

UART1_Init(9600);           //Inicializa el USART a 9600 bps.
Delay_ms(100);              //Espera a que el USART se estabilice.

  LCD_init ();
  lcd_cmd(_LCD_CURSOR_OFF);             // Comando LCD (apagar el cursor)}
  lcd_out (1,6,"FAOMIC");
  lcd_out (2,3,"SICPRI v 2.0");
  delay_ms(3000);

  for (i=0;i<20;i++){
  lcd_cmd(_LCD_SHIFT_LEFT);
  delay_ms(50);}
 
 
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Cmd(_LCD_RETURN_HOME);


    lcd_out (1,4, "BIENVENIDO");
    lcd_out (2,4, "Todo bien?");

    GIE_bit=1;                     //Interrupciones habilitadas.
    RBIE_bit=1;                           //Interrupcion PORTB habilitada

    while (ok==0);


                                         //Entramos a Sistema
    PWM1_Init(250);
    PWM1_Start();                       // start PWM1
    PWM1_Set_Duty(ilu);
    ok=0;
    med=1;

    l=0;
    Delay_ms(500);
    Lcd_Cmd(_LCD_CLEAR);                //Entramos ya al menu de pantallas.
   
    while(1){
    if (l<0) l=4;
    if (l>4) l=0;
    switch (l){
    case 0: lcd_out(1,1, "TEMPERATURA"), lcd_chr(2,10,223), lcd_out(2,11,"C");break;
    case 1: lcd_out(1,1, "LUZ  BLANCA ILUM"), lcd_out(2,11,"%"), luz()       ;break;
    case 2:  uv()           ;break;
    case 3:  laser()        ;break;
    case 4:  luzcuarto()    ;break;}
   }}
   
void interrupt(void){
  if (RB5_bit==1) ok=!ok, med++;  //Pulsador presionado.switch (med){

  if (RB6_bit==1) l--;  //Pulsador presionado.
 while (RB6_bit==1);

  if (RB4_bit==1) l++;  //Pulsador presionado.
 while (RB4_bit==1);

 INTF_bit=0;
 RBIF_bit=0;
}

void luz (void){
while (l==1){
switch (med){
case 1: ilu = 0,   ilutxt[2]='0', ilutxt[1] = '0', ilutxt[0]='0';break;
case 2: ilu = 64 , ilutxt[2]='5', ilutxt[1] = '2', ilutxt[0]='0';break;
case 3: ilu = 128 ,ilutxt[2]='0', ilutxt[1] = '5', ilutxt[0]='0';break;
case 4: ilu = 192 ,ilutxt[2]='5', ilutxt[1] = '7', ilutxt[0]='0';break;
case 5: ilu = 255, ilutxt[2]='0', ilutxt[1] = '0', ilutxt[0]='1';break;}
if  (med<1) med=5;
if (med>5) med=1;

PWM1_Set_Duty(ilu);
lcd_out(2,1,ilutxt);
}}



void uv (void){   
lcd_out (1,1,"LUZ ULTRAVIOLETA");
    while (l==2){
    if (ok==0) {
    lcd_out (2,1, "ON ");
    RB7_bit = 0;}
   
    if (ok==1){lcd_out (2,1, "OFF");
    RB7_bit = 1;}}}

void laser (void){
lcd_out (1,1,"LUZ LASER       ");
    while (l==3){
    if (ok==0) {lcd_out (2,1,"ON ");
    RA7_bit = 0;}
   
    if (ok==1) {lcd_out (2,1,"OFF");
    RA7_bit = 1;}}}
   
void luzcuarto (void){
lcd_out (1,1,"LUZ CUARTO      ");

    while (l==4){
        if (ok==0) {lcd_out (2,1,"ON ");
        UART1_Write_Text("LCON");}

        if (ok==1) {lcd_out (2,1,"OFF ");
        UART1_Write_Text("LCOFF");}
}}


Y adjuntas unas imagenes, de lo que pasa. En concreto, todo parece estar bien, pero en la parte en la que imprimo "LUZ CUARTO" en la primera fila, en realidad proyecta "OFF CUARTO", , y siempre pasa de un modo aparecido, como que "arrastra" palabras o caracteres.

En algunas busquedas que realice, decian que eran por variables convertidas a string, que tenian muchos caracteres, y que era mejor hacerlo manual, pero para evitar esa posibilidad, he retirado esas partes, como ven el codigo, consta de simples impresiones en LCD, que en PBP haria sin problema pero aqui no entiendo cual es el problema.

Como ven, en este caso, el problema se observa en la imagen 5.
Alguien sabe por que sucede esto? Segun yo el codigo es correcto, sencillo incluso, simple presentacion de cadenas especificadas, fijas, y me sale ese problema.


Muchas gracias por su apoyo.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #1 en: 25 de Mayo de 2014, 18:34:46 »
Hola

Jamás había visto esta sintaxis en C:

Código: [Seleccionar]
case 1: ilu = 0,   ilutxt[2]='0', ilutxt[1] = '0', ilutxt[0]='0';break;
¿No deberían haber punto-y-coma ahí?

Fuera de eso, yo mejor probaría en una LCD real.


Desconectado jo-fe-ar

  • PIC10
  • *
  • Mensajes: 24
Re: LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #2 en: 25 de Mayo de 2014, 18:52:00 »
Eso habia intentado antes tambien, usar ";", pero de echo el compilador marca error si lo escribo de esa forma.
Y asi como esta, esa parte, funciona perfectamente.
De echo ya lo probe en una LCD y el circuito reales, y pasa exactamente lo mismo que en el simulador, sin diferencia alguna :/

Gracias por la respuesta

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #3 en: 25 de Mayo de 2014, 21:59:38 »
Pues revisando rápido Wikipedia me enteré de lo que introdujiste es compilable con comas, pero tiene un comportamiento bastante peculiar. La coma quita/agrega precedencias... mejor revísalo bien.

http://en.wikipedia.org/wiki/Comma_operator#Examples

Código: [Seleccionar]
// Examples:               Descriptions:                                                                 Values after line is evaluated:
int a=1, b=2, c=3, i=0; // commas act as separators in this line, not as an operator
                        // ... a=1, b=2, c=3, i=0
i = (a, b);             // stores b into i
                        // ... a=1, b=2, c=3, i=2
i = a, b;               // stores a into i. Equivalent to (i = a), b;
                        // ... a=1, b=2, c=3, i=1
i = (a += 2, a + b);    // increases a by 2, then stores a+b = 3+2 into i
                        // ... a=3, b=2, c=3, i=5
i = a += 2, a + b;      // increases a by 2, then stores a to i, and discards unused
                        // a + b rvalue. Equivalent to (i = (a += 2)), a + b;
                        // ... a=5, b=2, c=3, i=5
i = a, b, c;            // stores a into i, discarding the unused b and c rvalues
                        // ... a=5, b=2, c=3, i=5
i = (a, b, c);          // stores c into i, discarding the unused a and b rvalues
                        // ... a=5, b=2, c=3, i=3
return a=4, b=5, c=6;   // returns 6, not 4, since comma operator sequence points
                        // following the keyword 'return' are considered a single
                        // expression evaluating to rvalue of final subexpression c=6
return 1, 2, 3;         // returns 3, not 1, for same reason as previous example
return(1), 2, 3;        // returns 3, not 1, still for same reason as above.  This
                        // example works as it does because return is a keyword, not
                        // a function call. Even though most compilers will allow for
                        // the construct return(value), the parentheses are syntactic
                        // sugar that get stripped out without syntactic analysis

Como mejor sugerencia, regresa los punto-y-coma. Debe compilar con ellos. Si no compila, algo más está mal.

Lo de las comas no es común.

Desconectado jo-fe-ar

  • PIC10
  • *
  • Mensajes: 24
Re: LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #4 en: 25 de Mayo de 2014, 22:43:03 »
Gracias por la informacion, si no mal recuerdo lo que he leido antes, lo que colocas es totalmente correcto, pero creo que en el caso del codigo que puse, es una particularidad de la instruccion SWITCH, permite separar por comas las acciones a realizar en cada caso, hasta encontrar ";" y el consecuente "break;"

Supongo que es un particular comportamiento de tal instruccion SWITCH para MikroC, pues en efecto, si uso ";" en vez de cada "," , no me compila y me muestra error,  ademas de exigirme, que si hay ";" entonces debe haber un break.

Aunque si esta interesante y curioso o.o
Muchas gracias por la info

Aunque creo que no es parte del problema de la LCD, me pareciera mas que tiene algo que ver con algun desbordamiento de alguna memoria, que luego me empieza a sobreescribir en todos lados :/

Muchas gracias

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #5 en: 26 de Mayo de 2014, 02:44:10 »
Uff, qué lío eso de las precedencias con las comas. No tenía ni idea de que eso funcionara así.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #6 en: 26 de Mayo de 2014, 22:18:33 »
Uff, qué lío eso de las precedencias con las comas. No tenía ni idea de que eso funcionara así.

Sí, pero no hay que liarse tanto... mejor no hay que usarlas.

jo-fe-ar, mejor compila el código con punto y coma y checa dónde falla. MikroC no debe tener ese tipo de reglas tan raras.

Desconectado a9965

  • PIC10
  • *
  • Mensajes: 22
Re: LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #7 en: 29 de Mayo de 2014, 07:10:18 »
Uff, qué lío eso de las precedencias con las comas. No tenía ni idea de que eso funcionara así.

Sí, pero no hay que liarse tanto... mejor no hay que usarlas.

jo-fe-ar, mejor compila el código con punto y coma y checa dónde falla. MikroC no debe tener ese tipo de reglas tan raras.

Uff, qué lío eso de las precedencias con las comas. No tenía ni idea de que eso funcionara así.

Sí, pero no hay que liarse tanto... mejor no hay que usarlas.

jo-fe-ar, mejor compila el código con punto y coma y checa dónde falla. MikroC no debe tener ese tipo de reglas tan raras.

Hola.

Llevo tiempo con MikroC y lcd. Particularmente he tenido problemas con la librería del lcd.

Por ejemplo, ahora estoy en un proyecto con un keypad, un lcd.
Trato de programar una interrupción del TMR0 para controlar la iluminación del lcd automáticamente.
Me pasa lo mismo que a ti, cuando salta la interrupción los caracteres del lcd se vuelven un poco locos.(aún no he conseguido arreglarlo).

No he mirado tu código, pero alguno de los problemas que a mi me ha dado dicha librería es por la frecuencia de reloj. No se si te servirá pero ahí queda mi experiencia con MikroC y la librería del lcd.

Un saludo.

Desconectado LucasBols

  • PIC16
  • ***
  • Mensajes: 129
    • Desarrollos y Servicios Digitales
Re: LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #8 en: 04 de Junio de 2014, 13:19:19 »
hola

proba de ponerle \0 al final de cada texto en lcd_out , ago como lcd_out (1,6,"FAOMIC\0"); por ahi se soluciona

eso me pasaba con el xc8 cuando la flash del pic se llenaba, se ve que tienen una forma poco común de ocupar los espacios,

saludos
Un experto es alguien que te explica algo sencillo de forma confusa de tal manera que te hace pensar que la confusión sea culpa tuya.

DSD http://www.dysd.com.ar/

Desconectado w3-sistemas

  • PIC12
  • **
  • Mensajes: 89
Re: LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #9 en: 08 de Junio de 2014, 11:20:14 »
hola, yo estoy estudiando C y estoy justo con LCD, lo primero que veo en tu dibujo creo que tenes un problema de conexion, nosotros tambien usamos 4 bit  para mandar la info, pero los otros 4 los ponemos a masa, vos en tu dibujo los tenes libres y eso hace que se metan ruidos, proba asi y si podes pone un dibujo completo de la conexion del lcd  con el micro, saludos

Desconectado jl_puerta

  • PIC10
  • *
  • Mensajes: 6
Re: LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #10 en: 14 de Octubre de 2015, 10:53:32 »
hola

proba de ponerle \0 al final de cada texto en lcd_out , ago como lcd_out (1,6,"FAOMIC\0"); por ahi se soluciona

eso me pasaba con el xc8 cuando la flash del pic se llenaba, se ve que tienen una forma poco común de ocupar los espacios,

saludos


hola a mi me ocurre tambien que al escribir en la lcd un menu de opciones me coloca las palabras en posiciones distintas a las que le indico, estoy utilizo switch para generar el menu, y bueno, tambien me da curiosidad sobre el uso de la flash, al compilar el mikrco me arroja unos mensajes donde dice que la ram esta usada al 70%, que sucederia si llega al 100% ??

Desconectado jl_puerta

  • PIC10
  • *
  • Mensajes: 6
Re:LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #11 en: 14 de Octubre de 2015, 10:57:45 »
hola a mi me ocurre tambien que al escribir en la lcd un menu de opciones me coloca las palabras en posiciones distintas a las que le indico, estoy utilizo switch para generar el menu, y bueno,el compañerolucasBols menciono algo  me da curiosidad, es sobre el uso de la flash, al compilar el mikroC me arroja unos mensajes donde dice que la ram esta usada al 70%, que sucederia si llega al 100% ??
hola

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #12 en: 14 de Octubre de 2015, 14:38:31 »
Con respecto a poner lso caracteres en otro lugar no se. Podria ser que la RAM afecte, depende de donde este ubicado la variable, pero que te modifique eso nomas y no varas cosas mas es lo complicado.
Lo ocupado de la flash no afecta en NADA. No se que lo llevo a hacer esa suposicion, tal ves un error en la libreria del LCD.
Ya que la posicion donde queres el caracter se lo das al LCD y el LCD es quien sigue el orden.

Sobre la RAM:
Si tenes usada la RAM al 70% estas bastante complicado.

C usa la RAM para crear variables, en lo que se le llama el "stack" ese espacio que sobra se usa para el stack. Los problemas que pueden surgir es que tus programas utlizen de mas el stack y eso afecte a los demas datos. Es decir que el stack crezca tanto que alcance la posicion de memoria de los datos que ya estan fijos.

Cuando vos haces:

Código: C
  1. int gvar;
  2.  
  3. void subrutina(){
  4.     int x,y;
  5.     static svar;
  6. }

gvar y svar te lo cuenta como RAM ocupada. Pero x e y se crean en el stack, por que al entrar a la rutina se "crean" y al salir se destruyen, es decir al compilador no le interesa guardar su valor.

Con eso espero haber respondido sobre lo de llegar al 100% de la RAM, si llegas al 100% , C no va a tener lugar para su stack, y lo mas seguro es que termine escribiendo el valor encima de alguna otra variable ( si es que no lo hace ya al 70% ) las soluciones son: o manejar mejor el tema de las variables de almacenamiento persistente (globales, estaticas) o comprarse un micro con mas RAM
« Última modificación: 14 de Octubre de 2015, 16:05:05 por KILLERJC »

Desconectado jl_puerta

  • PIC10
  • *
  • Mensajes: 6
Re:LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #13 en: 22 de Octubre de 2015, 18:00:28 »
hola gracias por tu respuesta, le habia preguntado a mi profesor sobre ese problema y me dijo que la serie 16f es un poco problematica para programar porq su memoria no es lineal como las de los pic18f ydpic entonces me dijo que migrara a la serie 18f  pero buscando y buscando porq no queria cambiar de pic me consegui una rutina que podria ayudar bastante en el ahorro de la ram solo cuando se trata de mostrar en LCD aqui esta  funcion para mostrar y ahorra memoria ram, probada en Mikroc for pic 6.0

char* codetxt_to_ramtxt(const char* ctxt){
static char txt[20];
char i;
for(i =0; txt = ctxt; i++);
return txt;
} // rutina

lcd_out(1,1,codetxt_to_ramtxt("Hola mundo")); ////// asi se usa

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:LCD 16X2 Se imprime ERRONEAMENTE, arrastra caracteres. MikroC
« Respuesta #14 en: 22 de Octubre de 2015, 22:26:00 »
En realidad la memoria del PIC16 es TAN lineal como el PIC18 (pero a vos te importaria muy poco si programas en C), el dsPIC/PIC24 ya es toda otra arquitectura distinta. Por que digo que es lo mismo?

En ambos (PIC16 y PIC18) el OPCODE de las instrucciones solo soporta 8 bits de direccionamiento (a excepcion de algunas instrucciones, creo que 2 que soportan 12bits en su opcode PIC18) por lo cual sin cambiar de bancos solo podes acceder desde 0x00 a 0xFF, si agregas los bits de los bancos a esa direccion podes direccionar mas. Incluso tenes los direccionamientos indirectos que permiten alcanzar toda la direccion sin necesidad de cambio de bancos.

Asi como tenes una zona que es accesible desde todos los bancos en el PIC16 (0x7F a 0xFF creo que es), en el PIC18 tenes una porcion del banco 0 que se llama access bank y es posible acceder al mismo desde cualquier banco, tambien por access podes acceder a los SFR desde cualquier banco, es una mejora. PIC18 tambien posee bancos. Y mas bancos que los PIC16
Las principales diferencias entre uno y otro para el tema de almacenamiento de variables, uso del stack de C, etc son:

Mas RAM obviamente.
Los PIC18 seguro que permiten el guardado de "constantes" en memoria y se pueden leer, Tal es el caso de tu "Hola mundo", se guardaria en la flash. algunos PIC16 tambien possen pero es mas extraño verlo.
Los PIC18 tiene un set de instrucciones que facilita la implementacion del stack ( con su set extendido ), lo cual hace mas rapido a tu programa.
El acceso a todos los SFR se puede hacer desde cualquier banco, distinto al PIC16 que estas obligado a cambiar de banco para eso.

Y la ultima diferencia, es la posicion de los SFR, en el PIC16 estan al comienzo de cada banco. en el PIC18 estan todos en el ultimo banco.

-------------------------------------

Con respecto al programa me parece raro que eso termine "ahorrando" memoria RAM. por que tenes un static char, el cual te ocuparia 20lugares de la memoria RAM si o si.
La pregunta es. probaste con algo asi ?

Código: [Seleccionar]
const char txt[] = "Hola mundo";
lcd_out(1,1,txt);

Y ver donde ubica "Hola mundo" ? si como una tabla en la flash o como una variable en la RAM al agregarle el const
« Última modificación: 22 de Octubre de 2015, 22:30:10 por KILLERJC »