Skocz do zawartości

HD44780 własne znaki


miltien

Pomocna odpowiedź

Witam, potrzebuje kilka własnych znaków na wyświetlaczu zgodnym ze sterownikiem HD44780, przeglądając fora trafiłem na multum tematów ale niestety żaden nie był doprowadzony do końca, i nie było pokazanego rozwiązania, tylko teoria jak ma to działać:

Więc muszę umieścić w pamieci DD RAM Wyświetlacza ,znak pod odpowiednim adresem, korzystając z tej tabeli:

muszę użyć komendy DD RAM set z adresem pamięci;

oraz osiem razy Data write z kodem mojego znaku;

(opisuje wszystko dokładnie, żeby można było stwierdzić czy poprawnie myślę)

Spłodziłem coś takiego (na przykładzie znaku:

B01001

B01001

B01001

B01001

B01001

B01001

B01001

B01001

):

#include <avr/io.h>
#include <util/delay.h>
#include "HD44780.h"


#define F_CPU 1000000L


int main(void)
{
 	_delay_ms(100);
LCD_Initalize();									//inicjalizacja lcd

	char tab[8] = {0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09};

LCD_WriteCommand(0x40);								//wysylanie komendy do lcd:
													//0x40 - DD RAMset z adresem 0x00 
for(int i=0;i<=7;i++)

	{
 		LCD_WriteData(tab[i]);						//wysylanie danych do lcd
	}												//osiem razy 0x09 

LCD_WriteCommand(0x80);								//Busy flag read (bez tego nie zapisuje
													//zadnych danych do 0x00)				

LCD_WriteText(0x00);								//Wyswietla zawartosc 0x00

return 0;
}

Efektem tego kodu są wyświetlane "krzaki" na wyświetlaczu, co dziwne wyłączając i włączając uC znak robi się coraz bardziej podobny do tego zdefiniowanego za 20 razem włączając uC mam dopiero wyświetlony zdefiniowany znak bez kilku pikseli, początkowo myślałem ze problem jest w zajętości "busy flag": wyświetlacza i dodałem jakieś delay ale nic nie pomogło, brakuje mi już pomysłów co możne być nie tak, prosiłbym o sprawdzenie czy faktycznie ten kontroler działa tak jak zrozumiałem, lub kawałek kodu żebym schematycznie zrozumiał i zmienił moje myślenie.

uC to ATMega8 z wewnętrznym oscylatorem;

wyświetlacz pracuje w trybie 8bit z sprawdzaniem busy flag;

używam bibliotek Radosława Kwietnia:

HD44780.h:

//-------------------------------------------------------------------------------------------------
// Wyświetlacz alfanumeryczny ze sterownikiem HD44780
// Sterowanie w trybie 8-bitowym z odczytem flagi zajętości
// Plik : HD44780.h	
// Mikrokontroler : Atmel AVR
// Kompilator : avr-gcc
// Autor : Radosław Kwiecień
// Źródło : http://radzio.dxp.pl/hd44780/
// Data : 24.03.2007
//-------------------------------------------------------------------------------------------------

#include <avr/io.h>
#include <util/delay.h>

//-------------------------------------------------------------------------------------------------
//
// Konfiguracja sygnałów sterujących wyświetlaczem.
// Można zmienić stosownie do potrzeb.
//
//-------------------------------------------------------------------------------------------------
#define LCD_RS_DIR		DDRB
#define LCD_RS_PORT 	PORTB
#define LCD_RS			(1 << PB0)

#define LCD_RW_DIR		DDRB
#define LCD_RW_PORT		PORTB
#define LCD_RW			(1 << PB1)

#define LCD_E_DIR		DDRB
#define LCD_E_PORT		PORTB
#define LCD_E			(1 << PB2)

#define LCD_DATA_DIR	DDRD
#define LCD_DATA_PORT	PORTD
#define LCD_DATA_PIN	PIND

//-------------------------------------------------------------------------------------------------
//
// Instrukcje kontrolera Hitachi HD44780
//
//-------------------------------------------------------------------------------------------------

#define HD44780_CLEAR					0x01

#define HD44780_HOME					0x02

#define HD44780_ENTRY_MODE				0x04
#define HD44780_EM_SHIFT_CURSOR		0
#define HD44780_EM_SHIFT_DISPLAY	1
#define HD44780_EM_DECREMENT		0
#define HD44780_EM_INCREMENT		2

