Estoy intentando escribir un programa en C para mostrar texto en este LCD, por alguna razón no muestra nada en absoluto. Seguí el este tutorial en YouTube y usé mi libro escolar (recientemente empecé a estudiar eléctrico. ingeniería), pero incluso después de copiar exactamente lo que estaba allí (a excepción de los puertos y esas cosas) todavía no funcionó.
Esperaba que alguien de aquí pudiera echar un vistazo rápido y ver qué está pasando. No sé qué hacer más.
#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);
}
Después de la respuesta a continuación:
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;
}