logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[bascom]Zmiana definiowalnych znaków w LCD a VFD

manekinen 13 Gru 2009 10:04 3515 6
  • #1 7381745
    manekinen
    Poziom 29  
    Hej,

    W programie podczas pracy musze zmieniać na żądanie definiowalne znaki wyświetlacza. Wszystkie LCD jakie mam nie sprawiają problemów, problem zaczyna się gdy chcę zmienić znaki w wyświetlaczu VFD. Po wysłaniu wszystkich i wysłaniu polecenia CLS wyświetlacz nieraz zmieni znaki, nieraz pokaże kilka krzaków i wróci do poprzednich znaków, a nieraz wykrzaczy się program. Do komunikacji używam linii RW i biblioteki lcd4busy.

    Próbowałem dodawać wszelakie opóźnienia, na nowo inicjować, nawet wyłączać i włączać na czas zmiany znaków (komendy 08H i 0FH) i żadnych zmian... z resztą jest o wiele szybszy niż lcd więc to chyba nie kwestia zbyt szybkiego wysyłania. Działa prawidłowo z innymi znakami jeśli wrzuce je na początku programu. Ponadto wyświetlacz ma problem z ustawieniem znaku w komórce zero pamięci ram, ciągle jest "_". Wyświetlacz to noritake CU20029ECPB-W1J. Producent nie udostępnia nawet pełnej noty od niego. Może ktoś walczył z podobnymi wyświetlaczami? Po za regulacją jasności nie posiada żadnych dodatkowych komend.

    Fragment kodu
    
    If Tryb = 0 Then
       Incr Efekt
       If Efekt = 5 Then Efekt = 0
       Gosub Lcdchr
       'Efekt_eepr = Efekt
       Waitms 10
    End If
    
    [...]
    
    Lcdchr:
    
    Select Case Efekt
    
       Case 0:
       Deflcdchar 0 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 31
       Deflcdchar 1 , 32 , 32 , 32 , 32 , 32 , 32 , 31 , 31
       Deflcdchar 2 , 32 , 32 , 32 , 32 , 32 , 31 , 31 , 31
       Deflcdchar 3 , 32 , 32 , 32 , 32 , 31 , 31 , 31 , 31
       Deflcdchar 4 , 32 , 32 , 32 , 31 , 31 , 31 , 31 , 31
       Deflcdchar 5 , 32 , 32 , 31 , 31 , 31 , 31 , 31 , 31
       Deflcdchar 6 , 32 , 31 , 31 , 31 , 31 , 31 , 31 , 31
       Deflcdchar 7 , 31 , 31 , 31 , 31 , 31 , 31 , 31 , 31
    
       Case 1 :
       Deflcdchar 0 , 32 , 32 , 32 , 32 , 32 , 32 , 32 , 27
       Deflcdchar 1 , 32 , 32 , 32 , 32 , 32 , 32 , 27 , 27
       Deflcdchar 2 , 32 , 32 , 32 , 32 , 32 , 27 , 27 , 27
       Deflcdchar 3 , 32 , 32 , 32 , 32 , 27 , 27 , 27 , 27
       Deflcdchar 4 , 32 , 32 , 32 , 27 , 27 , 27 , 27 , 27
       Deflcdchar 5 , 32 , 32 , 27 , 27 , 27 , 27 , 27 , 27
       Deflcdchar 6 , 32 , 27 , 27 , 27 , 27 , 27 , 27 , 27
       Deflcdchar 7 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 27
    
    [...itd...]
    
    End Select
    
    Return
    




    DODANO



    Dodałem wszystko co mogłem z dużym zapasem czasowym, wyłaczam co niepotrzebne, teraz w ten sposób przygotowuje wyświetlacz:
    
    Lcdchr:
    Stop Watchdog
    Stop Timer1
    Disable Interrupts
    Gosub D_off
    Waitms 100
    Gosub D_on
    Waitms 100
    Initlcd
    Waitms 10
    Initlcd
    Cls
    Cursor Off
    Waitms 10
    
    Select Case Efekt
    
    [...]
    
    End Select
    Waitms 100
    Initlcd
    Waitms 100
    Initlcd
    Cursor Off
    Waitms 100
    Start Watchdog
    Start Timer1
    Enable Interrupts
    
    Return
    

    Później włączam wszystko co powyłączałem. Jest już stabilniejszy, mogę zmienić znaki kilkukrotnie ale po tych kilku razach to program się wysypuje a nie wyświetlacz - bo wystarczy zresetować procka i rusza. Opóźnienie po włączenie lcd komendą mogę dać nawet 1s i nic to nie zmienia. Już nie mam pojęcia jak mu jeszcze moge życie ułatwić :( Całość chodzi na 16MHz ale nie ma to znaczenia skoro i tak korzystam z linii RW, z resztą podczas normalnego wyświetlania nie ma najmniejszego błędu a sam wyświetlacz jest bardzo szybki.
  • Pomocny post
    #2 7382289
    mirekk36
    Poziom 42  
    manekinen napisał:
    ... z resztą jest o wiele szybszy niż lcd więc to chyba nie kwestia zbyt szybkiego wysyłania. .


    Nie jestem pewien czy to będzie to - ale z tym zdaniem, że jest o wiele szybszy to bym się nie zgodził tak do końca bo wprawdzie minimalny czas (E)nable Pulse Width 450ns jest podobny jak w innych typowych wyświetlaczach LCD to już (E)nable Cycle Time 1000ns jest aż ze DWA razy dłuższy niż w typowych wyświetlaczach LCD. Np w moim PLED czas (E)nable Cycle Time to 500ns

    i tak się zastanawiam czy z tego powodu właśnie nie następują pewne komplikacje u ciebie pomimo jak mówisz zastosowania R/W . To jednak ma małe znaczenie jeśli biblioteka Bascomowa ten czas omawiany powyżej ustala nawet z zapasem na poziomie być może 700ns

    Może spróbuj potaktować procka dużo niższą częstotliwością np 8MHz albo 4MHz z wewn oscyal. Wtedy rozkazy asemblerowe NOP używane często w takich przypadkach do opóźnień już znacznie wydłużą wszystkie czasy dostępu w tym te omawiane powyżej i wtedy może będzie ci dobrze to działać. W zasadzie jeśli ten twój program ma robić tylko tak niewiele rzeczy jak tu zaprezentowałeś i nie wykorzystuje jakoś specjalnie przerwań z większą ilością w nich kodu - to spokojnie można taktować procek za pomocą 8MHz bez uszczerbku dla widocznych efektów czy animacji, które chcesz uzyskać na tego typu wyświetlaczach obojętnie czy VFD, czy LCD czy PLED. No chyba, że jak mówiłem jednak masz większy program , sporo przerwań itp
  • #3 7382418
    manekinen
    Poziom 29  
    Chodzi o to że program jest napięty czasowo jak... barania torba. Musi być 16MHz, a pewnie i tak go pewnie będe chciał przetaktować na 20...

    Wcześniej sprawdzałem z 8MHz i to samo, więc niżej nie jechałem, ale za Twoją namową sprawdziłem teraz na 4MHz - i jest dobrze! Ja jakoś zawsze myślałem że bascom sobie sam przelicza czas impulsu Enable według podanego $crystal... wydaje się być to logiczne.

    Pisząc że jest szybszy miałem na myśli to że wizualnie chodzi gdzieś 2-3 razy szybciej od LCD które mam... z resztą pokaże...





    Jak widać nawet po ponownym włączeniu zasilania niezbyt chętnie chce startować...

    Ale czas trwania impulsu Enable u mnie faktycznie wynosi 1000ns. Hmm więc nie pozostaje nic innego jak grzebanie w bibliotece i wydłużenie tego czasu?
  • #4 7382650
    mirekk36
    Poziom 42  
    Ciekawy jestem co tam za projekcik znowu płodzisz ;) ale zapewne wkrótce się dowiemy - efekty fajne ;)

    A odnośnie grzebania w bibliotece - to spokojnie można - masz jej pełny kod asemblerowy przecież dostępny. Z tego co pamiętam to chyba nie będzie trudne pójście na początku po najmniejszej linii oporu i dodaniu kilku NOP'ów tu i tam. Bo jak sobie zajrzysz to zobaczysz, że Bascom tu nie przelicza tych opóźnień dla sygnałów E czy RS czy dla odczytu flagi zajętości. Wstawione jest tam po kilka rozkazów NOP (chyba po 2 z tego co pamiętam) i na prawdę to wystarcza dla ogromnej większości typowych wyświetlaczy LCD nawet przy taktowaniu 16MHz. Ale sam widzisz, że ten twój nie jest typowy .

    Sam zresztą kiedyś dawno dawno temu przerobiłem sobie tą bibliotekę, hmmm nie tfu w zadadzie na jej podstawie napisałem całkiem nową, która rozszerzała dla mnie wtedy jedną bardzo ważną funkcjonalność. Bo jak widzisz aby jej użyć wszystkie linie DB7..4 muszą być podłączone do pinów tego samego portu procka. A ja potrzebowałem podpinać sobie każdy sygnał do najbardziej dowolnego pinu i portu procka w tym także RS, RW oraz E ...... i ładnie mi to wyszło i wszystko pięknie i bez żadnych spowolnień działało..... no ale wiadomo - jak to pisanie w asemblerze - jest z tym co nieco roboty, testowania, zabawy itp. Dlatego dzisiaj wszystko już zresztą od dawna śmigam w C.
  • #5 7383160
    manekinen
    Poziom 29  
    Próbowałem wstawiać wszelakie opóźnienia w bilbiotece, niestety nie przyniosło to żadnego efektu, nawet dla 8MHz...

    przykładowo
    
    Ldi R30, 28
    Ldi R31, 78
    Rcall _lcd_delay                    ; 20 ms delay at 4 MHz
    

    Rejestrów nie ruszałem, ale dodałem "*BASIC: waitms 5" nie wiem czy dobrze, ale błędów nie wywalał.

    Tam wszędzie gdzie przed końcem Enable były po 2 NOP'y to dałem nawet po 10. Kod się rozrósł, ale poprawy żadnej :(

    mirekk36 napisał:
    Bo jak widzisz aby jej użyć wszystkie linie DB7..4 muszą być podłączone do pinów tego samego portu procka. A ja potrzebowałem podpinać sobie każdy sygnał do najbardziej dowolnego pinu i portu procka w tym także RS, RW oraz E


    https://www.elektroda.pl/rtvforum/topic842746.html :)
    Napisałem potem na forum mcs i za trzy dni była gotowa biblioteka :)
    http://www.mcselec.com/index2.php?option=com_...d=59&page=viewtopic&t=4941&highlight=lcd4busy

    mirekk36 napisał:
    Ciekawy jestem co tam za projekcik znowu płodzisz

    Nic nowego, to jest analizator widma na avr ( http://diy.elektroda.eu/analizator-widma-akustycznego/ ), robie drugą wersję, rozbudowaną o dodatkowe opcje itp. Miałem dzisiaj opublikować ale okazało się że z vfd są takie jaja więc...
  • Pomocny post
    #6 7385032
    maniek1818
    Poziom 22  
    Ldi R30, 28 
    Ldi R31, 78 
    Rcall _lcd_delay                    ; 20 ms delay at 4 MHz


    Witam, przedstawiony kod asemblerowy jest niezmiernie prosty w edytowaniu i zmienianiu parametrów instrukcji.
    Ldi - jak każdy wie, to ładowanie odpowiedniej wartości do rejestru
    Rcall - wywołanie programu.

    
    _lcd_delay:
       Sbiw R30,1                           ;2 cycles   
       Brne _lcd_delay                      ;2 cycles
    Ret
    

    Sbiw - instrukcja która od pary rejestrów odejmuje stałą wartość K, w tym przypadku 1 i zapisuje wynik jest umieszczany w tej samej parze rejestrów, gdy wynik będzie równy 0 ustawia flagę Z.
    Brne - wywołuje skok do początku pętli gdy flaga Z=0.
    JAK ZMIENIĆ CZAS opiszę przykład dla ~ 20ms = 20 000us
    1. Odejmujemy 4, poniewarz samo wykonanie instrukcji Rcall zajmuje 4 cykle
    2. Konwertujemy 19 996 do HEX => 1001110 00011100
    3. Konwertujemy spowrotem do DEC => R31, 78 i R32, 28
    Pozdrawiam i życzę miłego dalszego owocnego klepania w Bascomie.
  • #7 7385148
    manekinen
    Poziom 29  
    Dzięki wielkie za ten opis! :)

    A więc w lcd4busy.lib, przy inicjacji, początkowe 20ms
    
    Ldi R30, 28
    Ldi R31, 78
    Rcall _lcd_delay                    ; 20 ms delay at 4 MHz
    

    zwiększyłem na 40ms, z uwzględnieniem -4ms
    
    Ldi R30, 60
    Ldi R31, 156
    Rcall _lcd_delay 
    

    A kolejne 5ms
    
    Ldi R30, 132
    Ldi R31, 19
    rcall _lcd_delay                    ; 5 mS delay at 4 MHz
    

    na 20ms
    
    Ldi R30, 28
    Ldi R31, 78
    rcall _lcd_delay
    


    Niestety, żadnej poprawy. Dalszą część wykluczam, bo po inicjacji program korzysta z flagi busy więc tam już chyba problemu nie ma z czasami. Mimo tego spróbuje jeszcze powrzucać jakieś większe opóźnienia w każdy sygnał enable...

    Dodano po 2 [minuty]:

    A może problemem jest wysyłanie znaków do wyświetlacza? Znak w komórce zero nie zapisuje się, może ta komórka jest przeznaczona na coś innego i dla tego takie zwiechy... w skróconej nocie nie jest opisane które komórki to własne znaki, w tablicy tylko pierwsze 16 jest pustych... może trzeba definiować jako 8-15?


    DODANO


    A więc zapis do komórek 8-15 nic nie daje, nie pomaga też nie-zapisywanie do komórki zerowej. Potestowałem dłużej i się okazuje że jeśli nie wykonuje żadnego wysyłania znaków, to reszta podprogramu (czyli wyłącz, włącz, init, init, itp) nie sprawia najmniejszego problemu, można pstrykać ile wlezie bez najmniejszego błędu. Ale wystarczy że wyśle choć jeden znak i wszystko staje. Tzn jak ma juz się zawiesić to od razu przy pierwszym deflcdchar. Reset procka stawia na nogi całość, podejrzewam że program wysyła znak, wyświetlacz ma problem z odebraniem i nie zwraca flagi busy na którą program bezskutecznie oczekuje. Wygląda na to że trzeba by było dopisać jakiś timeout dla flagi busy i po prostu wysyłać lcd init jeśli jej nie dostaniemy po jakimś czasie :( Ewidentnie wina leży po stronie wyświetlacza, bo opóźnienia w bibliotece porobiłem już tak duże że już widać że wolniej pracuje a mimo tego źle odbiera te znaki. Nic tylko podziękować producentowi że nie udostępnia pełnego datasheeta...


    DODANO

    OK ostatni apdejt w tym pięknym monologu. Znalazłem datasheeta od tego ustrojstwa, sprawa własnego znaku w komórce zerowej się wyjaśniła - działa - jednak ja tam wpisywałem znak który posiada tylko trzy kropki w najniższej linii pola - a ten wyświetlacz może mieć tam tylko albo puste miejsce albo linię czyli kursor. Natomiast sprawy zawieszania się nie wyjaśniłem, więc zrobiłem to po chamsku - inkrementuje zmienną, wpisuje ją do eeprom, odpalam watchdoga, ide w peocedurę do zmiany znaków. Jak się wysypie to program startuje od nowa i pierwsze co robi to zmienia znaki, w tym przypadku jest to nie szkodliwe jak i nie zauważalne :)
REKLAMA