Intenté mostrar hola mundo en un LCD de 20x4 con Atmega328. Pero no pude mostrar ningún personaje en la pantalla. No estoy seguro de dónde está el problema, ni la inicialización ni el orden de sincronización. Estoy utilizando PortB como puerto de datos y PortD0 como RS, PortD1 como RW y PortD2 como EN.
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#define dataport PORTB
#define commport PORTD
#define rs PD0
#define wr PD1
#define en PD2
int LCD_Init(void);
int LCD_SendData(unsigned char *);
int wrcomm(void);
int wrdata(void);
int main(void)
{
DDRB = 0xFF;
DDRD = 0xFF; //set portD 4,5,6 as output pins
_delay_ms(500);
LCD_Init();
while (1)
{
LCD_SendData("hello");
dataport = 0xC0;
wrcomm();
LCD_SendData("world");
}
//while(1);
return 1;
}
int LCD_Init(void)
{
//Function set
dataport = 0x38; //0b00111000, DL = "Low", 8-bit mode; N = "high", 2-line display; F=0, 5x8 display
wrcomm();
_delay_us(50);
//clear LCD screen
dataport = 0x01; //clear screen
wrcomm();
_delay_ms(2);
//display on/off control
dataport = 0x0e; //0b00001110, D=1, display is turned on; C=1, cursor is turned on; B=0, blink is off
wrcomm();
//cursor at line 1
dataport = 0x80;
wrcomm();
_delay_us(50);
//entry mode set
dataport = 0x06;
_delay_us(50);
//cursor or display shift
dataport = 0x1C; //0b00011100, S/C=1, R/L=1, shift all the display to the right, cursor moves according to the display
wrcomm();
_delay_us(50);
return 1;
}
int LCD_SendData(unsigned char *s)
{
unsigned char *j = s;
int i;
for (i = 0; i < strlen(j); i++)
{
dataport = j[i];
wrdata();
}
return 1;
}
int wrcomm(void)
{
commport &= ~(1 << rs); //selecting command register
commport &= ~(1 << wr); //selecting write mode
_delay_us(200);
commport |= 1 << en; //EN = 1
_delay_ms(1);
commport &= ~(1 << en); //EN = 0
_delay_ms(1);
return 1;
}
int wrdata(void)
{
commport |= 1 << rs; //selecting data register
commport &= ~(1 << wr); //selecting write mode
_delay_us(200);
commport |= 1 << en; //EN = 1
_delay_ms(1);
commport &= ~(1 << en); //EN = 0
_delay_ms(1);
return 1;
}