miltien Napisano Lipiec 12, 2011 Udostępnij Napisano Lipiec 12, 2011 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 // //------------------------------------------------------------------------------------------------- Cytuj Link do komentarza Share on other sites More sharing options...
Barto Lipiec 12, 2011 Udostępnij Lipiec 12, 2011 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 } //... 1 Cytuj Link do komentarza Share on other sites More sharing options...
miltien Lipiec 14, 2011 Autor tematu Udostępnij Lipiec 14, 2011 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 😋 Cytuj Link do komentarza Share on other sites More sharing options...
Jerry26 Styczeń 15, 2013 Udostępnij Styczeń 15, 2013 Witam,a można z tych znaków składać inne ? To by mi trochę ułatwiło życie, np. z litery "o" "z" " ' ", złożyć "ó" albo "ź" ? A jeśli można, to jak najprościej to zrobić ? Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. 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
BlackJack Styczeń 25, 2013 Udostępnij Styczeń 25, 2013 Można definiować własne znaki, ale nie można z dwóch znaków, złożyć jednego. Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!