Obs?uga LCD na HD44780 w C (WinAVR)

Jul 19, 2010 1 Replies

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.


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 :-)

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required