No i w końcu stało się … W końcu „poszedł na warsztat” wyświetlacz graficzny … Nie tam jakiś super nowoczesny, kolorowy, ale specyficzny, wszystkim dobrze znany – z telefonu … Traf tak chciał, że budując lub starając się uruchomić radyjko na TEA5767, na pierwszy strzał chciałem uruchomić projekt znaleziony w internecie. I proszę radio w projekcie wyposażone było w wyświetlacz 😉 i to nie byle jaki, bo jak wcześniej wspomniałem specyficzny. Wysoce energooszczędny (pobór prądu około 240µA przy zasilaniu napięciem 3,3V) niewielki 84 na 48 pikseli, zasilany ku mojej udręce napięciem 3,3V. Charakteryzujący się czytelnym polem o bardzo dobrych właściwościach, pochodzący z telefonu Nokia 3310 ;-p
Z istotnych zalet należy wymienić szeroki zakres temperatur pacy, od wysokich mrozów -25°C po ekstremalne upały 70°C, np w nagrzanym latem samochodzie pozostawionym na otwartym słońcu. Wyświetlacz pomieści 6 wierszy po 14 znaków. Przy organizacji: 6 kolumn i 8 wierszy (na znak). Z tego można obliczyć ile bajtów potrzeba na jeden wiersz – wychodzi 6 na każdy znak x 14 znaków = 84 bajty w 6 wierszach – co daje 504 bajty pamięci RAM w sterowniku. Układ wyświetlacza stanowi zintegrowany ze sterownikiem moduł LCD – GD47 i dwa kondensatory (nie wiem czy są wykorzystane). Moduł wykonany jest w technologii COG (Chip on Glass), z wyprowadzeniami typu ACF (Adhesive Conductive Film). Do pracy niezbędne są dwa kondensatory poza obwodem modułu, umieszczone na płytce drukowanej urządzenia współpracującego.
Sterownik ekranu zawiera HW-reset, tripler lub quadrupler napięcia zależnie od temperatury, układ kompensacji temperatury i kontroli napięcia niskiego zasilania.
Sterownik zawiera (jak to wspomniałem wcześniej) 84×48 bitów pamięci RAM. Jeden bit w pamięci RAM odwzorowuje jeden piksel na ekranie. Sterownik nie zawiera CG-ROM (generatora znaków). Brak generatora przysporzy dodatkowej pracy lecz możemy dowolnie definiować wielkość i rodzaj czcionki. Poszukując informacji o wyświetlaczu natrafiłem na dwa podawane w różnych artykułach oznaczenia sterownika -> LPH7779, oraz PCD8544. Modele te różnią się drobnymi detalami w postaci instrukcji (tryb negatywowy i ustawianie kontrastu). W odnalezionych informacjach znalazłem też wzmiankę o różnych modelach wyświetlaczy stosowanych w telefonach pochodzących od producentów: Philips i Seiko Epson. Co było by zgodne z odmiennymi oznaczeniami kontrolerów. Możemy je rozpoznać po rodzaju złącza i wyprowadzeniach w telefonie.

