Obs?uga LCD na HD44780 w C (WinAVR)

Witam. Napisałem sterownik wyświetlacza wspomagając się jakąś zagramaniczną książką w C, używając kombajnu WinAVR + AVR Studio. Kompiluje się bez błędów. Natomiast nie działa jak powinno, w symulacji wyświetla bzdury, w "realu" za to nic.

Obsługa jest 4 bitowa. Schemat wyprowadzeń w/g płytki testowej and- tech (R/W zwarte do masy w tym schemacie, a pin0 - podświetlenie) :

formatting link
Symulowałem w Hapsim z ustawieniem 4 bitowym (dobrym?): Data : PORTA, HighNibble:4-7, LowNibble:4-7 EN : PORTA3 Read/Write : PORTA0 Select Pin: PORTA2

KOD : -----------------------------

#include <avr/io.h>

#include <util/delay.h>

// F_CPU zdefiniowane w opcjach projektu na 16MHz #define LCD_DataPort PORTA #define LCD_DataDR DDRA #define LCD_DataPin PINA

#define LCD_RS 2 #define LCD_RW 0 #define LCD_EN 3

void delay_us(int d) { _delay_us(d); } void delay_ms(int d) { _delay_ms(d); }

void lcdCommand(unsigned char cmnd) { LCD_DataPort = (LCD_DataPort & 0x0F) | (cmnd & 0xF0); LCD_DataPort &= ~ (1<<LCD_RS); // 0 -> command LCD_DataPort &= ~ (1<<LCD_RW); // LCD_DataPort |= ~ (1<<LCD_EN); delay_us(1); LCD_DataPort &= ~ (1<<LCD_EN);

delay_us(20);

LCD_DataPort = (LCD_DataPort & 0x0F) | (cmnd << 4); // LCD_DataPort |= ~ (1<<LCD_EN); delay_us(1); LCD_DataPort &= ~ (1<<LCD_EN); }

void lcdData(unsigned char data) { LCD_DataPort = (LCD_DataPort & 0x0F) | (data & 0xF0); LCD_DataPort |= (1<<LCD_RS); // 1 -> data LCD_DataPort &= ~ (1<<LCD_RW); // 0 -> write

LCD_DataPort |= (1<<LCD_EN); // H to L pulse delay_us(1); LCD_DataPort &= ~ (1<<LCD_EN);

LCD_DataPort = (LCD_DataPort & 0x0F) | (data << 4); LCD_DataPort |= (1<<LCD_EN); // H to L pulse delay_us(1); LCD_DataPort &= ~ (1<<LCD_EN); }

void lcd_init() { LCD_DataDR = 0xFF;

LCD_DataPort &= ~(1<<LCD_EN); delay_us(2000);

lcdCommand(0x33); delay_us(100); lcdCommand(0x32); delay_us(100); lcdCommand(0x28); delay_us(100); lcdCommand(0x0e); delay_us(100); lcdCommand(0x01); delay_us(2000); lcdCommand(0x06); delay_us(100); }

void lcd_print( char *str) { unsigned char i=0; while(str[i]!=0) { lcdData(str[i]); i++; }

}

int main(void) { lcd_init(); while(1) { lcd_print("a"); delay_ms(10); } return 0; }

----------------------------------------

Co zrobiłem źle ? Co powinienem poprawić ? Dopiero zaczynam z tym zabawę i przyjemniej się uczyć "z nauczycielem", niż bez, bo szybciej. Patrzyłem na ten kod i sam chyba za łatwo nie znajdę błędu. Dzięki za pomoc.

Reply to
Jan Górski
Loading thread data ...

Wystąpił błąd w procedurze inicjacji wyświetlacza w tryb 4 bit.

Powinno wyglądać np tak :

// KOD ---------------------------------------------

delay_ms(20); LCD_DataDR = 0xFF; LCD_DataPort &= ~(1<<LCD_RS); // zeruje RS LCD_DataPort &= ~(1<<LCD_EN); // zeruje E delay_ms(2);

for (int i = 0; i < 3; i++ ) { LCD_DataPort |= ~(1<<LCD_EN); lcdCommand(0x33); LCD_DataPort &= ~(1<<LCD_EN); // zeruje E delay_ms(5); } LCD_DataPort |= ~(1<<LCD_EN); lcdCommand(0x32); LCD_DataPort &= ~(1<<LCD_EN); // zeruje E delay_ms(2);

// KONIEC KODU ----------------------------

Dalej trzeba pokonfigurować pamięć, karetkę itp. Co ciekawe, często bez tych zabiegów symulacja Hapsim działa, a właściwy wyświetlacz wywala śmieci.

Powodzenia wszystkim stawiającym pierwsze kroki :-)

Reply to
Jan Górski

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.