Właściwie tytuł trochę sprowadza na manowce bo co prawda będę opowiadał o wyświetlaczach czy wyświetlaczu LCD, lecz temat będzie trochę szerszy i dotyczyć będzie LCD I²C. Precyzując, przestawię sposób co prawda nie nowy, ale bardzo ciekawy i praktyczny, w jaki sterować zwykłym wyświetlaczem znakowym LCD, skonstruowanym na sterowniku HD44780 przez magistralę TWI (I²C) w Bascom AVR.
Tajemnicza nazwa z tytułu – LCD Chip On Board określa rodzaj konstrukcji wyświetlacza i że tak powiem są to pospolite wyświetlacze jedno, dwu i cztero wierszowe. Swego czasu, a było to w maju 2013 roku, w końcu zdecydowałem się na zakup modułu o nazwie LCM1602 IIC. Określę go nazwą interfejsu sprzętowego LCD I²C. Wyśmienity pomysł polega na podłączeniu do wyprowadzeń zwykłego wyświetlacza znakowego LCD, expandera IO magistrali I²C. Moduły te wygrzebałem w sieci internet dużo wcześniej, lecz nie czułem się na sile samodzielnie oprogramować komunikacji do wyświetlacza za pośrednictwem takiego interfejsu. Niby nic skomplikowanego bo trzeba by dorwać specyfikację sterownika HD44780, poczytać i poćwiczyć wysyłanie odpowiednich bajtów … ale komu by się chciało skoro jest gotowa biblioteka dla środowiska Bascom AVR ;-D Można ją pobrać ze strony producenta środowiska programistycznego dla µC AVR MCS Elecrtonics. Ha – sęk w tym, iż modułów takich na dziś dzień jest już kilka wersji i różnią się między sobą nie tylko topologią wyprowadzeń do wyświetlacza. Więc w tamtym to czasie zacząłem się przyglądać i bibliotece i modułowi oczywiste było to, że kod biblioteki nie pasował do modułu i wtedy to, nie za bardzo wiedziałem jak go poprawić. 🙄
Przygotowałem sobie w tamtym czasie ściągawkę z opisem wyprowadzeń i coś tam grzebałem, grzebałem aż temat przysechł. Rozwiązanie bardzo mi się podobało z uwagi na fakt, że zwykły wyświetlacz jest sterowany za pomocą dwóch pinów µC – magistrali TWI, oraz że tak sterowanych wyświetlaczy może być kilka, co jest nie tak błahą i łatwą do uzyskania zaletą. Przy okazji wyświetlacz może powędrować na „większą” odległość od jednostki MCU, która nim zarządza. (Detale jak osiągnąć sporą długość magistrali przy okazji mojego opisu I²C TWI – jak kaktus “dawał po garach” ;-D) A z tytułu użycia tego interfejsu i jego oprogramowania mamy możliwość programowego załączania i wyłączania podświetlenia wyświetlacza. Wszystko również dzięki komunikacji magistralą TWI. Sterowanie załączaniem podświetlenia odbywa się wyprowadzeniem P3 portu expandera. Normalnie same zalety.
Moduł został skonstruowany tak aby sposób sterowania podświetleniem można było zmienić, bez integracji w obwód PCB. Dzięki takiej funkcjonalności można też pokusić się o wykonanie płynnej regulacji podświetlenia wyświetlacza. Ja w tym celu nie grzebał bym w bibliotece do obsługi nowego interfejsu, a rozłączył zworkę i odpowiedni pin wysterował sygnałem PWM, doprowadzając dodatkowy przewód od µC.
Tak się składa, że to tematu powracałem kilkakrotnie lecz ciągle było coś bardziej istotnego i moduł trafiał do szuflady 😉 Przez ten cały okres naczytałem się wiele o różnych dysfunkcjach spowodowanych nieprawidłowym funkcjonowaniem biblioteki, powodującym z kolei nieprawidłowe inicjowanie sterownika wyświetlacza … Aż pewnego razu przeglądając forum http://www.mcselec.com znalazłem ulepszoną wersję biblioteki prezentowanej na początku tego artykułu. Nie występują w niej problemy z wyświetleniem zdefiniowanych znaków oraz uczynniona została funkcjonalność załączania podświetlenia – względem poprzedniej wersji.
Mając do dyspozycji narzędzie w postaci nowej biblioteki bl_lcd_i2c.lib z obsługi wyświetlacza korzystamy tak jak dotychczas, dzięki standardowym rozkazom BascomAVR. Dodać należy jedynie „kawałek konfiguracji”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
'I2c LCD on Arduino Nano 16x2 display with backlight $regfile = "M328pdef.dat" ' the used chip $crystal = 16000000 ' frequency used $baud = 9600 ' baud rate $lib "i2c_twi.lib" 'hardware i2c/TWI $lib "bl_Lcd_i2c.lib" ' AN #118 library from Kent Config Twi = 100000 ' with this addition ' * lds r27,{backlight} ' andi _temp2,&hf7 ' or _temp2,r27 'LCD-display including backlight '0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 '1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 'G 5 C R R E D D D D D D D D B B 'N O S W 0 1 2 3 4 5 6 7 L L 'D V N S 'PCF8574 'P7 = D7 'P6 = D6 'P5 = D5 'P4 = D4 'P3 = 1 = backlight on / 0 = backlight off 'P2 = E 'P1 = RW 'P0 = RS '( Const Pcf_d4 = 4 Const Pcf_d5 = 5 Const Pcf_d6 = 6 Const Pcf_d7 = 7 Const Pcf_rs = 0 Const Pcf_rw = 1 Const Pcf_e1 = 2 ') Const Pcf_rs = 0 Const Pcf_rw = 1 'not used, set to 0 to ground for write Const Pcf_e1 = 2 Const Pcf_e2 = 3 'podświetlenie ON/OFF Const Pcf_d4 = 4 Const Pcf_d5 = 5 Const Pcf_d6 = 6 Const Pcf_d7 = 7 Declare Sub I2c_scan Dim B As Byte Dim A As Byte Dim _lcd_e As Byte Dim Backlight As Byte Backlight_on Alias &H08 Backlight_off Alias &H00 Backlight = Backlight_on _lcd_e = 128 Const Pcf8574_lcd = &H40 'definicja adresu bazowego ekspandera I/O dla naszego LCD Config Scl = Portc.5 'konfiguracja magistrali TWI Config Sda = Portc.4 'I2cinit 'Call I2c_scan 'if you want to check if the PCF8574 is seen activate this Wait 2 Do Cls Home 'kursor w pierwszej pozycji pierwszej linii Lcd "i2c-display" 'wyświetlamy tekst Wait 1 Lowerline 'przejście do niższej lini, kursor na pierwszą pozycję Wait 1 Lcd "Shift this." 'wyświetlamy tekst Wait 1 For A = 1 To 10 Shiftlcd Right 'przesuwamy tekst o jedną pozycję w prawo Waitms 250 'krótka przerwa w działaniu Next For A = 1 To 10 Shiftlcd Left 'przesuwamy tekst o jedną pozycje w lewo Waitms 250 'krótka przerwa w działaniu Next Locate 2 , 1 'ustawiamy kursor w pozycji Lcd "*" 'wyświetlamy jeden znak Wait 1 'krótka przerwa w działaniu Shiftcursor Right 'przesunięcie kursora Lcd "@" 'wyświetlamy jeden znak Wait 1 'krótka przerwa w działaniu Home Upper 'przejście do linii wyżej, kursor na pierwszą pozycję Lcd "Replaced." 'nadpisujemy stary tekst Wait 1 'krótka przerwa w działaniu Cursor Off Noblink 'ukrywamy kursor Wait 1 'krótka przerwa w działaniu Cursor On Blink 'uaktywniamy kursor Wait 1 'krótka przerwa w działaniu Display Off 'wyświetlacz off Wait 1 'krótka przerwa w działaniu Display On 'wyświetlacz on 'Now lets build a special character 'the first number is the characternumber (0-7) 'The other numbers are the rowvalues 'Use the LCD tool to insert this line Deflcdchar 2 , 32 , 10 , 32 , 14 , 17 , 17 , 17 , 14 ' replace ? with number (0-7) Deflcdchar 0 , 32 , 4 , 32 , 14 , 18 , 18 , 18 , 13 ' replace ? with number (0-7) Deflcdchar 1 , 32 , 10 , 32 , 14 , 18 , 18 , 18 , 13 ' replace ? with number (0-7) _lcd_e = 128 Cls 'select data RAM Rem it is important that a CLS is following the deflcdchar statements because it will set the controller back in datamode Lcd Chr(0) ; Chr(1) 'print the special character '----------------- Now use an internal routine ------------ _temp1 = 2 'value into ACC !rCall _write_lcd 'put it on LCD '************************************************************************** Wait 2 Loop End Sub I2c_scan ' check all devices on the I2c-bus Print "Scan start" For B = 0 To 254 Step 2 'for all odd addresses I2cstart 'send start I2cwbyte B 'send address If Err = 0 Then 'we got an ack Print "Slave at : " ; B ; " hex : " ; Hex(b) ; " bin : " ; Bin(b) End If I2cstop 'free bus Next Print "End Scan" End Sub |
Zamieszczony kod dostosowałem do swoich potrzeb, i prezentuje on „nowe” możliwości. Proszę zauważyć, że praktycznie nic się nie zmieniło w programowej obsłudze wyświetlacza. Doszła jedynie nowa deklaracja biblioteki:
1 |
$lib "bl_Lcd_i2c.lib" |
oraz najistotniejsze:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Const Pcf_rs = 0 Const Pcf_rw = 1 'not used, set to 0 to ground for write Const Pcf_e1 = 2 Const Pcf_e2 = 3 'podświetlenie ON/OFF Const Pcf_d4 = 4 Const Pcf_d5 = 5 Const Pcf_d6 = 6 Const Pcf_d7 = 7 Dim _lcd_e As Byte Dim Backlight As Byte Backlight_on Alias &H08 Backlight_off Alias &H00 Backlight = Backlight_on _lcd_e = 128 |
od góry:
konfiguracja topologii wyprowadzeń,
deklaracja niezbędnych zmiennych,
przypisanie poprawnych wartości nowym zmiennym.
Uwagi może wymagać kwestia omówienia zmiennej _lcd_e, do której przypisujemy odpowiednią wartość zależną od tego którą linię wyświetlacza – E mamy „uczynnić”. Z założenia biblioteka miała być uniwersalna i obsługiwać wyświetlacze z dwoma wyprowadzeniami E.
;define a constant named PCF8574_LCD pointing to the i2c address
;dimension _lcd_e as byte to control the E-lines (4 lines LCD:s)
;_lcd_e should have one of the following values
;128 to enable E1, 64 to enable E2, 192 to enable both E1 and E2 (cls, deflcdchar)
;Connect the following pins from PCF8574 to LCD
;
;P0 – D4
;P1 – D5
;P2 – D6
;P3 – D7
;P4 – RS
;P5 – RW (not used, set to 0 to ground for write)
;P6 – E2 (on 1 or 2 line display nc)
;P7 – E1
Tak wygląda zapis autora w oryginale biblioteki.
W naszym zastosowaniu jej funkcjonalność została zmodyfikowana na rzecz możliwości sterowania podświetleniem. Niemniej potrzeba podania wymaganego stanu na pin E pozostała.
Więc od tej pory obsługa wyświetlacza znakowego przez temu podobny interfejs magistrali TWI nie powinna przysporzyć problemów – nie wolno zapominać jedynie o przypisaniu odpowiedniego adresu w kodzie, pod którym zgłosi się ekspander PCF8547. Wracając jeszcze do samej konstrukcji modułu, warto wspomnieć, iż sterowanie podświetleniem buforowane jest tranzystorem J3Y – S0850. Oraz nowsze wersje modułu posiadają rezystory pull-up dla wejść adresowych!
Praktycznie do tematu wróciłem gdy dostałem do przetestowania bardzo interesujący wyświetlacz COB – LCD 1602A Qapass o organizacji 16 znaków w 2 wierszach. Oznaczenie producenta Eone Qapass – 1602A. Jako wyświetlacz negatywowy charakteryzuje go doskonała czytelność nawet z większej odległości i nie koniecznie jak określa producent z kierunku godziny 6. Dodatkowe walory i nutę ekskluzywności zapewnia niebieskie tło dla białych napisów. Test zlecił Wojciech prowadzący sklep i witrynę firmową moduliki.pl.
Korzystając ze sposobności, iż omawiam stosowanie wyświetlaczy znakowych LCD w nowej odsłonie, poruszę jeszcze jeden istotny fakt. Dotyczy on sprzętu i wymaganych elementów zewnętrznych niezbędnych aby wyświetlacz pracował prawidłowo. Mianowicie mam na myśli ustawianie kontrastu, oraz sterowanie podświetleniem. Wszyscy przywykliśmy do tego, że podświetlenie po prostu włączamy lub wyłączamy. Do celów komunikacji z użytkownikiem produktu finalnego w postaci opracowanego urządzenia, możemy sterować jasnością wyświetlacza lub wręcz mrugać podświetleniem. A jako bajer użytkownik może mieć możliwość ustawienia sobie maksymalnej jasności, czy intensywności podświetlenia. Odmienną sprawą jest ustawienie kontrastu, gdzie „lekceważąco wszyscy konstruktorzy wtykają” na PCB potencjometr montażowy, który w końcowym efekcie ukryty jest w czeluściach urządzenia. Jednak zwrócę uwagę na to, że obie nastawy mogą być realizowane programowo w „nastawach urządzenia” (menu), oczywiście o ile udostępnimy taką możliwość. Jak to zrobić? – można wykorzystać w tym celu hardware lub software PWM. I doprowadzić dwie linie do wyświetlacza, z których jedna może bezpośrednio sterować podświetleniem, a druga przez układ całkujący (RC) odpowiedzialna będzie za nastawę kontrastu. Przez programową modyfikację wypełnienia generowanego przebiegu prostokątnego PWM, wpływać będziemy na efekt wizualny.Oczywiście na dziś dzień są dostępne w sprzedaży wyświetlacze LCD z wbudowaną obsługą magistrali TWI, lecz w chwili obecnej ich cena dużo przewyższa koszt zakupu prostego wyświetlacza i modułu omawianego interfejsu.
nota katalogowa IC expandera
PCF8574-expander_IO.pdf (5892 pobrania )
nota katalogowa wyświetlacza
eone-QAPASS_1602a1.pdf (5400 pobrań )
nota katalogowa tranzystora
J3Y_S8050LT1.pdf (3881 pobrań )
jeśli ktoś zechce osobiście „przerobić temat” przydatne mogą okazać się linki:
http://www.avr-praxis.de/forum/showthread.php?2130-I2C-LCD-%28-auch-Arduino-%29-mit-PCF8574-OHNE-LIB-betreiben/page12
http://forum.atnel.pl/topic4578.html
http://www.elektroda.pl/rtvforum/topic2721360.html
http://bascom-forum.de/archive/index.php/t-4045.html?s=31c6341cda392fbfb262e98e75ba2401
http://rn-wissen.de/wiki/index.php/LCD-Modul_am_AVR
http://www.mikrocontroller.net/topic/47219