Ich lerne die Schnittstelle von Atmega 16a mit 16X2 LCD. Ich habe eine Header-Datei für Routinen geschrieben, die häufig verwendet werden, und jedes Mal, wenn ich mit Atmega 16a eine Schnittstelle mit LCD herstellen möchte, verwende ich diese Header-Datei.
Hier ist meine LCD-Header-Datei:
#include<stdlib.h>
#include<avr/io.h>
#include<util/delay.h>
int cx=1;
int cy=1;
void LCD_Send(unsigned char c,unsigned char DC)
{
if(DC==0)
{
PORTC=0x0F & (c>>4);
PORTC=PORTC|(1<<5);
_delay_ms(1);
PORTC=PORTC & (~(1<<5));
_delay_ms(1);
PORTC=0x0F & (c);
PORTC=PORTC | (1<<5);
_delay_ms(1);
PORTC=PORTC & (~(1<<5));
_delay_ms(1);
}
else if(DC==1)
{
PORTC=0x0F & (c>>4);
PORTC=PORTC | (1<<7);
PORTC=PORTC|(1<<5);
_delay_ms(1);
PORTC=PORTC & (~(1<<5));
_delay_ms(1);
PORTC=0x0F & (c);
PORTC=PORTC | (1<<7);
PORTC=PORTC | (1<<5);
_delay_ms(1);
PORTC=PORTC & (~(1<<5));
_delay_ms(1);
}
return ;
}
void LCD_init(void)
{
DDRC=0b11101111;
LCD_Send(0x01,0);
LCD_Send(0x0F,0);
LCD_Send(0x28,0);
cx=1;cy=1;
return ;
}
void LCD_Send_String(char* s)
{
for(int i=0;s[i]!='\0';i++)
{
LCD_Send(s[i],1);
if(cx==16)
{
cx=1;cy++;
LCD_Send(0xC0,0);
}
else
cx++;
}
return ;
}
void LCD_GotoXY(unsigned int x,unsigned int y)
{
if(y==1)
{
char addr=0x80;
addr=addr+(x-1);
LCD_Send(addr,0);
}
else if(y==2)
{
char addr=0xC0;
addr=addr+(x-1);
LCD_Send(addr,0);
}
cx=x; cy=y;
return ;
}
void LCD_Print(int data,unsigned int x,unsigned int y)
{
char string[10];
LCD_GotoXY(x,y);
itoa(data,string,10);
LCD_Send_String(string);
return ;
}
Hier sind RS, R/W und E jeweils PC7, PC6 und PC5, DB4, DB5, DB6, DB7 sind jeweils PC0, PC1, PC2, PC3. Ich verwende den 4-Bit-Modus für die Eingabe.
Hier ist meine main.c-Datei (der Code, der auf dem Mikroprozessor ausgeführt wird):
#include"lcd.h"
int main(void)
{
LCD_init();
char s[20]="1234567890123456789";
LCD_Send_String(s);
return 0;
}
Wenn ich den Speicher mit der HEX-Datei flashe und dann zurücksetze, zeigt das LCD gut an
Wenn ich dann später zurücksetze, werden Zufallsvariablen angezeigt (tatsächlich kann ich sehen, dass sich die zweite Zeile überhaupt nicht ändert, was bedeutet, dass der Bildschirm nicht gelöscht wird, aber ein Befehl geschrieben wurde, um den Bildschirm zu löschen) LCD_init()
.
Ich bin mir ziemlich sicher, dass mit dem Board und den Verbindungen nichts falsch ist, da es mit anderen Header-Dateien funktioniert. Ich bin mir ziemlich sicher, dass es sich um einen Fehler in meinem Code handelt. Ich wäre wirklich dankbar, wenn mir jemand helfen würde, diesen Code zu reparieren. Wenn ich ihn wieder zurücksetze, wird die richtige Sequenz wie im ersten Bild angezeigt
Ihr Problem ist, dass das Display seinen Zustand während des MCU-Resets beibehält. Beim Kaltstart ist der anfängliche Datenmodus 8-Bit, den Sie sofort auf 4-Bit umschalten, der Daten mit einem Paar EN-Impulsen liest.
Wenn Sie die MCU zurücksetzen, wissen Sie nicht, ob gerade oder ungerade Anzahl von EN-Impulsen gesendet wurden. Sie müssen also das Display irgendwie zurücksetzen, auch wenn es keinen Reset-Pin hat.
Dies kann durch Senden von 0x33 0x33 erfolgen (im 8-Bit-Modus bedeutet dies, dass 4-mal auf 8-Bit umgeschaltet wird, im 4-Bit-Modus bedeutet dies, dass ein- oder zweimal auf 8-Bit umgeschaltet wird). Dann können Sie sicher sein, dass Sie immer vom gleichen Stand aus starten.
Fahren Sie dann mit dem regulären 0x32 (oder 4-Bit 0x02, wenn Sie eine einzelne 4-Bit-Schreibfunktion haben), 0x28 fort, um in den 4-Bit-2-Zeilen-Modus zu gelangen.
LCDs neigen dazu, wenn der Datenstrom irgendwie desynchronisiert wird, z. B. durch Anschließen während der Datenübertragung oder durch Zurücksetzen des Bildschirms oder des Mikrocontrollers, aber nicht beider.
Ich merke aus Ihrem Code, dass es keine Startverzögerung gibt. LCDs benötigen oft eine kurze Zeit zum "Hochfahren", bevor Sie mit dem Senden von Daten beginnen können. Fügen Sie dem Start Ihres Codes eine kleine Verzögerung hinzu. Sehen Sie im LCD-Datenblatt nach, wie viel.
Überprüfen Sie das Datenblatt für das LCD. Oft müssen Sie nach dem Einschalten eine bestimmte Zeit warten, bevor Sie die Init-Sequenz senden. Vielleicht ist dein Problem folgendes:
Wenn Sie das Gerät programmieren, war es bereits eine Weile eingeschaltet, sodass Ihre Init-Sequenz funktioniert. Wenn Sie es kalt starten, gibt es keine Verzögerung, sodass das LCD noch nicht für die Init-Sequenz bereit ist.
Bitte poste auch einen Link zum Datenblatt
Wladimir Cravero
Aditya
Aditya
Wladimir Cravero
Aditya
Wladimir Cravero
Aditya