Witam.
Mam problem z wyświetlaczem LCD 2x16 (1602FZA).
LCD cały czas wyświetla tylko kwadraty. Programuje na atmega8 i skorzystałem z kodu który mam w kursie. Gdzieś na elektrodzie wyczytałem że może być to problem z kompatybilnością.
"Co się tyczy wyświetlacza, to nie wiem czy ten 1602ZFA V1.0, oparty o sterownik ST7066U i ST7065C, jest w pełni kompatybilny ze sterownikiem HD44780 (a taki zastosował autor SKALARa), szczególnie jeżeli chodzi o sterowanie 4 bitowe (wiem, że z tym są problemy). "
Jak sobie poradzić z tym fantem.
KOD:
#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>
//w programie zak³ada siê, ¿e:
//a) wszystkie linie obs³uguj¹ce wyœwietlacz LCD
// s¹ pod³¹czone do jednego portu,
//b) linie DB4..7 s¹ pod³¹czone do linii 4..7 portu.
#define DDR_LCD DDRB
#define PORT_LCD PORTB
#define RS_LCD 2
#define EN_LCD 3
#define DB4_LCD 4
#define DB5_LCD 5
#define DB6_LCD 6
#define DB7_LCD 7
//deklaracje funkcji
void Wyslij_do_LCD(int8_t);
void WlaczLCD(void);
void CzyscLCD(void);
void WyswietlLCD(char*, int8_t);
//funkcja g³ówna
int main(void)
{
char napis[15] = "Witaj, kotlecie";
WlaczLCD();
WyswietlLCD(napis, 15);
for(; ; );
return 0;
}
//////////////////////////////////////////////
void Wyslij_do_LCD(int8_t bajt)
{
//ustawienie EN
PORT_LCD |= _BV(EN_LCD);
//wys³anie 4 najstarszych bitów danych
PORT_LCD = (bajt & 0xF0)|(PORT_LCD & 0x0F);
//potwierdzenie wys³ania danych (opadaj¹cym zboczem EN)
PORT_LCD &= ~(_BV(EN_LCD));
//zaczekaj cykl
asm volatile("nop");
//ustawienie EN
PORT_LCD |= _BV(EN_LCD);
//wys³anie 4 najm³odszych bitów danych
PORT_LCD = ((bajt & 0x0F)<<4)|(PORT_LCD & 0x0F);
//potwierdzenie wys³ania danych (opadaj¹cym zboczem EN)
PORT_LCD &= ~(_BV(EN_LCD));
//zaczekaj 40 us
_delay_us(40);
}
void WlaczLCD()
{
//ustawienie kierunku wyjœciowego linii pod³¹czonych do LCD
DDR_LCD = (0xF0)|(1<<RS_LCD)|(1<<EN_LCD);
//stan niski na liniach
PORT_LCD = 0;
//zaczekaj co najmniej 45 ms na ustabilizowanie siê napiêcia
_delay_ms(45);
//1
//ustaw liniê EN
PORT_LCD |= (1<<EN_LCD);
//za³aduj sekwencjê 0011
PORT_LCD |= (1<<DB4_LCD)|(1<<DB5_LCD);
//potwierdŸ opadaj¹cym zboczem EN
PORT_LCD &= ~(_BV(EN_LCD));
//zaczekaj co najmniej 4.1 ms
_delay_ms(4.1);
//2
//ustaw liniê EN
PORT_LCD |= (1<<EN_LCD);
//potwierdŸ opadaj¹cym zboczem EN sekwencjê 0011
PORT_LCD &= ~(_BV(EN_LCD));
//zaczekaj co najmniej 100 us
_delay_us(100);
//3
//ustaw liniê EN
PORT_LCD |= (1<<EN_LCD);
//potwierdŸ opadaj¹cym zboczem EN sekwencjê 0011
PORT_LCD &= ~(_BV(EN_LCD));
//zaczekaj co najmniej 100 us
_delay_us(100);
//4
//ustaw liniê EN
PORT_LCD |= (1<<EN_LCD);
//ustawienie interfejsu 4-bitowego
PORT_LCD &= ~(_BV(DB4_LCD));
//potwierdŸ opadaj¹cym zboczem EN
PORT_LCD &= ~(_BV(EN_LCD));
//ustaw parametry wyœwietlacza
//bit 4 = 0 (s³owo danych ma 4 bity)
//bit 3 = 1 (2 wiersze znaków)
//bit 2 = 0 (matryca 5x8 pikseli)
PORT_LCD &= ~(_BV(RS_LCD));
Wyslij_do_LCD(0b00101000);
PORT_LCD |= _BV(RS_LCD);
//ustaw tryb pracy wyœwietlacza
//bit 2 = 1 (inkrementowanie adresu zapisu danych)
//bit 1 = 1 (wy³¹czenie przesuwania w prawo)
PORT_LCD &= ~(_BV(RS_LCD));
Wyslij_do_LCD(0b00000110);
PORT_LCD |= _BV(RS_LCD);
//w³¹cz wyœwietlacz
//bit 2 = 1 (w³¹czenie wyœwietlania)
//bit 1 = 1 (kursor aktywny)
//bit 0 = 0 (kursor nie miga)
PORT_LCD &= ~(_BV(RS_LCD));
Wyslij_do_LCD(0b00001110);
PORT_LCD |= _BV(RS_LCD);
CzyscLCD();
}
void CzyscLCD()
{
PORT_LCD &= ~(_BV(RS_LCD));
Wyslij_do_LCD(1);
PORT_LCD |= _BV(RS_LCD);
//czekaj 1.64 ms
_delay_ms(1.64);
}
void WyswietlLCD(char *napis, int8_t ile)
{
int8_t k = 0;
while(k<ile)
{
Wyslij_do_LCD(napis[k]);
k++;
}
}
Mam problem z wyświetlaczem LCD 2x16 (1602FZA).
LCD cały czas wyświetla tylko kwadraty. Programuje na atmega8 i skorzystałem z kodu który mam w kursie. Gdzieś na elektrodzie wyczytałem że może być to problem z kompatybilnością.
"Co się tyczy wyświetlacza, to nie wiem czy ten 1602ZFA V1.0, oparty o sterownik ST7066U i ST7065C, jest w pełni kompatybilny ze sterownikiem HD44780 (a taki zastosował autor SKALARa), szczególnie jeżeli chodzi o sterowanie 4 bitowe (wiem, że z tym są problemy). "
Jak sobie poradzić z tym fantem.
KOD:
#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>
//w programie zak³ada siê, ¿e:
//a) wszystkie linie obs³uguj¹ce wyœwietlacz LCD
// s¹ pod³¹czone do jednego portu,
//b) linie DB4..7 s¹ pod³¹czone do linii 4..7 portu.
#define DDR_LCD DDRB
#define PORT_LCD PORTB
#define RS_LCD 2
#define EN_LCD 3
#define DB4_LCD 4
#define DB5_LCD 5
#define DB6_LCD 6
#define DB7_LCD 7
//deklaracje funkcji
void Wyslij_do_LCD(int8_t);
void WlaczLCD(void);
void CzyscLCD(void);
void WyswietlLCD(char*, int8_t);
//funkcja g³ówna
int main(void)
{
char napis[15] = "Witaj, kotlecie";
WlaczLCD();
WyswietlLCD(napis, 15);
for(; ; );
return 0;
}
//////////////////////////////////////////////
void Wyslij_do_LCD(int8_t bajt)
{
//ustawienie EN
PORT_LCD |= _BV(EN_LCD);
//wys³anie 4 najstarszych bitów danych
PORT_LCD = (bajt & 0xF0)|(PORT_LCD & 0x0F);
//potwierdzenie wys³ania danych (opadaj¹cym zboczem EN)
PORT_LCD &= ~(_BV(EN_LCD));
//zaczekaj cykl
asm volatile("nop");
//ustawienie EN
PORT_LCD |= _BV(EN_LCD);
//wys³anie 4 najm³odszych bitów danych
PORT_LCD = ((bajt & 0x0F)<<4)|(PORT_LCD & 0x0F);
//potwierdzenie wys³ania danych (opadaj¹cym zboczem EN)
PORT_LCD &= ~(_BV(EN_LCD));
//zaczekaj 40 us
_delay_us(40);
}
void WlaczLCD()
{
//ustawienie kierunku wyjœciowego linii pod³¹czonych do LCD
DDR_LCD = (0xF0)|(1<<RS_LCD)|(1<<EN_LCD);
//stan niski na liniach
PORT_LCD = 0;
//zaczekaj co najmniej 45 ms na ustabilizowanie siê napiêcia
_delay_ms(45);
//1
//ustaw liniê EN
PORT_LCD |= (1<<EN_LCD);
//za³aduj sekwencjê 0011
PORT_LCD |= (1<<DB4_LCD)|(1<<DB5_LCD);
//potwierdŸ opadaj¹cym zboczem EN
PORT_LCD &= ~(_BV(EN_LCD));
//zaczekaj co najmniej 4.1 ms
_delay_ms(4.1);
//2
//ustaw liniê EN
PORT_LCD |= (1<<EN_LCD);
//potwierdŸ opadaj¹cym zboczem EN sekwencjê 0011
PORT_LCD &= ~(_BV(EN_LCD));
//zaczekaj co najmniej 100 us
_delay_us(100);
//3
//ustaw liniê EN
PORT_LCD |= (1<<EN_LCD);
//potwierdŸ opadaj¹cym zboczem EN sekwencjê 0011
PORT_LCD &= ~(_BV(EN_LCD));
//zaczekaj co najmniej 100 us
_delay_us(100);
//4
//ustaw liniê EN
PORT_LCD |= (1<<EN_LCD);
//ustawienie interfejsu 4-bitowego
PORT_LCD &= ~(_BV(DB4_LCD));
//potwierdŸ opadaj¹cym zboczem EN
PORT_LCD &= ~(_BV(EN_LCD));
//ustaw parametry wyœwietlacza
//bit 4 = 0 (s³owo danych ma 4 bity)
//bit 3 = 1 (2 wiersze znaków)
//bit 2 = 0 (matryca 5x8 pikseli)
PORT_LCD &= ~(_BV(RS_LCD));
Wyslij_do_LCD(0b00101000);
PORT_LCD |= _BV(RS_LCD);
//ustaw tryb pracy wyœwietlacza
//bit 2 = 1 (inkrementowanie adresu zapisu danych)
//bit 1 = 1 (wy³¹czenie przesuwania w prawo)
PORT_LCD &= ~(_BV(RS_LCD));
Wyslij_do_LCD(0b00000110);
PORT_LCD |= _BV(RS_LCD);
//w³¹cz wyœwietlacz
//bit 2 = 1 (w³¹czenie wyœwietlania)
//bit 1 = 1 (kursor aktywny)
//bit 0 = 0 (kursor nie miga)
PORT_LCD &= ~(_BV(RS_LCD));
Wyslij_do_LCD(0b00001110);
PORT_LCD |= _BV(RS_LCD);
CzyscLCD();
}
void CzyscLCD()
{
PORT_LCD &= ~(_BV(RS_LCD));
Wyslij_do_LCD(1);
PORT_LCD |= _BV(RS_LCD);
//czekaj 1.64 ms
_delay_ms(1.64);
}
void WyswietlLCD(char *napis, int8_t ile)
{
int8_t k = 0;
while(k<ile)
{
Wyslij_do_LCD(napis[k]);
k++;
}
}