#define HD44780_DISPLAY_ONOFF			0x08
#define HD44780_DISPLAY_OFF			0
#define HD44780_DISPLAY_ON			4
#define HD44780_CURSOR_OFF			0
#define HD44780_CURSOR_ON			2
#define HD44780_CURSOR_NOBLINK		0
#define HD44780_CURSOR_BLINK		1

#define HD44780_DISPLAY_CURSOR_SHIFT	0x10
#define HD44780_SHIFT_CURSOR		0
#define HD44780_SHIFT_DISPLAY		8
#define HD44780_SHIFT_LEFT			0
#define HD44780_SHIFT_RIGHT			4

#define HD44780_FUNCTION_SET			0x20
#define HD44780_FONT5x7				0
#define HD44780_FONT5x10			4
#define HD44780_ONE_LINE			0
#define HD44780_TWO_LINE			8
#define HD44780_4_BIT				0
#define HD44780_8_BIT				16

#define HD44780_CGRAM_SET				0x40

#define HD44780_DDRAM_SET				0x80

//-------------------------------------------------------------------------------------------------
//
// Deklaracje funkcji
//
//-------------------------------------------------------------------------------------------------

void LCD_WriteCommand(unsigned char);
unsigned char LCD_ReadStatus(void);
void LCD_WriteData(unsigned char);
unsigned char LCD_ReadData(void);
void LCD_WriteText(char *);
void LCD_GoTo(unsigned char, unsigned char);
void LCD_Clear(void);
void LCD_Home(void);
void LCD_Initalize(void);

//-------------------------------------------------------------------------------------------------
//
// Koniec pliku HD44780.h
//
//-------------------------------------------------------------------------------------------------

HD44780.c:

//-------------------------------------------------------------------------------------------------
// Wyświetlacz alfanumeryczny ze sterownikiem HD44780
// Sterowanie w trybie 8-bitowym z odczytem flagi zajętości
// Plik : HD44780.c	
// Mikrokontroler : Atmel AVR
// Kompilator : avr-gcc
// Autor : Radosław Kwiecień
// Źródło : http://radzio.dxp.pl/hd44780/
// Data : 24.03.2007
//-------------------------------------------------------------------------------------------------

#include "HD44780.h"


