Ich versuche, ein Programm in C zu schreiben, um Text auf diesem LCD anzuzeigen, aus irgendeinem Grund zeigt es überhaupt nichts an. Ich habe dieses Tutorial auf YouTube befolgt und mein Schulbuch verwendet (ich habe vor kurzem angefangen, Elektrotechnik zu studieren), aber selbst nachdem ich genau kopiert hatte, was da war (außer den Anschlüssen und dem Zeug), funktionierte es immer noch nicht.
Ich hatte gehofft, jemand hier könnte einen kurzen Blick darauf werfen und erkennen, was los ist. Ich weiß nicht mehr, was ich tun soll.
#include <avr/io.h>
#include <util/delay.h>
//These are the DDR and PORT associated with the 8 bits data send/received
#define LCD_DDR DDRC
#define LCD_PORT PORTC
//LCD_COMMAND_DDR if you will, so with the three pins Enable/RegisterSelect/ReadWrite
#define LCD_CMD_DDR DDRD
#define LCD_CMD_PORT PORTD
#define LCD_CMD_RS PIND0
#define LCD_CMD_RW PIND1
#define LCD_CMD_E PIND2
#define LED_PIN PIND7
//Just some defenitions to make it easier for me
#define LCD_CLEAR_DISPLAY 0b00000001
#define LCD_CURSOR_HOME 0b00000010
//Enable display/cursor/blink
#define LCD_DISP_ALL 0b00001111
//Set it to 8 bits mode
#define LCD_SET_MODE 0b00111000
// Set Auto-increment noshift
#define LCD_SET_AI_NOSHIFT 0b00000110
void initializeLCD();
void commandLCD(unsigned char d);
void putcLCD(unsigned char c);
void checkIfBusy();
void switchEnable();
int main(void)
{
initializeLCD();
putcLCD(0x41);
putcLCD('A');
putcLCD('L');
putcLCD('L');
putcLCD('O');
}
void initializeLCD()
{
LCD_DDR = 0xFF;
LCD_PORT = 0x00;
LCD_CMD_DDR = 0xFF;
LCD_CMD_PORT = 0x00;
_delay_ms(200);
commandLCD(LCD_SET_MODE);
commandLCD(LCD_DISP_ALL);
commandLCD(LCD_CLEAR_DISPLAY);
commandLCD(LCD_SET_AI_NOSHIFT);
}
void checkIfBusy()
{
//Set LCD DDR to input
LCD_DDR = 0x00;
//Set RegisterSelect low so the 'inner registry' is selected (not the characters on the screen)
LCD_CMD_PORT &= ~(1 << LCD_CMD_RS);
//Set ReadWrite high so I can read data
LCD_CMD_PORT |= 1 << LCD_CMD_RW;
while(LCD_PORT >= 0x80)
{
switchEnable();
}
//ReadWrite back to low so I can write to it again
LCD_CMD_PORT &= ~(1 << LCD_CMD_RW);
//DDR back to output
LCD_DDR = 0xFF;
}
void switchEnable()
{
//Enable high
LCD_CMD_PORT |= (1 << LCD_CMD_E);
asm volatile ("nop"); //delay a bit (tried it also with _delay_ms(200);
asm volatile ("nop");
//Enable low
LCD_CMD_PORT &= ~(1 << LCD_CMD_E);
}
void commandLCD(unsigned char d)
{
//delay untill busyflag is off
checkIfBusy();
//put command to the port
LCD_PORT = d;
//set both RegisterSelect and ReadWrite low
LCD_CMD_PORT &= ~((1 << LCD_CMD_RS)|(1 << LCD_CMD_RW));
switchEnable();
// Clear the port
LCD_PORT = 0x00;
_delay_ms(2);
}
void putcLCD(unsigned char c)
{
//see if we're done
checkIfBusy();
// put character to port
LCD_PORT = c;
//Set ReadWrite low
LCD_CMD_PORT &= ~(1 << LCD_CMD_RW);
//Set RegisterSelect high
LCD_CMD_PORT |= (1 << LCD_CMD_RS);
switchEnable();
LCD_PORT = 0x00;
_delay_ms(2);
}
Nach der Antwort unten:
int main(void)
{
LCD_DDR = 0xFF;
LCD_PORT = 0x00;
LCD_CMD_DDR = 0xFF;
LCD_CMD_PORT = 0x00;
initializeLCD();
putcLCD(0x41);
}
void initializeLCD()
{
_delay_ms(15);
initCommandLCD(0b00110000);
_delay_ms(5);
initCommandLCD(0b00110000);
_delay_ms(100);
initCommandLCD(0b00110000);
_delay_ms(100);
initCommandLCD(0b00111000);
_delay_ms(100);
initCommandLCD(0b00001000);
_delay_ms(100);
initCommandLCD(0b00000001);
_delay_ms(100);
initCommandLCD(0b00000111);
_delay_ms(100);
}
void checkIfBusy()
{
LCD_DDR = 0;
LCD_CMD_PORT |= 1 << LCD_CMD_RW;
LCD_CMD_PORT &= ~(1 << LCD_CMD_RS);
while(LCD_PORT >= 0x80)
{
switchEnable();
}
LCD_DDR = 0xFF;
}
void switchEnable()
{
LCD_CMD_PORT |= (1 << LCD_CMD_E);
_delay_ms(2);
LCD_CMD_PORT &= ~(1 << LCD_CMD_E);
}
void initCommandLCD(unsigned char d)
{
LCD_PORT = d;
LCD_CMD_PORT &= ~((1 << LCD_CMD_RW)|(1 << LCD_CMD_RS));
switchEnable();
LCD_PORT = 0;
}
void commandLCD(unsigned char d)
{
checkIfBusy();
initCommandLCD(d);
}
void putcLCD(unsigned char c)
{
checkIfBusy();
LCD_PORT = c;
LCD_CMD_PORT &= ~(1 << LCD_CMD_RW);
LCD_CMD_PORT |= (1 << LCD_CMD_RS);
switchEnable();
LCD_PORT = 0;
}
Ok, ich habe mir das Tutorial-Video angesehen. Ich kann das Datenblatt für den LCD-Treiber nicht finden, also gehe ich nur von dem Beispiel aus, das Sie verlinkt haben. Sie haben ein paar wichtige Unterschiede:
Ihre Befehlssequenz ist nicht in der Reihenfolge des Beispiels. Es ist wichtig, die gleiche Reihenfolge zu haben, da einige Befehle manchmal zwei oder mehr Bytes umfassen.
Sie warten nur 2 µs nach jedem Befehl, im Gegensatz zu nur nach dem LCD_CLEAR_DISPLAY
. Der Code aus dem Video und der Webseite zeigt eine Verzögerung von 50 µs nach dem, was Sie den LCD_SET_MODE
Befehl und den folgenden Befehl genannt haben.
Sie senden dann einen anderen Befehl LCD_SET_AI_NOSHIFT
als 0b00000110
, auf der Webseite sendet er einen ähnlichen unbenannten Befehl von 0b00001110
.
Versuchen Sie, Ihre Verzögerungszeiten zu erhöhen und dieselbe Befehlssequenz wie im Beispiel zu senden.
Ich hoffe, das löst Ihr Problem.
EDIT: Ah, habe das Datenblatt gefunden . Außerdem stelle ich fest, dass Sie zwischen den Befehlen nach beschäftigt suchen. Der Set-Mode-Befehl 0b00000110
dauert 37 µs, aber das sollte wegen der Überprüfung in Ordnung sein. Das Datenblatt sagt jedoch, dass das Busy-Flag nicht überprüft werden kann, bevor der Set-Mode-Befehl gesendet wird und einige ms danach. Überprüfen Sie Seite 45 des verlinkten Datenblatts für die Initialisierungsroutine. Versuchen Sie, die Verzögerungen fest zu codieren, während sie geschrieben sind, und sehen Sie, ob es immer noch nicht funktioniert.
_delay_ms(15); putcLCD('A');
Soweit ich weiß, gibt es keinen Befehl zum Einschalten des LCD0x0F
für LCD an, Cursor an und Blinken an (S.24).Ich musste JTAG oben in meinem Main deaktivieren:
MCUCSR = (1<<JTD);
MCUCSR = (1<<JTD);
Es funktioniert jetzt, mein Code ist gut, ich muss mein LCD nicht manuell initialisieren. Löschen Sie einfach den Bildschirm und optionale Befehle.
Endgültiger Code:
#include <avr/io.h>
#include <util/delay.h>
#include <math.h>
#define LCD_DDR DDRC
#define LCD_PORT PORTC
#define LCD_CMD_DDR DDRD
#define LCD_CMD_PORT PORTD
#define LCD_CMD_RS PIND0
#define LCD_CMD_RW PIND1
#define LCD_CMD_E PIND2
#define LED_PIN PIND7
void initializeLCD();
void commandLCD(unsigned char d);
void putcLCD(unsigned char c, unsigned char c1);
void checkIfBusy();
void switchEnable();
void putsLCD();
void lcdNewLine();
void resetLCD();
int currentLine = 0;
int currentChar = 0;
int main(void)
{
MCUCSR = (1 << JTD);
MCUCSR = (1 << JTD);
LCD_DDR = 0xFF;
LCD_PORT = 0x00;
LCD_CMD_DDR = 0xFF;
LCD_CMD_PORT = 0x00;
initializeLCD();
while(1)
{
putsLCD("Printstuff");
_delay_ms(3000);
}
}
void initializeLCD()
{
_delay_ms(15);
commandLCD(0x01);
commandLCD(0b00111100);
}
void checkIfBusy()
{
LCD_DDR = 0x00;
LCD_CMD_PORT |= 1 << LCD_CMD_RW;
LCD_CMD_PORT &= ~(1 << LCD_CMD_RS);
while(LCD_PORT >= 0x80)
{
switchEnable();
}
LCD_DDR = 0xFF;
}
void switchEnable()
{
LCD_CMD_PORT |= (1 << LCD_CMD_E);
_delay_ms(2);
LCD_CMD_PORT &= ~(1 << LCD_CMD_E);
}
void commandLCD(unsigned char d)
{
checkIfBusy();
LCD_PORT = d;
LCD_CMD_PORT &= ~((1 << LCD_CMD_RW)|(1 << LCD_CMD_RS));
switchEnable();
LCD_PORT = 0;
}
void putcLCD(unsigned char c, unsigned char c1)
{
if(c == '\n')
{
lcdNewLine();
return;
}
if (currentChar >= 20 && c != ' ' && c1 != ' ' && c1 != '\0')
{
currentChar = 0;
putcLCD('-', ' ');
lcdNewLine();
}
if (c == ' ' && currentChar == 1)
return;
checkIfBusy();
LCD_PORT = c;
LCD_CMD_PORT &= ~(1 << LCD_CMD_RW);
LCD_CMD_PORT |= (1 << LCD_CMD_RS);
switchEnable();
LCD_PORT = 0x00;
currentChar++;
}
void resetLCD()
{
checkIfBusy();
commandLCD(0x01);
currentChar = 1;
currentLine = 1;
}
void lcdNewLine()
{
char line = 20;
switch(currentLine)
{
case 1:
line *= 2;
break;
case 2:
line *= 1;
break;
case 3:
line *= 4.2;
break;
}
line += 0b10000000;
checkIfBusy();
commandLCD(line);
currentLine += 1;
currentChar = 1;
}
void putsLCD(unsigned char *s)
{
checkIfBusy();
resetLCD();
int maxCount = strlen(s);
int i;
for(i = 0; i < maxCount; i++)
{
if(s[i] == '\0')
break;
char arg2 = ' ';
if(i + 1 < maxCount)
arg2 = s[i + 1];
putcLCD(s[i], arg2);
}
}
pjc50
Samuel
Erstaunliche Träume
Erstaunliche Träume
Samuel
Erstaunliche Träume
Erstaunliche Träume
LCD_CMD_PORT &= ~(1 << LCD_CMD_E);
in switchEnable hat nicht funktioniert.Erstaunliche Träume
Samuel
Erstaunliche Träume
Erstaunliche Träume
pjc50
Erstaunliche Träume
Lundin
Erstaunliche Träume