prosty sposób na identyfikację producenta modułu wyświetlacza, identyfikacja na podstawie typu złącza
Wyświetlacz ten można spotkać w telefonach
– Nokia 3210
– Nokia 3310
– Nokia 3330
– Nokia 5510
– Nokia 5110
– Nokia 6110
– Nokia 6150
– Nokia 8210
– Nokia 8850
Warto wspomnieć, że w telefonie Nokia 3410 znajduje się bardzo podobny wyświetlacz. Ma on większą rozdzielczość (96×65 pikseli), sterownik PCF8812 (Philips). Sterownik ten może obsłużyć matrycę większą – 102×65, niż zastosowana w tym wyświetlaczu telefonu. Mechanicznie i elektrycznie matryce do Nokii 3310 i 3410 są w pełni zamienne. Mają mieć identyczne wymiary, wyprowadzenia elektryczne.
Doskonały artykuł z minimum wiedzy o topologii wyprowadzeń dla „naszego” wyświetlacza.
Wyprowadzenia jakie mamy do dyspozycji to:
SDIN serial data input – Input for the clock signal: 0.0 to 4.0 Mbits/s.
SCLK serial clock input
D/C data/command – dla command aktywny stan niski
SCE chip enable – aktywny stan niski
RES external reset input – aktywny stan niski
VOUT do podłączenia kondensatora filtrującego zasilanie matrycy
VDD zasilanie
GND masa zasilania
Sterując wyświetlacz należy pamiętać, iż maksymalna częstotliwość sygnału SCLK nie może przekroczyć 4MHz aby wszystko dobrze funkcjonowało. Podanie prawidłowego sygnału reset też jest bardzo istotne, ponieważ nieprawidłowe może nawet uszkodzić moduł, co jest nawet zaznaczone w nocie katalogowej.
Gdy załączymy zasilanie należy odczekać 30ms i podać sygnał reset o czasie trwania 100ns.
Po załączeniu zasilania i zresetowaniu modułu musi nastąpić prawidłowa inicjalizacja sterownika LCD. Nie jest to nic innego jak seria instrukcji określających niezbędne parametry dla prawidłowej pracy. W tym momencie opowiem czego się naczytałem. Otóż model tego wyświetlacza stał się na tyle popularny, iż doczekał się też produkcji nazwijmy je „nieoryginalnych”. Prawdopodobnie nie zawsze są one w 100% zgodne z notą sterownika PCD8544, o którą jest oparty kod źródłowy przytoczony poniżej, z przykładem obsługi wyświetlacza. Co objawia się błędnym funkcjonowaniem lub całkowitym brakiem współpracy z wyświetlaczem. Ponoć zaradzić temu można przez modyfikację poleceń i parametrów służących do inicjalizacji.
Znalazłem też uwagi na temat kondensatora podłączanego do wyprowadzenia Vout. W nocie podana jest informacja o minimalnej wartości kondensatorów zewnętrznych wynoszącej 1µF, w różnych opracowaniach najczęściej widziałem kondensator o wartości 4,7µF. Niemniej nota zawiera też informację, iż zalecana jest większa pojemność od minimalnej. Czytając czyjeś opracowanie znalazłem informację o tym, że przy małych wartościach kondensatora Vout wyświetlacz (nie oryginalny) nie pracował poprawnie. Dopiero przy wartości dużo większej układ zaczął pracować.
A ja sobie myślę, że problemy mogą wynikać w związku z zastosowaniem różnych modeli zaimplementowanych sterowników, o których wspomniałem na wstępie bądź jeszcze odmiennych.
Tak, że w razie problemów należy zwrócić uwagę na kod inicjujący, oraz wartość tego kondensatora. Mnie na szczęście takie niedogodności nie spotkały, ale miałem inne problemy … o tym może później.
W tym momencie trzeba rozważyć sposób połączenia modułu z µC. O ile zdecydujemy się na wspólne zasilanie na poziomie 3,3V o tyle nie będzie wymagane dalsze zwracanie w tym temacie uwagi. Należy pamiętać tylko o stosownych kondensatorach. Co natomiast jeśli µC musi być zasilany napięciem wyższym – np 5V? Trzeba rozważyć dobry nieskomplikowany sposób translacji sygnałów magistrali, oraz dodatkowe zasilanie 3,3V dla modułu wyświetlacza. Można zastosować stabilizator ? – hehe przerost formy nad treścią i jakiś translator poziomów magistrali. Tutaj ułatwieniem będzie to, że komunikacja jest zawsze jednokierunkowa – od µC do wyświetlacza. Do translacji można zastosować któryś ze scalaków MAX3393, 74LS07, albo 2xLVC125. Mam na myśli kilka dróg postępowania:
1. olać wszystko, wszak jest pewna doza prawdopodobieństwa że wszystko (wyświetlacz) będzie działało przy napięciu zasilania 5V – takie napięcie jest dopuszczalne w określonych warunkach. Pewno kiedyś potestuję.
2. przejąć się i napchać tych wszystkich scalaków na PCB.
3. Wypośrodkować i zbudować „zasilacz” z szeregowego opornika i zenerki, bez translacji magistrali lub z, w postaci szeregowych oporników na liniach.
Teoretycznie i praktycznie większość układów scalonych zasilanych 3,3V toleruje sygnały na wejściach GPIO o poziomach logicznych 5V. Dla mnie czym mniej elementów tym lepiej ;-D – mniej pracochłonne i taniej wychodzi.
Do obsługi wyświetlacza w BASCOM znalazłem kilka rozwiązań programowych. Jedne oparte na komunikacji SPI ze wsparciem software lub hardware, przywiązujące nas do ściśle określonych pinów, a inne już w pełni realizowane programowo. Te drugie mi bardziej odpowiadało i te tutaj zaprezentuję. Zaznaczam, iż nie jestem autorem tego kodu, jedynie udało się go w kilku miejscach zoptymalizować. Kod pochodzi z forum elektroda. Kod oparty o SPI można przeglądać tutaj. W tym miejscu wspomnę jeszcze o pewnej zalecie komunikacji SPI, otóż z łatwością możemy zdefiniować w BASCOMie prędkość magistrali co nie jest bez znaczenia, w przypadku zastosowania rezonatorów wzorcowych o dużej częstotliwości. Do tego celu służy polecenie CONFIG SPI z parametrem CLOCKRATE gdzie CLOCKRATE = 4|16|64|128 (dotyczy tylko CONFIG SPI= HARD). W helpie wyczytamy:
The clock rate selects the division of the of the oscillator frequency that serves as the SPI clock. So with 4 you will have a clock rate of 4.000000 / 4 = 1 MHz , when a 4 MHZ XTAL is used.
W wybranym przeze mnie rozwiązaniu trzeba będzie programowo dostosować prędkość SCLK do kryterium wymaganego, w przypadku gdy µC będzie musiał pracować wydajniej. Można to uczynić np aseblerową instrukcją NOP.
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 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 |
'Set in Options, Compiler: $hwstack = 128 $swstack = 128 $framesize = 128 $regfile = "m8def.dat" $crystal = 4000000 'LCD VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV 'Config Pinb.0 = Output 'Config Pinb.2 = Output 'Config Pinb.1 = Output 'Config Pinb.3 = Output 'Config Pinb.5 = Output Dim Lcd_data As Byte Dim Updatelcd As Bit '1 = Update Dim Lcd_cache(504) As Byte 'data to send to LCD RAM Dim Lcdcacheidx As Word 'pointer Dim Ch As Byte '---------------------- Aliases ------------------------------------ '( Zasilanie Alias Portb.6 : Config Pinb.6 = 1 : Portb.6 = 0 ') Sclk Alias Portb.5 : Config Pinb.5 = 1 : Portb.5 = 0 Sdin Alias Portb.3 : Config Pinb.3 = 1 : Portb.3 = 0 Dc Alias Portb.0 : Config Pinb.0 = 1 : Portb.0 = 0 Sce Alias Portb.2 : Config Pinb.2 = 1 : Portb.2 = 0 Res Alias Portb.4 : Config Pinb.4 = 1 : Portb.4 = 0 '--------------------- LCD constants ----------------------------- Const Lcd_inver = &H0D 'inverted screen (after normal command mode) Const Lcd_normal = &H0C 'normal screen (after normal command mode) Const Test = &H09 'All pixels on (after normal command mode) Const Normal_command = &H20 'normal command mode '--------------------- LCD Sub declarations ------------------------- Declare Sub Lcdcmd_(byval Command As Byte ) Declare Sub Lcdinit Declare Sub Lcdclear Declare Sub Lcdupdate Declare Sub Lcdgoxy(byval X As Byte , Byval Y As Byte) 'from 1,1 to 14,6 Declare Sub Lcdchr(byval Ch As Byte , Byval Lcdfontsize As Byte , Byval Ch_inv As Byte) 'ch=character, Lcdfontsize 1 = high 1, Lcdfontsize 2=high 2, Ch_inv 1=inverse Declare Sub Lcdstr(byval Lcdstring As String , Byval Lcdfontsize As Byte , Byval Ch_inv As Byte) 'lcdstring = string to LCD, Lcdfontsize 1 = high 1, Lcdfontsize 2=high 2, Ch_inv 1=inverse Declare Sub Lcdpixel(byval X As Byte , Byval Y As Byte , Byval Pixelmode As Byte ) 'x 1-84, y 1-48, pixelmode 0=OFF, pixelmode 1=ON, pixelmode 2=XOR Declare Sub Lcdline(byval X1 As Byte , Byval Y1 As Byte , Byval X2 As Byte , Byval Y2 As Byte , Byval Pixelmode As Byte ) 'xy1=start, xy2=end of line, pixelmode as in Lcdpixel Declare Sub Lcdrectangle(byval X3 As Byte , Byval Y3 As Byte , Byval Wide As Byte , Byval Height As Byte) Declare Sub Show(byval Xx As Byte , Byval Yy As Byte) 'show bitmap from program memory. XX 1 to (84-_width), YY 1 to 6 (n*8) Declare Sub Clearshow(byval Xx As Byte , Byval Yy As Byte) 'clear window last show 'LCD ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Reset Res 'RESET LCD Waitms 10 Set Res '--------------------- LCD Init ---------------------------------- Call Lcdinit 'must be first in program!!! 'vvvvvvvvvvvvvvvvvvvv DEMO VVVVVVVVVVVVVVVVVVVVVVVVVVV Dim Ii As Byte Dim Wsk As Byte Wsk = 0 Do Lcdclear Lcdgoxy 6 , 6 Lcdstr "Text" , 1 , 0 Lcdupdate Wait 2 Lcdgoxy 1 , 1 Lcdstr "Normal" , 1 , 0 Lcdupdate Wait 2 Lcdgoxy 9 , 1 Lcdstr "Inwers" , 1 , 1 Lcdupdate Wait 2 Lcdgoxy 1 , 4 Lcdstr "Double" , 2 , 0 Lcdupdate Wait 2 Lcdclear Lcdgoxy 1 , 2 Lcdstr "Bitmap" , 2 , 0 Restore Egypt Show 1 , 4 Lcdupdate Wait 3 Lcdclear Lcdgoxy 1 , 4 Lcdstr "Piksele" , 2 , 0 Lcdgoxy 1 , 6 Lcdstr "Piksele" , 2 , 1 Lcdupdate Wait 1 For Ii = 1 To 84 If Wsk = 0 Then Wsk = 1 Else Wsk = 0 End If Lcdpixel Ii , 8 , Wsk Lcdupdate 'Waitms 10 Next Ii Lcdclear Lcdgoxy 3 , 3 Lcdstr " Line " , 1 , 0 Lcdupdate Wait 1 Lcdline 1 , 1 , 84 , 48 , 1 Lcdupdate Wait 3 Lcdgoxy 4 , 3 Lcdstr "Line XOR" , 1 , 1 Lcdgoxy 3 , 4 Lcdstr " " , 1 , 1 Lcdupdate Wait 1 Lcdline 84 , 1 , 1 , 48 , 2 Lcdupdate Wait 3 Lcdclear Lcdgoxy 3 , 3 Lcdstr "Rectangle " , 1 , 0 Lcdupdate Wait 1 Lcdrectangle 3 , 3 , 80 , 43 Lcdupdate Wait 2 Lcdclear Lcdgoxy 1 , 2 Lcdstr "1234567" , 2 , 0 Lcdgoxy 1 , 4 Lcdstr "7654321" , 2 , 0 Lcdgoxy 1 , 6 Lcdstr "1234567" , 2 , 0 Lcdupdate Wait 5 Loop '^^^^^^^^^^^^^^^^^^^^^ DEMO ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ' ----------------------- LCD subroutines ----------------------- '----------------------- Lcdcmd (Command) ---------------------- Sub Lcdcmd_(byval Command As Byte ) Local Licznik As Byte 'Local Licznik1 As Byte Sce = 0 'enable (SCE) Dc = 0 For Licznik = 7 To 0 Step -1 Sclk = 0 Sdin = Command.licznik Sclk = 1 Next Licznik Sclk = 0 Sce = 1 End Sub '----------------------- Lcdinit ------------------------------ Sub Lcdinit Waitms 50 ' Set Zasilanie Waitms 5 Reset Res 'RESET LCD Waitms 5 Set Res 'end of reset Set Sce 'in Lcdcmd() will be "L"! Call Lcdcmd_(&H21) 'extended command mode Call Lcdcmd_(&Hb8) 'c8LCD contrast (mayby you must change) Call Lcdcmd_(&H06) 'temperature compensation Call Lcdcmd_(&H13) 'bias 1:48 Call Lcdcmd_(&H20) 'normal command mode Call Lcdcmd_(&H0c) 'normal display Call Lcdcmd_(&H40) 'Y=0 Call Lcdcmd_(&H80) 'X=0 Call Lcdclear Call Lcdupdate End Sub '---------------------- Lcdclear ------------------------------ Sub Lcdclear Call Lcdcmd_(&H40) 'Y=0 Call Lcdcmd_(&H80) 'X=0 Local I As Word For I = 1 To 504 Lcd_cache(i) = 0 Next I ' Lcdcacheidx = 1 End Sub '--------------------- Lcdupdate ------------------------------- 'copy full LCD_cache to LCD RAM Sub Lcdupdate Local I As Word Local Licznik As Byte Call Lcdcmd_(&H80) 'sets 0 X-addr of RAM Call Lcdcmd_(&H40) 'sets 0 Y-addr of RAM For I = 1 To 504 Lcd_data = Lcd_cache(i) Sce = 0 'enable (SCE) Dc = 1 ' nop ' nop For Licznik = 7 To 0 Step -1 ' nop ' nop Sclk = 0 Sdin = Lcd_data.licznik Sclk = 1 Next Licznik ' nop ' nop Sclk = 0 Sce = 1 Next I Updatelcd = 0 End Sub '--------------------- Lcdgoxy-------------------------------- Sub Lcdgoxy(byval X As Byte , Byval Y As Byte) 'from 1,1 to 14,6 Local I As Word Local J As Word X = X - 1 I = X I = I * 6 Y = Y - 1 J = Y J = Y * 84 Lcdcacheidx = I + J Incr Lcdcacheidx 'Lcdchacheidx 1-504! End Sub '------------------ Lcdchr------------------------------------- Sub Lcdchr(byval Ch As Byte , Byval Lcdfontsize As Byte , Byval Ch_inv As Byte) '1 character on LCD Local I As Byte Local J As Word Local K As Byte Local Ba As Byte Local Bb As Byte Local Tmpidx As Word Local Tmpidx1 As Word If Ch < &H20 Then Ch = 92 If Ch > &H7B Then Ch = 92 J = Ch - 32 J = J * 5 If Lcdfontsize = 1 Then For I = 1 To 6 K = Lookup(j , Fontlookup) If Ch_inv = 1 Then 'negative If I = 6 Then 'black for 6 row K = 255 Else K = K Xor &HFF End If Else If I = 6 Then 'white for 6 row K = 0 End If End If Lcd_cache(lcdcacheidx) = K Incr Lcdcacheidx Incr J Next I Else 'high 2 Tmpidx = Lcdcacheidx - 84 'signs go up and can't be at 1,x For I = 1 To 6 If I = 6 Then If Ch_inv = 1 Then K = 255 Else K = 0 End If Else K = Lookup(j , Fontlookup) If Ch_inv = 1 Then K = K Xor &HFF End If End If Ba.0 = K.0 Ba.1 = K.0 Ba.2 = K.1 Ba.3 = K.1 Ba.4 = K.2 Ba.5 = K.2 Ba.6 = K.3 Ba.7 = K.3 Bb.0 = K.4 Bb.1 = K.4 Bb.2 = K.5 Bb.3 = K.5 Bb.4 = K.6 Bb.5 = K.6 Bb.6 = K.7 Bb.7 = K.7 Lcd_cache(tmpidx) = Ba 'up of character Incr Tmpidx Lcd_cache(tmpidx) = Ba 'double wide Incr Tmpidx Tmpidx1 = Tmpidx + 82 Lcd_cache(tmpidx1) = Bb 'down of character Incr Tmpidx1 Lcd_cache(tmpidx1) = Bb 'double wide Incr J Next I Lcdcacheidx = Lcdcacheidx + 12 '6+6 End If Kon_lcdchr: End Sub '-------------------- Lcdstr---------------------------------------- Sub Lcdstr(lcdstring As String , Lcdfontsize As Byte , Ch_inv As Byte) Local M As Byte Local N As String * 1 For M = 1 To Len(lcdstring) N = Mid(lcdstring , M , 1) Ch = Asc(n) Call Lcdchr(ch , Lcdfontsize , Ch_inv ) Next M End Sub '------------------- Lcdpixel -------------------------------------- Sub Lcdpixel(x As Byte , Y As Byte , Pixelmode As Byte ) Local Index As Word Local Offset As Byte Local I As Byte If X > 84 Then Goto End_lcdpixel If Y > 48 Then Goto End_lcdpixel Y = Y - 1 Index = Y / 8 Index = Index * 84 Index = Index + X Offset = Y / 8 Offset = Offset * 8 Offset = Y - Offset Lcd_data = Lcd_cache(index) I = 1 Shift I , Left , Offset Select Case Pixelmode Case 0: 'pixel off I = I Xor &HFF Lcd_data = Lcd_data And I Case 1: 'pixel on Lcd_data = Lcd_data Or I Case 2: 'pixel xor Lcd_data = Lcd_data Xor I End Select Lcd_cache(index) = Lcd_data End_lcdpixel: End Sub '----------------------- Lcdline ------------------------------------ Sub Lcdline(x1 As Byte , Y1 As Byte , X2 As Byte , Y2 As Byte , Pixelmode As Byte ) Local Dx As Integer Local Dy As Integer Local Stepx As Integer Local Stepy As Integer Local Fraction As Integer Local I As Byte Dy = Y2 - Y1 Dx = X2 - X1 If Dy < 0 Then Dy = -dy Stepy = -1 Else Stepy = 1 End If If Dx < 0 Then Dx = -dx Stepx = -1 Else Stepx = 1 End If Shift Dx , Left , 1 '-2 Shift Dy , Left , 1 '-2 Call Lcdpixel(x1 , Y1 , Pixelmode) If Dx > Dy Then I = Dx Shift I , Right , 1 '/2 Fraction = Dy - I While X1 <> X2 If Fraction >= 0 Then Y1 = Y1 + Stepy Fraction = Fraction - Dx End If X1 = X1 + Stepx Fraction = Fraction + Dy Call Lcdpixel(x1 , Y1 , Pixelmode) Wend Else I = Dy Shift I , Right , 1 '/2 Fraction = Dx - I While Y1 <> Y2 If Fraction >= 0 Then X1 = X1 + Stepx Fraction = Fraction - Dy End If Y1 = Y1 + Stepy Fraction = Fraction + Dx Call Lcdpixel(x1 , Y1 , Pixelmode) Wend End If Updatelcd = 1 End Sub ' ----------------------- LCDrectangle ----------------------- Sub Lcdrectangle(x3 As Byte , Y3 As Byte , Wide As Byte , Height As Byte) Wide = X3 + Wide Decr Wide Height = Y3 + Height Decr Height Call Lcdline(x3 , Y3 , Wide , Y3 , 1 ) Call Lcdline(x3 , Height , Wide , Height , 1 ) Call Lcdline(x3 , Y3 , X3 , Height , 1 ) Call Lcdline(wide , Y3 , Wide , Height , 1 ) End Sub '--------------------- Show ---------------------- 'XX 1 to (84-_width), YY 1 to 6 (n*8) 'must be RESTORE "data to show" before CALL it subrotine Sub Show(xx As Byte , Yy As Byte) Local Swidth As Byte Local Shigh As Byte Local Cacheidx As Word Local I As Byte Local J As Byte Local K As Byte Local L As Byte Read Swidth Read Shigh K = Yy + Shigh K = K - 1 L = Xx + Swidth L = L - 1 If K > 6 Then Goto End_show If L > 84 Then Goto End_show For I = Yy To K Cacheidx = I - 1 Cacheidx = Cacheidx * 84 Cacheidx = Cacheidx + Xx For J = Xx To L Read Ch Lcd_cache(cacheidx) = Ch Incr Cacheidx Next J Next I Updatelcd = 1 End_show: End Sub '--------------------- ClearShow ---------------------- 'XX 1 to (84-_width), YY 1 to 6 (n*8) 'must be RESTORE "data to show" before CALL it subrotine Sub Clearshow(xx As Byte , Yy As Byte) Local Swidth As Byte Local Shigh As Byte Local Cacheidx As Word Local I As Byte Local J As Byte Local K As Byte Local L As Byte Read Swidth Read Shigh K = Yy + Shigh K = K - 1 L = Xx + Swidth L = L - 1 For I = Yy To K Cacheidx = I - 1 Cacheidx = Cacheidx * 84 Cacheidx = Cacheidx + Xx For J = Xx To L Lcd_cache(cacheidx) = 0 Incr Cacheidx Next J Next I Updatelcd = 1 End Sub End 'end program 'end program ' Character generator ' This table defines the standard ASCII characters in a 5x7 dot format. '------------------------------------------------------------------------------/ $data Fontlookup: Data &H00 , &H00 , &H00 , &H00 , &H00 , ' sp Data &H00 , &H00 , &H2F , &H00 , &H00 , ' ! Data &H00 , &H07 , &H00 , &H07 , &H00 , ' " Data &H14 , &H7F , &H14 , &H7F , &H14 , ' # Data &H24 , &H2A , &H7F , &H2A , &H12 , ' $ Data &HC4 , &HC8 , &H10 , &H26 , &H46 , ' % Data &H36 , &H49 , &H55 , &H22 , &H50 , ' & Data &H00 , &H05 , &H03 , &H00 , &H00 , ' ' Data &H00 , &H1C , &H22 , &H41 , &H00 , ' ( Data &H00 , &H41 , &H22 , &H1C , &H00 , ' ) Data &H14 , &H08 , &H3E , &H08 , &H14 , ' - Data &H08 , &H08 , &H3E , &H08 , &H08 , ' + Data &H00 , &H00 , &H50 , &H30 , &H00 , ' , Data &H10 , &H10 , &H10 , &H10 , &H10 , ' - Data &H00 , &H60 , &H60 , &H00 , &H00 , ' . Data &H20 , &H10 , &H08 , &H04 , &H02 , ' / Data &H3E , &H51 , &H49 , &H45 , &H3E , ' 0 Data &H00 , &H42 , &H7F , &H40 , &H00 , ' 1 Data &H42 , &H61 , &H51 , &H49 , &H46 , ' 2 Data &H21 , &H41 , &H45 , &H4B , &H31 , ' 3 Data &H18 , &H14 , &H12 , &H7F , &H10 , ' 4 Data &H27 , &H45 , &H45 , &H45 , &H39 , ' 5 Data &H3C , &H4A , &H49 , &H49 , &H30 , ' 6 Data &H01 , &H71 , &H09 , &H05 , &H03 , ' 7 Data &H36 , &H49 , &H49 , &H49 , &H36 , ' 8 Data &H06 , &H49 , &H49 , &H29 , &H1E , ' 9 Data &H00 , &H36 , &H36 , &H00 , &H00 , ' : Data &H00 , &H56 , &H36 , &H00 , &H00 , ' ; Data &H08 , &H14 , &H22 , &H41 , &H00 , ' < Data &H14 , &H14 , &H14 , &H14 , &H14 , ' = Data &H00 , &H41 , &H22 , &H14 , &H08 , ' > Data &H02 , &H01 , &H51 , &H09 , &H06 , ' ? Data &H32 , &H49 , &H59 , &H51 , &H3E , ' @ Data &H7E , &H11 , &H11 , &H11 , &H7E , ' A Data &H7F , &H49 , &H49 , &H49 , &H36 , ' B Data &H3E , &H41 , &H41 , &H41 , &H22 , ' C Data &H7F , &H41 , &H41 , &H22 , &H1C , ' D Data &H7F , &H49 , &H49 , &H49 , &H41 , ' E Data &H7F , &H09 , &H09 , &H09 , &H01 , ' F Data &H3E , &H41 , &H49 , &H49 , &H7A , ' G Data &H7F , &H08 , &H08 , &H08 , &H7F , ' H Data &H00 , &H41 , &H7F , &H41 , &H00 , ' I Data &H20 , &H40 , &H41 , &H3F , &H01 , ' J Data &H7F , &H08 , &H14 , &H22 , &H41 , ' K Data &H7F , &H40 , &H40 , &H40 , &H40 , ' L Data &H7F , &H02 , &H0C , &H02 , &H7F , ' M Data &H7F , &H04 , &H08 , &H10 , &H7F , ' N Data &H3E , &H41 , &H41 , &H41 , &H3E , ' O Data &H7F , &H09 , &H09 , &H09 , &H06 , ' P Data &H3E , &H41 , &H51 , &H21 , &H5E , ' Q Data &H7F , &H09 , &H19 , &H29 , &H46 , ' R Data &H46 , &H49 , &H49 , &H49 , &H31 , ' S Data &H01 , &H01 , &H7F , &H01 , &H01 , ' T Data &H3F , &H40 , &H40 , &H40 , &H3F , ' U Data &H1F , &H20 , &H40 , &H20 , &H1F , ' V Data &H3F , &H40 , &H38 , &H40 , &H3F , ' W Data &H63 , &H14 , &H08 , &H14 , &H63 , ' X Data &H07 , &H08 , &H70 , &H08 , &H07 , ' Y Data &H61 , &H51 , &H49 , &H45 , &H43 , ' Z Data &H00 , &H7F , &H41 , &H41 , &H00 , ' [ Data &H55 , &H2A , &H55 , &H2A , &H55 , ' 55 Data &H00 , &H41 , &H41 , &H7F , &H00 , ' ] Data &H04 , &H02 , &H01 , &H02 , &H04 , ' ^ Data &H40 , &H40 , &H40 , &H40 , &H40 , ' _ Data &H00 , &H01 , &H02 , &H04 , &H00 , ' ' Data &H20 , &H54 , &H54 , &H54 , &H78 , ' a Data &H7F , &H48 , &H44 , &H44 , &H38 , ' b Data &H38 , &H44 , &H44 , &H44 , &H20 , ' c Data &H38 , &H44 , &H44 , &H48 , &H7F , ' d Data &H38 , &H54 , &H54 , &H54 , &H18 , ' e Data &H08 , &H7E , &H09 , &H01 , &H02 , ' f Data &H0C , &H52 , &H52 , &H52 , &H3E , ' g Data &H7F , &H08 , &H04 , &H04 , &H78 , ' h Data &H00 , &H44 , &H7D , &H40 , &H00 , ' i Data &H20 , &H40 , &H44 , &H3D , &H00 , ' j Data &H7F , &H10 , &H28 , &H44 , &H00 , ' k Data &H00 , &H41 , &H7F , &H40 , &H00 , ' l Data &H7C , &H04 , &H18 , &H04 , &H78 , ' m Data &H7C , &H08 , &H04 , &H04 , &H78 , ' n Data &H38 , &H44 , &H44 , &H44 , &H38 , ' o Data &H7C , &H14 , &H14 , &H14 , &H08 , ' p Data &H08 , &H14 , &H14 , &H18 , &H7C , ' q Data &H7C , &H08 , &H04 , &H04 , &H08 , ' r Data &H48 , &H54 , &H54 , &H54 , &H20 , ' s Data &H04 , &H3F , &H44 , &H40 , &H20 , ' t Data &H3C , &H40 , &H40 , &H20 , &H7C , ' u Data &H1C , &H20 , &H40 , &H20 , &H1C , ' v Data &H3C , &H40 , &H30 , &H40 , &H3C , ' w Data &H44 , &H28 , &H10 , &H28 , &H44 , ' x Data &H0C , &H50 , &H50 , &H50 , &H3C , ' y Data &H44 , &H64 , &H54 , &H4C , &H44 Egypt: Data 84 , 3, ' Image Table Name, Xbytes, N of Lines, 254 bytes Data &HFF , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01, Data &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H01 , &H81 , &H81 , &H81 , &H41 , &H41 , &H21, Data &H21 , &H31 , &H11 , &H11 , &H11 , &H11 , &H11 , &H31 , &H21 , &HA1 , &H41 , &HC1 , &H81 , &H81 , &H01 , &H01, Data &H01 , &H01 , &H01 , &H81 , &HC1 , &HE1 , &HF1 , &HF9 , &HFF , &HF3 , &H8D , &H11 , &H31 , &H41 , &H81 , &H81, Data &HE1 , &HF1 , &HF9 , &HFD , &HFF , &HFF , &HFD , &H09 , &H11 , &H21 , &H41 , &H81 , &H01 , &H01 , &H01 , &H01, Data &H01 , &H01 , &H01 , &HFF , &HFF , &H40 , &H40 , &H40 , &H40 , &H40 , &H40 , &H40 , &H40 , &H40 , &H40 , &H40, Data &H40 , &H40 , &H40 , &H40 , &H40 , &H40 , &H40 , &H40 , &H60 , &H60 , &H3C , &H04 , &H06 , &H03 , &H01 , &H00, Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H80 , &HE0 , &HE0 , &HF8 , &HFC , &HFE , &HFF , &HFF , &H82 , &H04, Data &H08 , &H30 , &HE1 , &HE3 , &HF4 , &HFC , &HFE , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HF0, Data &HFC , &HFC , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFE , &HE0 , &H00 , &H00 , &H00, Data &H01 , &H02 , &H04 , &H08 , &H10 , &H20 , &HC0 , &HFF , &HFF , &HFE , &HDE , &HFE , &HFE , &HFF , &HFE , &HFF, Data &HFE , &HFF , &HEF , &HEF , &HDF , &HDF , &HFF , &HEF , &HFF , &HEF , &HEF , &HEF , &HEF , &H9E , &HDE , &HDE, Data &HDE , &HDE , &HCE , &HCE , &HCE , &HEE , &HEE , &HCE , &H8E , &HCF , &HCF , &HCF , &HDF , &HEF , &HCF , &HEF, Data &HCF , &HEF , &HDF , &HFC , &HFE , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF, Data &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF, Data &HFF , &HFE , &HFC , &HFC , &HF8 , &HFC , &HFC , &HFF , &HFF , &HFF , &HFC , &HFF |
Kod jest bardzo dobrze opisany i raczej nie powinien wymagać wyjaśnień. Uwagi zasługuje fakt, iż zakomentowałem sterowanie zasilaniem wyświetlacza przy testach. Zasilanie brane jest w tym przykładzie z pina µC, który nim czynnie steruje, załączając je w stosownym momencie by spełnić wymogi czasowe. Po skompilowaniu kod zajmuje 6814 bajtów pamięci flash, więc wersja demo środowiska IDE już nie wystarczy. Wiadomo najwięcej miejsca pochłania grafika i definicja czcionki. Można je przegonić do EEPROM gdyż BASCOM umożliwia umieszczenie wartości z pół Data w tej pamięci. Służy do tego przełącznik $EEPROM zastosowany po etykiecie danych, szczegóły w helpie Bascom-Avr. Kod znacząco się wtedy odchudzi. Po uruchomieniu układu z załadowanym przykładowym kodem możemy cieszyć się demonstracją jak poniżej:
Przy zmianie wartości kontrastu w procedurze LCDINIT należy zwrócić szczególną uwagę na wpisywaną wartość. Ma ona bezpośredni wpływ na wartość napięcia zasilania matrycy – VOP. Można ustawić 128 wartości, ale użyteczny zakres regulacji to nastawy w zakresie 30…90. Po resecie nie jest zerowana zawartość pamięci RAM i należy usunąć z niej wartości przypadkowe, co widzimy pod koniec procedury inicjującej.
Tak jak wcześniej wspominałem sterownik nie ma generatora znaków więc znaki są definiowane samodzielnie w kodzie. Aby zdefiniować nowy obrazek i umieścić go w liniach Data można posłużyć się np programem FastLCD. Sprawa wtedy jest wyjątkowo banalna, i ogranicza się do ustawienia rozmiaru i przygotowania grafiki oraz do wklejenia kodu wynikowego do listingu.
Efekt pracy programu prezentowany na wyświetlaczu ;-D
Jedno co mnie zastanawia to fakt, że w czasie gdy chciałem zrobić fotografię kaktusków i w aparacie załączona była lampa błyskowa, gdy zadziałał flesz, na wyświetlaczu przestawało być widać cokolwiek …
Inne programy do konwersji grafik na kod: Hex Workshop, BMP2Hex, PictureConert II, AsystentLCD, FastLCD, XVI32
Ciekawe artykuły na jakie trafiłem o wyświetlaczu:
EP 2003/5 str. 81 Sterowanie graficznych wyświetlaczy z telefonów komórkowych firmy Nokia, część 1,
EP 2003/6 str. 83 Sterowanie graficznych wyświetlaczy z telefonów komórkowych firmy Nokia, część 2,
EP 2003/7 str. 80 Sterowanie graficznych wyświetlaczy z telefonów komórkowych firmy Nokia, część 3,
EP 2008/2 str. 89 Kilka sposobów na wyświetlacz z Nokii 3310,
EP 2009/12 str. 84 Wyświetlacz graficzny do Nokii3310,
W wymienionych artykułach można odnaleźć alternatywne konfiguracje instrukcji inicjujących, które można testować w razie problemów. Tutaj jeszcze ciekawostki o sterownikach z wyświetlaczy znalezione na tej witrynie:
model name (of display) | type | nokia cellphones | |
LPH 7366 | 2 | Nokia 5110, 5120, 5130, 5160, 6110, 6150 | |
LPH 7677 | 1 | Nokia 3210 | |
LPH 7779 | 1 | Nokia 3310, 3315, 3330, 3350, 3410 | |
LPH 7690 | 1 | Nokia 6210 |
(digits in brackets show the marks in the following pictures)
- type 1:
- the display is connected to the circuit board [2] using metallic pins [1]
- leds are soldered on the other side of the circuit board [3]
- they enlight the display through holes in the circuit board [3]
- the display has 8 pins
- pin #1 is rightmost (rear view of display, connectors at the bottom line)
- tiny cables could be soldered directly onto the metallic pins
- recommentation: design a circuit board for leds and display connector on your own because the circuit board can hardly be recycled
- update: some displays use a different method to connect the display module to the circuit board: contact pads and a separate „transmitter”. it should be possible to solder wires directly onto the contact pads or to use an elastomer
- type 2:
- the display is connected to the circuit board [2] using an elastomer (’lcd-connector’ or 'rubber pad with conducting joints’) [1]
- leds are soldered on the same side of the circuit board [3] underneath the position of the display
- on the other side of the circuit board there are no electronic parts
- the display itself is „clipped” [4] onto the circuit board
- the display has 9 pins (additional possibility to connect an external oscillator)
- pin #1 is rightmost (rear view of display, elastomer at the bottom line)
- the circuit board of the cellphone can be 'recycled’ by simply cutting out the interesting part (see picture below)
Od teraz wszyscy razem zbieramy stare telefony będą super dawcami ;-D Coś mi się wydaje, że te wszystkie wyświetlacze będą długo nieśmiertelne. Wyświetlacz doczekał się nawet wersji modułu z PCB dla „majsterkowiczów”.Z ostatniej chwili, – prezentowany program bezproblemowo obsługuje wyświetlacz gdy µC taktowany jest wewnętrznym oscylatorem 8MHz – bez żadnych dodatkowych wybiegów. Przy takim taktowaniu częstotliwość na magistrali SCLK waha się w okolicach 100kHz.
okazało się że nie taki diabeł straszny jak go malują ;-D
A.D. 2014-05-06 z ostatniej chwili 😉 gdy wyświetlacz zasilam z portu μC wszystko działa gdy zasilanie główne wynosi 5V. I to bez jakichkolwiek dodatkowych elementów 😉
A.D. 2014-06-25 Ponieważ jakiś czas temu dostałem zapytanie – a szkoda, że nie przez formularz w artykule… o treści:
Pytanie odnośnie sterowania wyświetlacza, jak w Bascom wysłać na ten wyświetlacz zmienną ?
Więc odpowiem. Domyślam się że chodzi o typ zmiennej numerycznej. Ja realizuję taką funkcjonalność z użyciem funkcji STR.
1 2 3 4 |
Dim Napis As String * 14 Dim Liczba As Byte Napis = Str(Liczba) |
Służy ona do „konwersji” dowolnego typu liczby na ciąg znaków. Co z tego wynika? Może okazać się że nie potrzebnie nasz kod puchnie. Standardowa biblioteka zapewni konwersję przez tą funkcję dla typów byte, integer, word i longs. W przypadku kiedy nie potrzebujemy konwertować typów zmiennoprzecinkowych można zastosować alternatywną bibliotekę o nazwie mcsbyteint.lbx. Gdy w użyciu są tylko zmienne z zakresu byte wtedy warto zainicjować bibliotekę mcsbyte.lbx. I mamy piękny sposób na optymalizację kodu ;-D Dla przypomnienia biblioteki dołącza się następująco:
1 |
$LIB "mcsbyteint.lbx" |
A.D. 2015-01-10 buszując po forum MCS Electronics natrafiłem na temat gdzie wyczytałem, iż powstała biblioteka do obsługi tego typu wyświetlaczy. Nosi nazwę glcd-Nokia3310.lib. W wątku jest też mowa o jeszcze innych wyświetlaczach – polecam zaglądać. ;-D
Nota katalogowa sterownika wyświetlacza
PCD8544.pdf (2069 pobrań)
Nota katalogowa sterownika wyświetlacza
PCF8812U.pdf (2905 pobrań)
jak to podłączyć? Bo nie wiem, nigdzie nie ma jak podłączyć ten wyświetlacz…
Witam.
Może tak jak piszesz „nigdzie nie ma jak podłączyć …”
Ale w końcu trafiłeś na tą zieloną witrynę, a tutaj to nie nigdzie.
Mam uzasadnione wątpliwości czy czytałeś tą prezentację.
I z tego powodu jest mi niezmiernie przykro …