LCD muestra un comportamiento extraño al reiniciar el microcontrolador

0

He escrito un código para el microcontrolador 'PIC18F4550' (20MHz xtal) que muestra "Velocidad = xxx RPMs" en una LCD HD44780 en modo de 4 bits, donde xxx es el valor contenido en la variable llamada ' entrada'. El compilador utilizado es xc8 y estoy programando usando PICKIT3. He ejecutado la simulación en proteus y todo va bien hasta que reinicio el PIC utilizando el pin MCLR. Realmente muestra una salida anómala en la que parece que no puedo entender qué parte va mal. También he implementado esto en hardware y se comporta exactamente como lo hace en la simulación. Leí algo similar a este problema y la gente estaba sugiriendo que el pin de habilitación debe estar desordenándose durante el reinicio, pero no veo cómo podría estar sucediendo aquí, así que por favor, trate de ayudar a los muchachos. Me he quedado sin ideas.

#include<p18F4550.h>#include<stdio.h>#include<stdlib.h>#include<delays.h>#include<string.h>#define_XTAL_FREQ20000000#defineLCD_outPORTD#definersPORTCbits.RC0#definerwPORTCbits.RC1#defineenPORTCbits.RC2//---------------------//voidlcd_cmd(unsignedchara);//forLCDcommandsvoidlcd_data(unsignedcharb);//forLCDdatavoidlcd_reset(void);//toinitialize4-bitmodevoidlcd_init(void);//primaryinitializationinstructionsvoidstring_display(char*p);//todisplaycharacterstrings/arraysvoidshift_right(inta);//rightcursorshiftvoidshift_left(intb);//leftcursorshiftvoiddelay_10ms(intt);//delayinmultiplesof10msvoidfragment(intx);//fragments,processes&displaysintdata//.....................//voidmain(void){TRISC=0;TRISD=0;intinput=0;chartext1[]="Speed = ";
    char text2[] = "RPMs ";

    lcd_init();
    string_display(text1);
    shift_right(4);

    string_display(text2);
    shift_left(9);

    while(1)
    {
        input++;
        fragment(input);
    }
}


void fragment (int x)
{
    int number[3];
    char final_num[4];
    int flag = 0;

    number[2]= (x/1)%10;
    number[1]= (x/10)%10;
    number[0]= (x/100)%10;

    if(number[0]==0)
        flag++;
    if(number[1]==0 && number[0]==0)
        flag++;

    int temp=0;
    for(int i=flag;i<=2;i++)
    {
        final_num[temp]='0' + number[i];
        temp++;
    }

    if(x<1000)
    {
        string_display(final_num);
        shift_left(temp);
    }

    else
    {
        char nul[]="NUL";
        string_display(nul);
        shift_left(3);
    }

}

void delay_10ms(int t)
{
    for(int i=0; i<t;i++)
    {
        __delay_ms(10);
    }
}

void shift_right(int a)
{
    for(int i=0; i<a;i++)
    {
        lcd_cmd(0x14);
    }
}

void shift_left(int b)
{
    for(int i=0; i<b;i++)
    {
        lcd_cmd(0x10);
    }

}

void string_display(char *p)
{
    while(*p!=0)
    {
        lcd_data(*p);
        p++;
    }
}

void lcd_init(void)
{
    TRISC=0;
    TRISD=0;
    en = 0;
    rw = 0;

    LCD_out = 0;
    lcd_reset();
    lcd_cmd(0x28);
    lcd_cmd(0x01);
    lcd_cmd(0x0C);
}

void lcd_reset(void)
{
    __delay_ms(20);
    LCD_out=0x03;
    en=1;
    __delay_ms(5);
    en=0;

    __delay_ms(10);
    LCD_out=0x03;
    en=1;
    __delay_ms(5);
    en=0;

    __delay_ms(1);
    LCD_out=0x03;
    en=1;
    __delay_ms(5);
    en=0;

    __delay_ms(1);
    LCD_out=0x02;
    en=1;
    __delay_ms(5);
    en=0;
    __delay_ms(5);
}

void lcd_cmd(unsigned char cmd)
{
    rs=0;
    unsigned char temp;
    temp=cmd;

    //sends the upper four bits
    temp=temp>>4;
    LCD_out=temp;
    en=1;
    __delay_ms(1);
    en=0;
    __delay_ms(1);

    //sends the lower 4 bits
    temp=cmd;
    LCD_out=temp;
    en=1;
    __delay_ms(1);
    en=0;
    __delay_ms(1);
}

void lcd_data(unsigned char data)
{
    rs=1;
    unsigned char temp;
    temp=data;

    //sends the upper four bits
    temp=temp>>4;
    LCD_out=temp;
    en=1;
    __delay_ms(1);
    en=0;
    __delay_ms(1);

    //sends the lower 4 bits
    temp=data;
    LCD_out=temp;
    en=1;
    __delay_ms(1);
    en=0;
    __delay_ms(1);
}
    
pregunta Hameem

1 respuesta

2

Comenzaré con errores en el circuito:

  • El oscilador no está conectado correctamente.
  • Creo que no deberías limitar la corriente LCD con resistencia y capacitor. (R2, C1)
  • En Proteus, no es necesario que simules 5V, ya que los pines PIC están conectados a Vcc (5v). Puede reemplazar todas las conexiones para 5V a Vcc, es igual.
  • Asegúrese de que está suministrando 7805 con suficiente Vin. (ver hoja de datos)

Errores en el código:

Si está utilizando el compilador XC8 como dijo, no debe incluir todo esto:
Si está completamente seguro de que desea utilizar el encabezado especificado, inclúyalo.

#include <p18F4550.h>
#include <stdio.h>
#include <stdlib.h>
#include <delays.h>
#include <string.h>

En su lugar, debe incluir solo :

#include <xc8.h>

Incluirá todos los encabezados necesarios.

Tampoco puedo ver los bits de configuración en el código. Inclúyelos también.

Es posible que todo este desplazamiento hacia la izquierda y la derecha haga que su código no funcione correctamente. En lugar de desplazarme hacia la derecha o hacia la izquierda, imprimiría toda la pantalla a la vez. Ejemplo:

while(1)
{
    lcd_reset();

    input++;
    fragment(input);

    string_display(text1);
    char_display(number[0]);
    char_display(number[1]);
    char_display(number[2]);
    string_display(text2);
}
    
respondido por el Triak

Lea otras preguntas en las etiquetas