I'm trying to write a program in C to display text on this LCD, for some reason it displays nothing at all. I followed this tutorial on youtube and used my schoolbook (I recently started studying electrical engineering), but even after exactly copying what was there (except for the ports and stuff) it still didn't not work.
I was hoping someone here could have a quick look and spot what's going on. I don't know what to do anymore.
#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);
}
After answer below:
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;
}