LCD w C
- Aro
- Użytkownik
- Posty: 677
- Rejestracja: 30 paź 2006, 18:49
- Lokalizacja: Świerczyniec | Wrocław
- Kontakt:
LCD w C
Jest jakaś biblioteka w C do obsługi alfanumerycznego wyświetlacza LCD? Jak zrobic taką bibliotekę, czy plik, żeby wpis tekstu czy zmiennej na LCD sprowadzał się do jednego polecenia w głównym pliku źródłowym?
-
ZbeeGin
- Aro
- Użytkownik
- Posty: 677
- Rejestracja: 30 paź 2006, 18:49
- Lokalizacja: Świerczyniec | Wrocław
- Kontakt:
Troche tego jest. Wszystko sie dobrze kompiluje i ładuje do procka, no ale jak to bywa z czymś nowym oczywiście nie działa
. Pozmieniałem plik .h do moich potrzeb, no ale widocznie coś przegapiłem. Jak to poustawiac, bo te oznaczenia w pliku.h dotyczące lini
danych były troche dziwne. Ja mam wyświetlacz 1*16zn. podłączony do potru c tak: Rs-Pc.5, Ena-Pc.4, D4-Pc.3, D5-Pc.2, D6-Pc.1, D7-Pc.0
danych były troche dziwne. Ja mam wyświetlacz 1*16zn. podłączony do potru c tak: Rs-Pc.5, Ena-Pc.4, D4-Pc.3, D5-Pc.2, D6-Pc.1, D7-Pc.0
-
ZbeeGin
Tak zrobiłeś? (frament z pliku nagłówkowego lcd.h):
Nie używaną linię RW dałem na PC6.
Kod: Zaznacz cały
#define LCD_IO_MODE 1 /**< 0: memory mapped mode, 1: IO port mode */
#if LCD_IO_MODE
/**
* @name Definitions for 4-bit IO mode
* Change LCD_PORT if you want to use a different port for the LCD pins.
*
* The four LCD data lines and the three control lines RS, RW, E can be on the
* same port or on different ports.
* Change LCD_RS_PORT, LCD_RW_PORT, LCD_E_PORT if you want the control lines on
* different ports.
*
* Normally the four data lines should be mapped to bit 0..3 on one port, but it
* is possible to connect these data lines in different order or even on different
* ports by adapting the LCD_DATAx_PORT and LCD_DATAx_PIN definitions.
*
*/
#define LCD_PORT PORTC /**< port for the LCD lines */
#define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN 3 /**< pin for 4bit data bit 0 */
#define LCD_DATA1_PIN 2 /**< pin for 4bit data bit 1 */
#define LCD_DATA2_PIN 1 /**< pin for 4bit data bit 2 */
#define LCD_DATA3_PIN 0 /**< pin for 4bit data bit 3 */
#define LCD_RS_PORT LCD_PORT /**< port for RS line */
#define LCD_RS_PIN 5 /**< pin for RS line */
#define LCD_RW_PORT LCD_PORT /**< port for RW line */
#define LCD_RW_PIN 6 /**< pin for RW line */
#define LCD_E_PORT LCD_PORT /**< port for Enable line */
#define LCD_E_PIN 4 /**< pin for Enable line */
#elif defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || defined(__AVR_ATmega64__) || \
defined(__AVR_ATmega8515__)|| defined(__AVR_ATmega103__) || defined(__AVR_ATmega128__) || \
defined(__AVR_ATmega161__) || defined(__AVR_ATmega162__)
/*
* memory mapped mode is only supported when the device has an external data memory interface
*/
#define LCD_IO_DATA 0xC000 /* A15=E=1, A14=RS=1 */
#define LCD_IO_FUNCTION 0x8000 /* A15=E=1, A14=RS=0 */
#define LCD_IO_READ 0x0100 /* A8 =R/W=1 (R/W: 1=Read, 0=Write */
#else
#error "external data memory interface not available for this device, use 4-bit IO port mode"
#endif
- Aro
- Użytkownik
- Posty: 677
- Rejestracja: 30 paź 2006, 18:49
- Lokalizacja: Świerczyniec | Wrocław
- Kontakt:
dokładnie tak miałem. Nie jestem do końca pewny czy to wszystkie zmiany jakie trzeba wprowadzic. Zmieniałem jeszcze typ wyświetlacza na 1 linia 16 znaków(to jest kilka linijek wyżej od ustawień wyprowadzeń).
xtal=4000000 ustawiany troche wyżej to chyba nie powód niedziałania bo mam kwarc 1MHz
Kod: Zaznacz cały
#define LCD_LINES 1 /**< number of visible lines of the display */
#define LCD_DISP_LENGTH 16 /**< visibles characters per line of the display */
#define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */
#define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
#define LCD_START_LINE2 0x40 /**< DDRAM address of first char of line 2 */
#define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */
#define LCD_START_LINE4 0x54 /**< DDRAM address of first char of line 4 */
#define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */xtal=4000000 ustawiany troche wyżej to chyba nie powód niedziałania bo mam kwarc 1MHz
-
ZbeeGin
Myślę, że trzeba zmienić jeszcze dane w części:
Bo wyświetlacze 1x16 mają to do siebie, że w większości wewnętrznie są to dwie linie po 8 znaków, tylko połączone tak, by widać było jedną linię 16 znakową. Patrz: http://home.wanadoo.nl/electro1/avr/sof ... AYYBJP.pdf (str. 10)
Kod: Zaznacz cały
#define LCD_LINES 2 /**< number of visible lines of the display */ <-- tutaj
#define LCD_DISP_LENGTH 8 /**< visibles characters per line of the display */ <--tutaj
#define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */
#define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
#define LCD_START_LINE2 0x40 /**< DDRAM address of first char of line 2 */
#define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */
#define LCD_START_LINE4 0x54 /**< DDRAM address of first char of line 4 */
#define LCD_WRAP_LINES 1 /**< 0: no wrap, 1: wrap at end of visibile line */ <-- i tutaj
Ostatnio zmieniony 01 sty 1970, 1:00 przez ZbeeGin, łącznie zmieniany 1 raz.
- Aro
- Użytkownik
- Posty: 677
- Rejestracja: 30 paź 2006, 18:49
- Lokalizacja: Świerczyniec | Wrocław
- Kontakt:
Nic
. Raz tylko po zresttowaniu zapaliła się pierwsza kratka co chyba powinno oznaczac inicjację wyświetlacza jak się nie mylę. Próbowałem wszystkich możliwości, podłanczałem też pod wyświetlacz 2*16(odpowiednio zmodyfikowany .h) i też nic.
Mam jeszcze takie pytanie - czy to może byc powód kompilacji na starej wersji AVR-GCC? Ja mam 20050214.
Mam jeszcze takie pytanie - czy to może byc powód kompilacji na starej wersji AVR-GCC? Ja mam 20050214.
-
ZbeeGin
Jeszcze jedno. Linię RW wyświetlacza łączysz z masą? Jeśli tak to podłącz do portu zgodnie z definicją. Choć nie przyglądałem się dokładnie, ale może biblioteka próbować coś odczytać z LCD.
[ Dodano: 2007-01-30, 19:01 ]
-------------
Moje boje z tym programem także zakończyły się niepowodzeniem. Zmieniłem definicję pod LCD 2*16, ATTiny2313 w płytce AVT3500. Kompilacja w środowisku WinAVR 20060421 przechodzi bez problemów, po wgraniu do procesora... także echo.
P.S. Jak widać nie jesteśmy sami: http://www.elektroda.pl/rtvforum/viewto ... 274ed70e55
[ Dodano: 2007-01-30, 19:01 ]
-------------
Moje boje z tym programem także zakończyły się niepowodzeniem. Zmieniłem definicję pod LCD 2*16, ATTiny2313 w płytce AVT3500. Kompilacja w środowisku WinAVR 20060421 przechodzi bez problemów, po wgraniu do procesora... także echo.
P.S. Jak widać nie jesteśmy sami: http://www.elektroda.pl/rtvforum/viewto ... 274ed70e55
Ostatnio zmieniony 30 sty 2007, 23:43 przez ZbeeGin, łącznie zmieniany 1 raz.
Sądzę, że też możesz poradzić sobie sam. Potrzebujesz tylko drobnej informacji. Jeżeli używasz linii R/W, to możesz wczytywać status z LCD i wiedzieć, kiedy kończy on wykonywanie poprzednich poleceń. Jeżeli nie masz możliwości odczytu, jak po podaniu na R/W na stałe "0", to musisz odczekać określony czas wynikający z realizacji zadanego polecenia. Być może wyjaśnią ci się te kwestie po lekturze:Aro pisze:(...)Koppel sobie z tym poradził, tylko nie wiem jak bo (...)
https://elportal.pl/index.php?module=Co ... y&ceid=319
co prawda nie jest to w C, ale liczy się algorytm działania.
-
ZbeeGin
Widzisz Gaweł, ta biblioteka którą obaj z Aro próbowaliśmy odpalć - z marnym skutkiem - posiada odpowiednie opóźnienia wplecone w procedury:
Nigdzie nie doszukałem się procedur odczytujących status LCD podczas wykonywania operacji zapisu - ale przy takim skompilikowaniu kodu (dużo robi preprocesor) mogłem je przeoczyć gdzieś w #define lub w warunkowej kompilacji...
Kod: Zaznacz cały
/*
* Initialize LCD to 8 bit memory mapped mode
*/
/* enable external SRAM (memory mapped lcd) and one wait state */
MCUCR = _BV(SRE) | _BV(SRW);
/* reset LCD */
delay(16000); /* wait 16ms after power-on */
lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */
delay(4992); /* wait 5ms */
lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */
delay(64); /* wait 64us */
lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */
delay(64); /* wait 64us */-
ZbeeGin
Z ostatniej chwili. Udało mi się uruchomić tą bibliotekę i testowy program na płytce AVT3500. Ale działa nieco niestabilnie - przekłamuje znaki, definicje CGRAM są błędne. Myślę, że to sprawa opóźnień (Mój Tiny2313 pracuje z wewnętrznym RC@4MHz).
Zmiany jakie wprowadziłem:
1. Definicje
Jest to: D4 = PB.4, D5=PD.5, D6 = PD.6, D7 = PD.7, Rs = PB.2, E = PB.3, RW do masy (choć definicja jest na PB.0 nie używam RW).
W kwestii informacyjnej:
Czyli jak widać standardowy LCD 16x2.
2. Żródło "LCD.C"
Czyli stałe opóźnienie bez odczytywania BUSY_FLAG z rejestrów LCD. Ujemny skutek: nie można odczytać bieżącego adresu pozycji kursora. Ta jedyna procedura jak się okazuje odczytuje coś z LCD, i jest wykorzystywana w bibliotece. Zatem tu kol. Gaweł miał rację.
3. Program główny "TEST_LCD.C"
Zmiana treści procedury wait_until_key_pressed() by reagowała na stan PD0. Tutaj jest µ-switch S1 na płyce AVT. Ale ta zmiana nie ma odbicia w samej bibliotece.
Zmiany jakie wprowadziłem:
1. Definicje
Kod: Zaznacz cały
#define LCD_PORT PORTB /**< port for the LCD lines */
#define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN 4 /**< pin for 4bit data bit 0 */
#define LCD_DATA1_PIN 5 /**< pin for 4bit data bit 1 */
#define LCD_DATA2_PIN 6 /**< pin for 4bit data bit 2 */
#define LCD_DATA3_PIN 7 /**< pin for 4bit data bit 3 */
#define LCD_RS_PORT LCD_PORT /**< port for RS line */
#define LCD_RS_PIN 2 /**< pin for RS line */
#define LCD_RW_PORT LCD_PORT /**< port for RW line */
#define LCD_RW_PIN 0 /**< pin for RW line */
#define LCD_E_PORT LCD_PORT /**< port for Enable line */
#define LCD_E_PIN 3 /**< pin for Enable line */W kwestii informacyjnej:
Kod: Zaznacz cały
#define LCD_LINES 2 /**< number of visible lines of the display */
#define LCD_DISP_LENGTH 16 /**< visibles characters per line of the display */2. Żródło "LCD.C"
Kod: Zaznacz cały
/*************************************************************************
loops while lcd is busy, returns address counter
*************************************************************************/
static uint8_t lcd_waitbusy(void)
{
// register uint8_t c;
/* wait until busy flag is cleared */
// while ( (c=lcd_read(0)) & (1<<LCD_BUSY)) {}
/* the address counter is updated 4us after the busy flag is cleared */
// delay(2);
delay(64);
/* now read the address counter */
// return (lcd_read(0)); // return address counter
return (0);
}/* lcd_waitbusy */3. Program główny "TEST_LCD.C"
Zmiana treści procedury wait_until_key_pressed() by reagowała na stan PD0. Tutaj jest µ-switch S1 na płyce AVT. Ale ta zmiana nie ma odbicia w samej bibliotece.
Wszystkie kody są na stronie www.elportal.pl/n0017. Jeśli czegoś tam brakuje, proszę o wiadomość na maila (zwykle odpowiadam szybciej niż na PW). Kody są opatrzone bogatymi komentarzami, więc nie powinno być problemu aby zrozumieć ich działania.Aro pisze:Koppel sobie z tym poradził, tylko nie wiem jak bo nie mam tych numerów EDW.
Widzę, że sprawę już zamknąłeś z innym programem. Chciałem jednak tylko przypomnieć jak z mojej strony wygląda sprawa
// Edit: usunąłem kropkę z linka do strony która utrudniała jej otwarcie.
Ostatnio zmieniony 02 lut 2007, 17:54 przez Koppel, łącznie zmieniany 1 raz.