Mam problem z wysterowaniem wyświetlacza LCD na ATMEGA8.
Podejrzewam że gdzieś zrobiłem jakiegoś byka i świeże spojrzenie na problem może pomóc.
Wyświetlacz (WH2004A 4x20) podłączam pod portC Atmegi. Piny PC0-PC3 podłączyłem pod DB4-DB7 LCD, pin PC4 to RS w LCD, PC5 to sygnał E.
Wejścia R/W, DB0-DB3 podpięte do masy.
I żadnej reakcji ze strony wyświetlacza
Podejrzewam że gdzieś zrobiłem jakiegoś byka i świeże spojrzenie na problem może pomóc.
Wyświetlacz (WH2004A 4x20) podłączam pod portC Atmegi. Piny PC0-PC3 podłączyłem pod DB4-DB7 LCD, pin PC4 to RS w LCD, PC5 to sygnał E.
Wejścia R/W, DB0-DB3 podpięte do masy.
I żadnej reakcji ze strony wyświetlacza
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
//#include <util/delay.h>
#include <stdio.h>
#include <avr/pgmspace.h>
// Definicje dotyczace LCD
#define LCD PORTC //port z LCD
#define RS 4 // wybor rejestru
#define E 5 // sygnal zezwalajacy (enable)
#define SET_RS sbi(PORTC,PC4)
#define CLR_RS cbi(PORTC,PC4)
#define SET_E sbi(PORTC,PC5)
#define CLR_E cbi(PORTC,PC5)
//Definicje i markodeklaracje
//Definicje do delay-a
#define F_CPU 8000000 // 8MHz zegar procesora
#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond
#define LEDP1ON sbi(PORTD,PD0)
#define LEDP2ON sbi(PORTD,PD1)
#define LEDP1OFF cbi(PORTD,PD0)
#define LEDP2OFF cbi(PORTD,PD1)
#define LEDP1 PD0
#define LEDP2 PD1
//F-cje odpowiedzialne za delay
void delayp(unsigned int us)
{
do{asm("nop");}while(--us);
}
void delay_ms(unsigned int ms)
{
unsigned int i;
for (i=0;i<ms;i++)
{
delayp(999);
asm volatile (
"WDR"::);
}
}
void write_to_lcd(char x)
//void write_to_lcd(unsigned int x)
{
//Zapisujemy najpierw starsza czesc bajtu, nastepnie mlodsza
//po ustawieniu bajtow na wejsciach LCD wystawiamy sygnal E
CLR_E;
delay_ms(1);
LCD=(LCD & 0x0F)|(x>>4);//starsza czesc bajtu
SET_E;
delay_ms(5);
CLR_E;
delay_ms(1);
LCD=(LCD & 0x0F)|(x&0x0f);//mlodsza czesc bajtu
SET_E;
delay_ms(5);
CLR_E;
}
//***************** procedura zapisu instrukcji do wyświetlacza LCD
void LCD_write_command(char x)
{
CLR_RS; // niski stan na RS -> zapis instrukcji
delay_ms(1);
write_to_lcd(x); // zapis do LCD
}
//***************** procedura zapisu danej do wyświetlacza LCD
void LCD_write_char(char x)
{
SET_RS; // wysoki stan na RS -> zapis danej
delay_ms(1);
write_to_lcd(x); // zapis do LCD
}
//***************** procedura zapisu tekstu do wyświetlacza LCD
void LCD_write(char * s)
{
while(*s) // do napotkania 0
{
LCD_write_char(*s); // zapisz znak wskazywany przez s na LCD
s++; // zwiększ s (przygotuj nastepny znak)
}
}
void LCD_write_P(const char *s)
{
register char c;
while((c = pgm_read_byte(s))) // do napotkania 0
{
LCD_write_char(c); // zapisz znak wskazywany przez s na LCD
s++; // zwiększ s (przygotuj nastepny znak)
}
}
//***************** procedura inicjalizacji wyświetlacza LCD
void LCD_init(void)
{
delay_ms(15);
CLR_E; // E = 0
CLR_RS; // RS = 0
char i; // zmienna licznikowa
for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
{
SET_E; // E = 1
// LCD &= 0x30; //
CLR_E; // E = 0
delay_ms(5); // czekaj 5ms
}
SET_E; // E = 1
//LCD &= 0x2E; //
CLR_E; // E = 0
delay_ms(1); // czekaj 1ms
LCD_write_command(0x28); // interfejs 4-bity, 2-linie, znak 5x7
LCD_write_command(0x08); // wyłącz LCD, kursor i miganie
LCD_write_command(0x01); // czyść LCD
LCD_write_command(0x06); // bez przesuwania w prawo
LCD_write_command(0x0C); // włącz LCD, bez kursora i mrugania*/
LCD_write_command(0x03);
LCD_write_command(0x01);
//LCD_write_command(0x0F);//wlacz LCD, kursor i miganie
}
//***************** procedura ustawiania pozycji kursora
void LCD_xy(unsigned char w, unsigned char k)
{
LCD_write_command((w*0x40+k) | 0x80);
}
//***************** czysci wyswietlacz LCD
void LCD_clear(void)
{
LCD_write_command(0x01);
}
main()
{
DDRC|=_BV(PC0)|_BV(PC1)|_BV(PC2)|_BV(PC3)|_BV(PC4)|_BV(PC5);
//Diody statusu
DDRD |= _BV(LEDP1)|_BV(LEDP2);
const char pea[]="HELLO"; //stala dla wyswietlacza
do
{
LCD_init();
delay_ms(1000);
LCD_clear();
const char s="f";
LCD_write_char(s);
LCD_write_P(pea);
delay_ms(1000);
}
while(1);
}