//-------------------------------------------------------------------------------------------------
//
// Funkcja zapisu bajtu do wyświetacza (bez rozróżnienia instrukcja/dane).
//
//-------------------------------------------------------------------------------------------------
void _LCD_Write(unsigned char dataToWrite)
{
LCD_DATA_DIR = 0xFF;

LCD_RW_PORT &= ~LCD_RW;
LCD_E_PORT |= LCD_E;
LCD_DATA_PORT = dataToWrite;
LCD_E_PORT &= ~LCD_E;
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja odczytu bajtu z wyświetacza (bez rozróżnienia instrukcja/dane).
//
//-------------------------------------------------------------------------------------------------

unsigned char _LCD_Read(void)
{
unsigned char tmp = 0;

LCD_DATA_DIR = 0x00;

LCD_RW_PORT |= LCD_RW;
LCD_E_PORT |= LCD_E;
asm("nop");
tmp = LCD_DATA_PIN;
LCD_E_PORT &= ~LCD_E;
return tmp;
}

//-------------------------------------------------------------------------------------------------
//
// Funkcja zapisu rozkazu do wyświetlacza
//
//-------------------------------------------------------------------------------------------------
void LCD_WriteCommand(unsigned char commandToWrite)
{
LCD_RS_PORT &= ~LCD_RS;
_LCD_Write(commandToWrite);
while(LCD_ReadStatus()&0x80);
}

//-------------------------------------------------------------------------------------------------
//
// Funkcja odczytu bajtu statusowego
//
//-------------------------------------------------------------------------------------------------
unsigned char LCD_ReadStatus(void)
{
LCD_RS_PORT &= ~LCD_RS;
return _LCD_Read();
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja zapisu danych do pamięci wyświetlacza
//
//-------------------------------------------------------------------------------------------------
void LCD_WriteData(unsigned char dataToWrite)
{
LCD_RS_PORT |= LCD_RS;
_LCD_Write(dataToWrite);
while(LCD_ReadStatus()&0x80);
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja odczytu danych z pamięci wyświetlacza
//
//-------------------------------------------------------------------------------------------------
unsigned char LCD_ReadData(void)
{
LCD_RS_PORT |= LCD_RS;
return _LCD_Read();
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja wyświetlenia napisu na wyswietlaczu.
//
//-------------------------------------------------------------------------------------------------
void LCD_WriteText(char * text)
{
while(*text)
 LCD_WriteData(*text++);
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja ustawienia współrzędnych ekranowych
//
//-------------------------------------------------------------------------------------------------
void LCD_GoTo(unsigned char x, unsigned char y)
{
LCD_WriteCommand(HD44780_DDRAM_SET | (x + (0x40 * y)));
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja czyszczenia ekranu wyświetlacza.
//
//-------------------------------------------------------------------------------------------------
void LCD_Clear(void)
{
LCD_WriteCommand(HD44780_CLEAR);
_delay_ms(2);
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja przywrócenia początkowych współrzędnych wyświetlacza.
//
//-------------------------------------------------------------------------------------------------
void LCD_Home(void)
{
LCD_WriteCommand(HD44780_HOME);
_delay_ms(2);
}
//-------------------------------------------------------------------------------------------------
//
// Procedura inicjalizacji kontrolera HD44780.
//
//-------------------------------------------------------------------------------------------------
void LCD_Initalize(void)
{
unsigned char i;
LCD_DATA_DIR = 0xFF;
LCD_E_DIR 	|= LCD_E;   //
LCD_RS_DIR 	|= LCD_RS;  //
LCD_RW_DIR	|= LCD_RW;
_delay_ms(15); // oczekiwanie na ustalibizowanie się napiecia zasilajacego
LCD_RS_PORT &= ~LCD_RS; // wyzerowanie linii RS
LCD_E_PORT &= ~LCD_E;  // wyzerowanie linii E
LCD_RW_PORT  &= ~LCD_RW;

for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
 {
 LCD_E_PORT |= LCD_E;
 LCD_DATA_PORT = 0x3F;
 LCD_E_PORT &= ~LCD_E;
 _delay_ms(5); // czekaj 5ms
 }

LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_8_BIT); // interfejs 4-bity, 2-linie, znak 5x7
LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF); // wyłączenie wyswietlacza
LCD_WriteCommand(HD44780_CLEAR); // czyszczenie zawartosći pamieci DDRAM
LCD_WriteCommand(HD44780_ENTRY_MODE | HD44780_EM_SHIFT_CURSOR | HD44780_EM_INCREMENT);// inkrementaja adresu i przesuwanie kursora
LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_ON | HD44780_CURSOR_OFF | HD44780_CURSOR_NOBLINK); // włącz LCD, bez kursora i mrugania
}

//-------------------------------------------------------------------------------------------------
//
// Koniec pliku HD44780.c
//
//-------------------------------------------------------------------------------------------------
Link do komentarza
Share on other sites

Zajrzałem we własną bibliotekę i chyba znalazłem u ciebie błąd. Przy każdej z 8 lini definiowanego znaku musisz zmienić, w logicznym rozwiązaniu zwiększać numer adresu. Pod dany adres ląduje tylko jedna linia nowego znaku. Poza tym pamiętaj, że zawartość znaku mieści się w 5 najmłodszych bitach linii(0b 0 0 0 piskel1 piksel2 piksel3 piksel 4 piksel5). Jeszcze jedna sprawa- szanuj pamięć procka. Przyzwyczaj się do unsigned chara (0-255) przy 8-bitowcach bo z reguły wystarczają.

Tak na oko to powinno pójść:

//...
//LCD_WriteCommand(0x40);                                //wysylanie komendy do lcd:
                                                       //0x40 - DD RAMset z adresem 0x00
  char adres=0;
   for(unsigned char i=0;i<=7;i++)

       {
           LCD_WriteCommand(0x40|(adres+i));
           LCD_WriteData(tab[i]);                        //wysylanie danych do lcd
       }
//...
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dzięki Barto, dzięki tobie to rozkminiłem XD

A wiec dla wszystkich którzy mają ten sam problem:

(wszytko na przykładzie bibliotek Radzia)

Własne znaki definiujemy w ten sposób:

			char tab1[8] = {0,0,24,27,4,4,4,3};

	LCD_WriteCommand(0x40);								

		for(int i=0;i<=7;i++)      
LCD_WriteData(tab1[i]);																		

	LCD_WriteCommand(0x80);	

Gdzie tab1 to nasz znak:

dec bin

0 00000

0 00000

24 11000

27 11011

4 00100

4 00100

4 00100

3 00011

u mnie to znak stopni Celsjusza w jednym polu 😋

Na nasze osiem znaków mamy osiem "comand" 0x40 0x48 0x50 0x58 0x60 0x68 0x70 0x78

Odczytujemy je w ten sposób:

LCD_WriteData(0x00);

Kolejno z adresów 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07

Do zamknięcia 😋

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.