Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Kontroler I2C wyświetlacza na sterowniku T6963C

piotrva 27 Maj 2010 11:25 12634 22
  • Kontroler I2C wyświetlacza na sterowniku T6963C
    Witam serdecznie!
    Projekt ten jest moim pierwszym projektem który był tworzony nie tylko z chęci nauczenia się czegoś, czy wykorzystania jakichś elementów, lecz ze względów czysto praktycznych i użytkowych.
    Cele:
    Ograniczenie ilości pinów wykorzystywanych przez wyświetlacz graficzny LCD
    Opis układu:
    Sercem układu jest zaprogramowany procesor AT90S2313. Wgrane do niego oprogramowanie pozwala na przesyłanie do niego danych magistralą I2C. Odpowiednie komendy umożliwiają sterowanie wyświetlaczem graficznym opartym na sterowniku T6963C.
    Dostępne komendy to:
    Czyszczenie wyświetlacza
    Czyszczenie strony tekstowej wyświetlacza
    Czyszczenie strony graficznej wyświetlacza
    Ustawianie/kasowanie piksela
    Rysowanie/mazanie linii
    Rysowanie/mazanie okręgu
    Umieszczenie kursora w podanym wierszu i kolumnie
    Wyświetlenie tekstu

    Oraz komenda systemowa pozwalająca na zmianę adresu tego układu.
    Wykonanie i trudności:
    Oprogramowanie napisałem w języku BASCOM z wykorzystaniem biblioteki 12c_slave.
    Pierwszą trudnością była niewystarczająca liczba wyprowadzeń aktywnych procesora. Po podpięciu wszystkich linii sterujących wyświetlacza pozostawało tylko jedno wolne wyprowadzenie (magistrala I2C potrzebuje 2). problem rozwiązałem ustawiając w programie pin sterowania trybem czcionki (FS) na wewnętrzne wyprowadzenie komparatora analogowo-cyfrowego, a fizycznie zwierając pin FS wyświetlacza do stanu wysokiego (wybór trybu czcionki 6*8).
    Kolejną trudnością był czas potrzebny na zapisanie w odpowiedniej zmiennej wartości odebranej z magistrali. stąd w programie nadrzędnym musiałem wprowadzić opóźnienia między wysyłaniem kolejnych bajtów sygnału (na razie czas ten wynosi 1ms, ale będę starał się zejść z nim niżej bez utraty danych)
    Jeszce jedną trudność stanowił czas konieczny na obliczenia pozycji pikseli (na przykład dla okręgu) co powodowało przesyłanie komendy podczas rysowania koła i utratę danych). Dlatego wprowadziłem bajt zajętości (odczyt czegokolwiek z kości powoduje właśnie odczyt tego bajtu). Podczas obliczeń przyjmuje on wartość 1, co umożliwia sprawdzenie przez urządzenie nadrzędne, kiedy można posyłać następne dane (nie można odczytywania przeprowadzać jednak zbyt często, gdyż wtedy także następuje krótkie przerwanie rysowania. W swoim oprogramowaniu nadrzędnym ustanawiam częstotliwość sprawdzania zajętości także co 1ms.

    Wadą jest konieczność zapewnienia procesorowi zewnętrznego oscylatora, ale użyłem tego mikrokontrolera, ponieważ taki miałem pod ręką. Jeśli kotś by chciał to na PW mogę przesłać kompilacje pod inne procesory i inne wyświetlacze (o innych rozdzielczościach)

    Resztę danych zamieszam w krótkiej specyfikacji, załączam kody źródłowe i plik wsadowy .hex do AT90S2313 (skompilowany dla wyświetlacza 240*64)

    Proszę o komentarze i wszelką krytykę, oprócz tej, ze BASCOM to nieprofesjonalne oprogramowanie (bo mam tego świadomość, acz mimo wszystko programuje mi się w nim niezwykle przyjemnie) ;-)

    Kontroler I2C wyświetlacza na sterowniku T6963C Kontroler I2C wyświetlacza na sterowniku T6963C


    Fajne!
  • #2 27 Maj 2010 12:01
    utak3r
    Poziom 25  

    Taka mała propozycja, odnośnie tych wszystkich problemów z czasem wykonania komend: zrób sobie bufor, który będzie odbierał dane z magistrali. Jedne komendy wykonują się krócej, inne dłużej, te szybsze będą nadganiać stracony czas. Bit zajętości ustawiaj dopiero wtedy, gdy masz już pełny bufor.

    Też ostatnio robiłem sterownik wyświetlacza (ale tekstowego) - niektóre komendy wykonywały się nawet po kilka milisekund, inne kilka mikrosekund. Wprowadzenie bufora cyklicznego rozwiązało od ręki wszystkie problemy :)

  • #4 27 Maj 2010 14:07
    utak3r
    Poziom 25  

    No niestety - nie znam Bascoma.

  • #6 27 Maj 2010 14:40
    utak3r
    Poziom 25  

    Sądzę, że by się dało - pytanie tylko o prędkość. Wypełniać bufor musisz w przerwaniu - i to w jak najkrótszym czasie. Osobiście, podczas swojej implementacji, sam proces odkładania odczytanej wartości z magistrali do buforu zrobiłem jako wstawka asemblerowa do programu w C.

  • #7 27 Maj 2010 14:41
    hessuss
    Poziom 13  

    ale czy bufor to kwestja języka? wydaje mi się, że tu idzie o zasadę. Ja sobie zrobiłem bufor do rs232 w formie tabli, przerwanie dokłada na stosik znaki a procedurka zdejmuje , wystarczyła 8 bajtowa tabelka żeby nawet pisanie na 4 ręce nie powodowało przepełnienia. Zrób tak samo. Niech przerwanie odkłada ci na stos komendy a procedura niech zdejmuje w/g zasady FIFO , dobierz doświadczalnie wielkość buforka i problem z głowy :)

  • #8 27 Maj 2010 14:43
    miszcz310
    Poziom 19  

    No chyba nie koniecznie. Jakbyś utworzył tablicę (tylko że 2313 ma mało ramu) i zamiast od razu na wyświetlacz wysyłał komendy to wpisywał w tą tablicę i zwiększał indeks. jak indeks równy ileś tam to puch , przerwania idą spać zawartość bufora na wyświetlacz. czyść bufor i przerwania odblokować i jazda dalej z danymi i tak w pętli. Można jeszcze by zrobić że jak nic nie przychodzi po jakimś czasie to bufor się opróżnia, żeby nie było tak że całe ramki trzeba za każdym razem wysyłać. Pytanie tylko czy to we Flash wejdzie, ale myślę że jak pokombinujesz może się udać.

    Ehhh.. wyprzedzili mnie :P

  • #9 27 Maj 2010 15:43
    utak3r
    Poziom 25  

    miszcz310 napisał:
    czyść bufor i przerwania odblokować i jazda dalej z danymi i tak w pętli. Można jeszcze by zrobić że jak nic nie przychodzi po jakimś czasie to bufor się opróżnia, żeby nie było tak że całe ramki trzeba za każdym razem wysyłać.


    Nie... niepotrzebne marnowanie cykli - a przecież o prędkość nam tu chodzi, nie? :)
    Bufor cykliczny. Działa to tak:
    - definiujesz bufor i wskaźniki: na jego początek, koniec i aktualny. Do kompletu wskaźnik odczytu.
    - ZAPIS: przychodzi znak/komenda, zapisujesz to pod wskaźnikiem "aktualny". Zwiększasz aktualny o 1 i sprawdzasz, czy aktualny == koniec, jeśli tak, to aktualny = poczatek.
    - ODCZYT: robimy dwie procedury: sprawdzania, czy czeka w buforze jakiś znak - porównanie wskaźników odczytu i zapisu. Jeśli równe, nic nie ma dla nas. Druga: faktycznego odczytu. Odczytujesz spod wskaźnika "odczyt", zwiększasz o jeden i porównujesz z końcem. Jeśli równe, przesuwasz na początek.

    koniec :)

  • #10 27 Maj 2010 21:43
    Nerwus
    Poziom 18  

    utak3r napisał:
    miszcz310 napisał:
    czyść bufor i przerwania odblokować i jazda dalej z danymi i tak w pętli. Można jeszcze by zrobić że jak nic nie przychodzi po jakimś czasie to bufor się opróżnia, żeby nie było tak że całe ramki trzeba za każdym razem wysyłać.


    Nie... niepotrzebne marnowanie cykli - a przecież o prędkość nam tu chodzi, nie? :)
    Bufor cykliczny. Działa to tak:
    - definiujesz bufor i wskaźniki: na jego początek, koniec i aktualny. Do kompletu wskaźnik odczytu.
    - ZAPIS: przychodzi znak/komenda, zapisujesz to pod wskaźnikiem "aktualny". Zwiększasz aktualny o 1 i sprawdzasz, czy aktualny == koniec, jeśli tak, to aktualny = poczatek.
    - ODCZYT: robimy dwie procedury: sprawdzania, czy czeka w buforze jakiś znak - porównanie wskaźników odczytu i zapisu. Jeśli równe, nic nie ma dla nas. Druga: faktycznego odczytu. Odczytujesz spod wskaźnika "odczyt", zwiększasz o jeden i porównujesz z końcem. Jeśli równe, przesuwasz na początek.

    koniec :)


    Wszystko ładnie i pięknie ale co się stanie jak przepełnisz bufor? To nie jest sprzęt ratujący życie ale powinno się pisać bezpieczny kod.

  • #11 27 Maj 2010 22:15
    utak3r
    Poziom 25  

    Chyba nie przeczytałeś tego, co napisałem. Polecam więc jednak lekturę.

  • #13 28 Maj 2010 21:59
    gbr3
    Poziom 15  

    Czy transmisja i2c bardzo spowalnia obsługę kontrolera? Robiłem coś takiego dla SED1330 i nie było za ciekawie :/

  • #14 29 Maj 2010 01:28
    poorchava
    Poziom 18  

    Możesz też (zakładając, że tylko ty tego używasz i nie będzie problemów ze standardami) dodać dodatkową linię danych oznaczającą BUSY. Takie (albo podobne) rozwiązanie zastosowano w samochodach GM przed wprowadzeniem CAN do komunikacji pomiędzy wyświetlaczem pokładowym a komputerem/radiem/nawigacją itd. Masz wtedy 4 przewody: gnd, sda, scl i busy_ready.

  • #15 29 Maj 2010 10:06
    tmf
    Moderator Mikrokontrolery Projektowanie

    A po co miałaby być ta dodatkowa linia? Przecież obsługę busy można zrobić w pełni zgodnie ze standardem I2C.

  • #16 29 Maj 2010 11:03
    piotrva
    Moderator na urlopie...

    co do spowalniania transmisji, to nie są to zbyt duże opóźnienia, mam plan (ale czasu na razie nie), aby dodać tak jak radzili koledzy kolejkę i w niej zapisywać komendy - wtedy transmisja będzie jeszcze szybsza. Widoczne opóźnienia zauważyłem jedynie przy używaniu ustawiania pojedynczych pikseli. Jak będę mieć nowszą wersję oprogramowania to będzie zapewne działać lepiej.
    Co do linii BUSY to jakbyś przeczytał pierwszy post to zobaczyłbyś, że nie ma już wolnych pinów, na razie jest zajętość na I2C przechowywana.
    Jak będzie wersja 2.0 to dam znać ;-)

  • #17 31 Maj 2010 11:32
    22053
    Użytkownik usunął konto  
  • #19 31 Maj 2010 16:19
    utak3r
    Poziom 25  

    Bardzo "trochę". Widzisz - język taki czy siaki to najmniejszy problem (stąd też nie rozumiem tych, którzy trzymają się Bascoma i jak ognia boją się pójść dalej). Języka w podstawowym stopniu nauczysz się w kilka dni. Schody zaczynają się przy konkretnym zastosowaniu - a przy C zazwyczaj (zależy to od kompilatora tutaj) masz dostęp do uC na niższym poziomie, niż przez Bascoma, bardziej uwagę zwracasz na rejestry konfiguracyjne itp.

    Ogólnie... znajomość C z peceta niewiele wnosi do tematu C na uC - tak imho :)

  • #21 31 Maj 2010 16:47
    utak3r
    Poziom 25  

    Zgadza się, ale jak napisałem - nauka samego języka to dosłownie chwila moment...

  • #22 31 Maj 2010 16:47
    22053
    Użytkownik usunął konto  
  • #23 31 Maj 2010 16:58
    utak3r
    Poziom 25  

    R-MIK napisał:
    Reasumując:
    program obsługi "żelazka":
    - na PC startuje "tylko" kiljka minut, czasem działa w czasie rzeczywistym
    - na uC staruje 4ms, czas rzeczywisty nie jest problemem.


    A z czego to wynika? (tak jak i cała różnica między tymi dwoma docelowymi platformami) Otóż z tego, że na PC piszemy program, który działa pod kontrolą takiego lub innego systemu operacyjnego, natomiast dla uC (pomijam przypadki typu ARM9 i linuksa czy WinCE na nich) piszesz bezpośrednio pod procek, jego rejestry i jego asembler, przełączalne rejestrami funkcje pinów itp.itd. Stąd w zasadzie wynika cała różnica. Dodając do tego dostępne zasoby pamięci i MIPSów, o czym przedmówca wspominał - mamy obraz całości :)