Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Wyświetlacz LCD do dowolnego układu

andrzejlisek 21 Aug 2016 07:41 12180 9
phoenixcontact
  • Wyświetlacz LCD do dowolnego układu
    Przedstawiam konstrukcję wykonaną 2 lata temu, jaka jest graficzny wyświetlacz LCD przygotowany do współpracy z DSM-51, jednakże może współpracować z dowolnym innym układem mikroprocesorowym, który umożliwia szeregowe wysyłanie danych. W układzie sterującym jest zastosowany mikrokontroler ATMega32. Ponieważ był problem związany z niedoborem pamięci, przed opisem konstrukcji na forum, miałem zamiar wymienić kontroler na ATMega64 lub nawet ATMega128, ale zawsze albo o tym zapominałem, albo w sklepie nie było i tak wyświetlacz przeleżał, jednakże działa on poprawnie.

    Schemat rysowałem kiedyś ręcznie w celu zaplanowania rozmieszczenia elementów na płytce uniwersalnej, ale nie naniosłem wartości tych elementów, co sprawia, że nie jestem w stanie podać wartości kondensatorów i potencjometrów, jednakże stosowałem typowe elementy zgodnie z zaleceniami w notach katalogowych. Cztery kondensatory wokół MAX232 mają napis "104KSC", a dwa kondensatory podłączone to ATMegi mają napis "22". Potencjometr sterujący kontrastem ma napis "223" lub "E22", w zależności, jak czytać. Opornik ma kreski w kolejności złotą, czarną i brązową, jego rezystancja to chyba 10K lub 100K, podłączony między 5V a pinem Reset, tak, jak się robi w każdym AVR.

    Rezonator kwarcowy ma częstotliwość 7,3728, wybór częstotliwości był podyktowany możliwością uzyskania standardowych prędkości transmisji danych. Układ MAX232 jest zastosowany po to, żeby można było wykorzystać nieużywany port RS232 w DSM-51 sterowany programowo z mikrokontrolera 8052. Aby umożliwić podłączenie wyświetlacza, do pinu nr 9 w DSM-51 dolutowałem przewód umożliwiający wyprowadzenie napięcia zasilania 5V na RS232. Decydując się na to ulepszenie byłem przekonany, że na 99.9% nie będę nigdy chciał podłączać jakiegokolwiek urządzenia, w którym będzie przeszkadzać obecność napięcia 5V na pinie 9 i przez ostatnie 2 lata rzeczywiście nie podłączałem do DSM-51 do tego porty żadnego innego urządzenia oprócz opisywanego wyświetlacza. Wyświetlacz może tez współpracować z dowolnym urządzeniem operującym na poziomach TTL (0V i 5V). W tym celu należy wyjąć MAX 232 i odpowiednio połączyć dwie pary styków krótkimi drutami w celu uzyskania bezpośredniego połączenia mikrokontrolera z portem.

    Schemat w przybliżeniu oddaje rzeczywiste rozmieszczenie elementów układu.
    Wyświetlacz LCD do dowolnego układu

    Założenie jest takie, że jest pewien prosty protokół komunikacyjny od układu do wyświetlacza zawierający rozkazy do wykonania przez wyświetlacz. Rozkazy składając się z jednego lub dwóch bajtów. W przeciwna stronę nie są wysyłane żadne dane, tylko normalnie jest poziom wysoki, a jak bufor wyświetlacza jest pełny, to poziom zmienia się na niski, co informuje urządzenie wysyłające, że bufor jest pełny i że nie powinno wysyłać kolejnych danych do czasu, aż nie nastąpi zmiana stanu na wysoki. Bufor jest w stanie pomieścić 256 bajtów, a przepełnienie bufora jest sygnalizowane już przy istnieniu w nim 128 bajtów. Takie rozwiązanie sprawia, że nie ma ryzyka gubienia rozkazów i nie ma potrzeby sprawdzania sygnału zajętości przed każdym rozkazem. Wystarczy raz na kilkadziesiąt rozkazów.

    W tym przypadku został użyty wyświetlacz HY 19264E 201 ( http://www.artronic.com.pl/o_produkcie.php?id=590 ), jednak program można przerobić pod dowolny inny wyświetlacz graficzny. Można wyświetlać znaki tekstowo (8 linii po 32 znaki każda) oraz grafikę (192x64 pikseli). Rysowanie i pisanie tekstu działa na podobnej zasadzie, jak tryby graficzne w Microsoft QuickBasic. Zestaw znaków jest taki, jaki jest standardowy w DOS, a konkretnie w Atari Portfolio, bo tam też jest czcionka 6x8 pikseli.

    Podczas zapisu rozkazów, rysuje się po 8 pikseli naraz, więc żeby zmienić jeden piksel, należy odczytać pozostałe piksele zapisywane tym samym bajtem, zmienić jeden pit i ponownie ten bajt zapisać. Podczas pisania programu planowałem, że zawartość wyświetlacza będzie pamiętana w pamięci RAM w celu przyspieszenia obsługi wyświetlacza, że przy zapisie o wyświetlacza nie będzie potrzeby odczytu stanu zapisywanych bajtów z pamięci wyświetlacza. Jednak, jeżeli do tego dołączyłem możliwość zamalowywania kształtów przy buforze sensownej wielkości, to zdarzały się błędy, szczególnie przy wypełnianiu zamkniętych obszarów. Wielkość bufora do wypełniania obszarów zamkniętych determinuje maksymalną wielkość wypełnianego obszaru. Później przerobiłem program tak, że stan piksela jest odczytywany z wyświetlacza, więc program rysuje wolniej, ale nie ma już tych błędów związanych z wypełnieniem.

    Do obsługi wyświetlacza przewidziałem następujące rozkazy:
    01YYYYYY XXXXXXXX - Ustaw współrzędne punktu graficznego 1
    10YYYYYY XXXXXXXX - Ustaw współrzędne punktu graficznego 2
    11___YYY ___XXXXX - Ustaw współrzędne kursora tekstowego
    
    00000000          - Resetuj stan, ustawienia i wyczyść ekran
    00000001          - Wyczyść ekran
    00000010          - Ustaw kolor czarny i znaki w pozytywie
    00000011          - Ustaw kolor biały i znaki w negatywie
    00000111          - Ustaw kolor odwracający
    
    00000100          - Przejdź do stanu wprowadzania tekstu, powrót do stanu normalnego po wysłaniu znaku 00h
    00000101 CCCCCCCC - Wprowadź jeden znak
    00000110          - Przejdź do nowej linii
    00001CLV          - Ustawienia kursora tekstowego
                         - C - Przejście do nowej linii w przypadku znaku 0Dh
                         - L - Przejście do nowej linii w przypadku znaku 0Ah
                         - V - Kursor widoczny
    
    0010NSEW          - Przesuń kursor tekstowy o jedna pozycje
                         - N - W górę
                         - S - W dół
                         - E - W prawo
                         - W - W lewo
    
    0001N000          - Narysuj punkt
                         - N = 0 => Punkt nr 1
                         - N = 1 => Punkt nr 2
    0001N001          - Wypełnij obszar zamknięty
                         - N = 0 => Punkt nr 1
                         - N = 1 => Punkt nr 2
    0001_010          - Narysuj odcinek
    0001F011          - Narysuj prostokąt
                         - F = 0 => Pusty
                         - F = 1 => Pełny
    0001F10P          - Narysuj elipsę
                         - F = 0 => Pusta
                         - F = 1 => Pełna
                         - P = 0 => Współrzędne w punkcie 1, punkt 2 określa promienie
                         - P = 1 => Współrzędne w punkcie 2, punkt 1 określa promienie


    Układ posiada dwa wyłączniki, jeden włącza i wyłącza mikrokontroler, co pozwala restartować wyświetlacz i zmieniać tryby pracy bez odłączania lub przerywania zasilania urządzenia sterującego. Drugi wyłącznik umożliwia włączenie i wyłączenie podświetlenia. Wyświetlacz może pracować w trzech trybach. Wyświetlacz włączony bez trzymania któregokolwiek przycisku pracuje w trybie normalnej pracy. Przedstawiam dwa filmy, które nagrałem 2 lata temu:
    https://www.youtube.com/watch?v=YNZVdzwIfl4
    https://www.youtube.com/watch?v=5dL43_pmpAU
    Oprócz tego, daję zdjęcia z gry "Dominosa". W kolejności to jest początek tej gry na 6 poziomie i nieprawidłowe jej ukończenie, a następnie początek i prawidłowe ukończenie tej samej gry na 3 poziomie. W tej grze prezentowana jest plansza z różna liczbą oczek od 0 do tylu, ile wskazuje poziom i zadaniem gracza jest przykrycie planszy kostkami domina tak, żeby spełnić następujące warunki:
    - Kostka przykrywająca ma takie same pola, jak przykrywane pola planszy
    - Każda kostka jest inna
    - Każde pole na planszy jest przykryte dokładnie jeden raz (połową jednej kostki)
    Plansza jest wyświetlana po lewej stronie, a dostępne kostki po prawej stronie. Kostka wyświetlona w negatywie wskazuje, że jest użyta więcej niż jeden raz, co nie jest prawidłowe w grze.
    Wyświetlacz LCD do dowolnego układu Wyświetlacz LCD do dowolnego układu Wyświetlacz LCD do dowolnego układu Wyświetlacz LCD do dowolnego układu
    Jeżeli w chwili uruchomienia wyświetlacza jest trzymany pierwszy przycisk, to zostanie uruchomiony tryb ustawień. Ustawia się 3 parametry:
    Clock rate - Liczba cykli zegarowych na bit transmisji (wartość od 1 do 256), co przekłada się na prędkość transmisji (wyświetlona jako Baudrate, ze wzoru 7372800/(ClockRate*16)).
    Change mode - Kierunek i krok zmiany wartości liczby cykli zegarowych. To ustawienie nie wpływa na działanie wyświetlacza, ale pozwala zrealizować funkcjonalność ustawień na dwóch przyciskach, w których pierwszy wypiera parametr, a drugi zmienia wartość tego parametru.
    Return - Informacja zwrotna, czyli sposób reakcji na zapełnienie połowy bufora. Dostępne opcje to "None" (brak sygnalizacji, użyteczne w przypadku podłączenia do mikrokontrolera z UART, który nie może bezpośrednio odczytywać stanu linii wejścia), druga to "Low level on full", czyli stan niski przy zapełnieniu bufora.
    Wyświetlacz LCD do dowolnego układu Wyświetlacz LCD do dowolnego układu
    Aby przetestować transmisje, należy uruchomić wyświetlacz w trybie testowym, czyli uruchomić go trzymając drugi przycisk. Pojawi się słowo "TEST" i każde wysłanie bajtu do wyświetlacza spowoduje wyświetlenie wartości w postaci binarnej. W tym trybie należy sprawdzić, czy wyświetlane wartości są takie same, jak wysyłane. W przypadku błędów należy skorygować prędkość transmisji. Najlepiej uruchomić program, który wyświetla wszystkie wartości, w których jest jedna jedynak i siedem zer oraz wszystkie wartości, w których jest jedno zero i siedem jedynek, pożądane jest, żeby po każdych czterech program czekał na reakcje użytkownika (naciśnięcie klawisza urządzenia).
    Wyświetlacz LCD do dowolnego układu Wyświetlacz LCD do dowolnego układu Wyświetlacz LCD do dowolnego układu Wyświetlacz LCD do dowolnego układu
    Płytka z elektroniką od góry (po zdjęciu wyświetlacza) i od dołu.
    Wyświetlacz LCD do dowolnego układu Wyświetlacz LCD do dowolnego układu Wyświetlacz LCD do dowolnego układu Wyświetlacz LCD do dowolnego układu
    W załączniku kod źródłowy programu mikrokontrolera.

    Cool? Ranking DIY
    About Author
    andrzejlisek
    Level 29  
    Offline 
    Has specialization in: informatyk
    andrzejlisek wrote 3043 posts with rating 482, helped 61 times. Live in city Poznań. Been with us since 2005 year.
  • phoenixcontact
  • #2
    piotrva
    VIP Meritorious for electroda.pl
    Sam dawno temu popełniłem podobny projekt ;) W Bascom jeszcze ;)
    https://www.elektroda.pl/rtvforum/topic1678136.html
    Heh, z pewną dozą nostalgii sobie przypomniałem te zabawy sprzed 6 lat ;)

    Wartości elementów można wywnioskować z tego co napisałeś - poczytaj o oznaczeniach ;)

    Parę uwag dot. programu.
    1. nie definiuj F_CPU w kodzie - zawsze w definicjach w opcjach kompilacji.
    2. Program łatwiej się analizuje jeśli jest... rozbity na pliki - u Ciebie jest jeden kolosik ;)
    3. nie stosuj include-ów ze ścieżką bezwzględną ;)
    4. w definicji delay - wypadałoby dodać volatile, bo inaczej przy kompilacji z optymalizacją opóźnienie zostanie skasowane. Dalej tak generowane opóźnienie będzie zależne od cz. taktowania ;)
    5. Komunikację po UART można było zrobić na przerwaniach. teraz trzeba czekać na zakończenie operacji aby nadawać kolejne dane.
    6. Można było się pokusić o automatyczne ustawianie prędkości transmisji.
  • #3
    andrzejlisek
    Level 29  
    piotrva wrote:

    Wartości elementów można wywnioskować z tego co napisałeś - poczytaj o oznaczeniach ;)

    Właśnie wyczytałem, że opornik ma 10kOm, potencjometr 22kOm, dwa kondensatory mają 22pF, a cztery pozostałe mają 22nF.

    piotrva wrote:

    1. nie definiuj F_CPU w kodzie - zawsze w definicjach w opcjach kompilacji.

    Tego nie wiedziałem. Pracowałem z AVRStudio i wydawało się być oczywiste, że jeżeli jakaś stała ma mieś określoną wartość dla tego konkretnego programu, to definiuje się ją w kodzie tego programu. Musiałbym poszukać w opcjach kompilacji, gdzie się to definiuje.

    piotrva wrote:

    2. Program łatwiej się analizuje jeśli jest... rozbity na pliki - u Ciebie jest jeden kolosik ;)

    To się zgadza. Miał być to prosty program, tylko potem się tak rozrósł.

    piotrva wrote:

    3. nie stosuj include-ów ze ścieżką bezwzględną ;)

    Uwaga bardzo słuszna, jednak plik "binary.h" nie jest związany nawet z AVR, tylko używam w różnych projektach kompilowanych w C i C++, zawiera tylko ciągi bitowe w formacie Bxxxxxxxx dla liczb od 0 do 255.

    piotrva wrote:

    4. w definicji delay - wypadałoby dodać volatile, bo inaczej przy kompilacji z optymalizacją opóźnienie zostanie skasowane. Dalej tak generowane opóźnienie będzie zależne od cz. taktowania ;)

    Gdzie to "volatile" byś wstawił? Wydaje mi się, że składnia "define" nie przewiduje takiej "flagi".

    piotrva wrote:

    5. Komunikację po UART można było zrobić na przerwaniach. teraz trzeba czekać na zakończenie operacji aby nadawać kolejne dane.

    Pamiętam, że na początku próbowałem właśnie na przerwaniach, jednak pomimo teoretycznie poprawnego kodu, były problemy z działaniem, że albo nie odbierał, albo były błędy (wyświetlacz pokazywał coś innego niż to, co powinno). Być może zabrało "volatile" przy pewnych zmiennych. Wadą jest to, że procedurę odbioru należy wywoływać jak najczęściej, jest ona wciśnięta wszędzie, gdzie się da, między innymi we wszystkich pętlach. Sama obsługa portu, to jest wychwycenie, czy przyszedł nowy bajt i wprowadzenie go do bufora. Zgadzam się z tym, że jest to złe podejście, jednak problemy z działaniem skłoniły mnie do takiego, jakie zastosowałem.

    piotrva wrote:

    6. Można było się pokusić o automatyczne ustawianie prędkości transmisji.

    O tym nie myślałem. Czy chodziło Ci o to, że program na początku wysyła jakąś ustaloną sekwencję (np.bity naprzemiennie lub skrajne bity inne niż pozostałe), a program wyświetlacza dobiera prędkość tak długo, aż odbierane bajty będą mieć ustaloną wartość i to zasygnalizuje w jakiś sposób, np. poprzez zmianę stanu linii zwrotnej?
  • phoenixcontact
  • #4
    piotrva
    VIP Meritorious for electroda.pl
    andrzejlisek wrote:
    Uwaga bardzo słuszna, jednak plik "binary.h" nie jest związany nawet z AVR, tylko używam w różnych projektach kompilowanych w C i C++, zawiera tylko ciągi bitowe w formacie Bxxxxxxxx dla liczb od 0 do 255.

    Ależ kompilator akceptuje zapis binarny w formacie 0b............. Użycie takiego pliku to jakbyś tworzył książkę z wynikami sumować wszystkich liczb 8 bitowych - trochę bez sensu ;) czyli zapis 0b1011 będzie poprawnie zinterpretowany ;)

    andrzejlisek wrote:
    Gdzie to "volatile" byś wstawił? Wydaje mi się, że składnia "define" nie przewiduje takiej "flagi".

    Ale jest zapis asm volatile(...);

    andrzejlisek wrote:
    Pamiętam, że na początku próbowałem właśnie na przerwaniach, jednak pomimo teoretycznie poprawnego kodu, były problemy z działaniem, że albo nie odbierał, albo były błędy (wyświetlacz pokazywał coś innego niż to, co powinno). Być może zabrało "volatile" przy pewnych zmiennych. Wadą jest to, że procedurę odbioru należy wywoływać jak najczęściej, jest ona wciśnięta wszędzie, gdzie się da, między innymi we wszystkich pętlach. Sama obsługa portu, to jest wychwycenie, czy przyszedł nowy bajt i wprowadzenie go do bufora. Zgadzam się z tym, że jest to złe podejście, jednak problemy z działaniem skłoniły mnie do takiego, jakie zastosowałem.

    No to poszedłeś trochę na skróty (pewnie żądny efektów - też tak czasem mam), ale hmm, jak tak patrzę - może czas na odkurzenie projektu i poprawienie tego i owego? Możesz na stronie And-Techu podejrzeć przykłady pod m. in. ATMegę32 z obsługą UART'a na przerwaniach.

    andrzejlisek wrote:
    O tym nie myślałem. Czy chodziło Ci o to, że program na początku wysyła jakąś ustaloną sekwencję (np.bity naprzemiennie lub skrajne bity inne niż pozostałe), a program wyświetlacza dobiera prędkość tak długo, aż odbierane bajty będą mieć ustaloną wartość i to zasygnalizuje w jakiś sposób, np. poprzez zmianę stanu linii zwrotnej?


    Mniej więcej tak. Zwykle robi się to tak, że po starcie procesora (czy np. ustawieniu jakiejś linii przez drugie urządzenie) przeprowadza taką procedurę.

    Można to zrobić na 2 sposoby:
    1. Zakładamy, że użytkownik korzysta z jednej z kilku określonych prędkości. Wtedy np. ustawiamy się na najniższą z nich i patrzymy co odbierzemy. W zależności jak zostanie "zniekształcony" znak (wiemy co miało być nadane) określamy której prędkości używa użytkownik. Tu uwaga - przy niektórych relacjach odpowiedź "zniekształcona" może być zniekształcona w nieco losowy sposób (niektóre bity wypadające na granicy próbkowania przez uC)
    2. Elegancko - prędkość dowolna. Ustawiamy sekwencję która nadaje np. 2 zera - na początku i na końcu bajtu (przy stanie spoczynkowym linii 1). Mierzymy tylko czas między tymi 2 impulsami z wykorzystaniem timera i na tej podstawie określamy prędkość.

    W obu sytuacjach po powodzeniu odsyłamy tez znaną odpowiedź do układu nadrzędnego - jeśli wszystko ok - działamy dalej. Jeśli nie - powtarzamy.
  • #5
    andrzejlisek
    Level 29  
    piotrva wrote:
    andrzejlisek wrote:
    Uwaga bardzo słuszna, jednak plik "binary.h" nie jest związany nawet z AVR, tylko używam w różnych projektach kompilowanych w C i C++, zawiera tylko ciągi bitowe w formacie Bxxxxxxxx dla liczb od 0 do 255.

    Ależ kompilator akceptuje zapis binarny w formacie 0b............. Użycie takiego pliku to jakbyś tworzył książkę z wynikami sumować wszystkich liczb 8 bitowych - trochę bez sensu ;) czyli zapis 0b1011 będzie poprawnie zinterpretowany ;)

    ZTCW, to literały binarne są dopiero od C++11 lub C++14, ten plik powstał na potrzeby kompilatora Keil uVision lub SDCC (już nie pamiętam, którego, a na pewno nie obsługiwał on literałów binarnych). Możliwe, że akurat nowy Atmel Studio już obsługuje C11 i faktycznie można zrezygnować z pliku "binary.h". jak kiedyś wrócę do tego projektu, to sprawdzę.

    piotrva wrote:
    andrzejlisek wrote:
    Gdzie to "volatile" byś wstawił? Wydaje mi się, że składnia "define" nie przewiduje takiej "flagi".

    Ale jest zapis asm volatile(...);

    andrzejlisek wrote:
    Pamiętam, że na początku próbowałem właśnie na przerwaniach, jednak pomimo teoretycznie poprawnego kodu, były problemy z działaniem, że albo nie odbierał, albo były błędy (wyświetlacz pokazywał coś innego niż to, co powinno). Być może zabrało "volatile" przy pewnych zmiennych. Wadą jest to, że procedurę odbioru należy wywoływać jak najczęściej, jest ona wciśnięta wszędzie, gdzie się da, między innymi we wszystkich pętlach. Sama obsługa portu, to jest wychwycenie, czy przyszedł nowy bajt i wprowadzenie go do bufora. Zgadzam się z tym, że jest to złe podejście, jednak problemy z działaniem skłoniły mnie do takiego, jakie zastosowałem.

    No to poszedłeś trochę na skróty (pewnie żądny efektów - też tak czasem mam), ale hmm, jak tak patrzę - może czas na odkurzenie projektu i poprawienie tego i owego? Możesz na stronie And-Techu podejrzeć przykłady pod m. in. ATMegę32 z obsługą UART'a na przerwaniach.

    Zgadzam się z tym, że warto odkurzyć ten projekt i ulepszyć go. Teraz mam większe doświadczenie w programowaniu w C niż wtedy, dodatkowo posiadam teraz oscyloskop, którego wtedy nie posiadałem, co powodowało, że działałem po omacku. Jak coś wymyśle, ulepszę, to będę zamieszczać.

    piotrva wrote:
    andrzejlisek wrote:
    O tym nie myślałem. Czy chodziło Ci o to, że program na początku wysyła jakąś ustaloną sekwencję (np.bity naprzemiennie lub skrajne bity inne niż pozostałe), a program wyświetlacza dobiera prędkość tak długo, aż odbierane bajty będą mieć ustaloną wartość i to zasygnalizuje w jakiś sposób, np. poprzez zmianę stanu linii zwrotnej?


    Mniej więcej tak. Zwykle robi się to tak, że po starcie procesora (czy np. ustawieniu jakiejś linii przez drugie urządzenie) przeprowadza taką procedurę.

    Można to zrobić na 2 sposoby:
    1. Zakładamy, że użytkownik korzysta z jednej z kilku określonych prędkości. Wtedy np. ustawiamy się na najniższą z nich i patrzymy co odbierzemy. W zależności jak zostanie "zniekształcony" znak (wiemy co miało być nadane) określamy której prędkości używa użytkownik. Tu uwaga - przy niektórych relacjach odpowiedź "zniekształcona" może być zniekształcona w nieco losowy sposób (niektóre bity wypadające na granicy próbkowania przez uC)
    2. Elegancko - prędkość dowolna. Ustawiamy sekwencję która nadaje np. 2 zera - na początku i na końcu bajtu (przy stanie spoczynkowym linii 1). Mierzymy tylko czas między tymi 2 impulsami z wykorzystaniem timera i na tej podstawie określamy prędkość.

    W obu sytuacjach po powodzeniu odsyłamy tez znaną odpowiedź do układu nadrzędnego - jeśli wszystko ok - działamy dalej. Jeśli nie - powtarzamy.

    Z punktem 2 to dobry pomysł. Wtedy do ustawień można dorobić opcje "auto", gdzie po uruchomieniu wyświetlacza będzie oczekiwać na przeprowadzenie procedury ustalającej prędkość transmisji.
  • #6
    Milek79
    Level 15  
    piotrva wrote:
    1. nie definiuj F_CPU w kodzie - zawsze w definicjach w opcjach kompilacji.

    Jeżeli to i tak jest w jednym pliku, to po co?
    piotrva wrote:
    4. w definicji delay - wypadałoby dodać volatile, bo inaczej przy kompilacji z optymalizacją opóźnienie zostanie skasowane. Dalej tak generowane opóźnienie będzie zależne od cz. taktowania ;)

    https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile
    "asm statements that have no output operands, including asm goto statements, are implicitly volatile. "
    andrzejlisek wrote:
    ZTCW, to literały binarne są dopiero od C++11 lub C++14, ten plik powstał na potrzeby kompilatora Keil uVision lub SDCC (już nie pamiętam, którego, a na pewno nie obsługiwał on literałów binarnych). Możliwe, że akurat nowy Atmel Studio już obsługuje C11 i faktycznie można zrezygnować z pliku "binary.h". jak kiedyś wrócę do tego projektu, to sprawdzę.

    W standardzie są od C++14, ale gcc obsługuje je jako swoje rozszerzenie standardu już wcześniej.
  • #7
    piotrva
    VIP Meritorious for electroda.pl
    Milek79 wrote:
    Jeżeli to i tak jest w jednym pliku, to po co?

    Dla zasady ;) A na serio - np. za jakiś czas trzeba będzie dołączyć jakiś plik/bibliotekę i zaczną się schody.
    Milek79 wrote:
    "asm statements that have no output operands, including asm goto statements, are implicitly volatile. "

    Racja, ale znów lepiej pokazać o co nam chodzi. Podobnie jak czasem bywa z priorytetem operatorów - szczerze poza mnożeniem/dzieleniem i dodawaniem/odejmowaniem stosuję nawiasy - niby mógłbym sprawdzać/zapamiętać priorytety, ale nadmiar nie szkodzi a ułatwia analizowanie kodu ;)
  • #9
    andrzejlisek
    Level 29  
    MAREK10747 wrote:
    Do raspbery pi też to jest ????

    Ja osobiście nie próbowałem, jednak teoretycznie ro Raspberry Pi też można podłączyć i obsłuzyć. o ile dobrze pamiętam, RPi operuje poziomami 0V i 3,3V, więc trzeba dołączyć odpowiedni konwerter poziomów, ale posiada on UART wyprowadzony na GPIO, więc transmisję rozkazów można obsługiwać sprzętowo, w programie, to tylko wprowadzać bajty do bufora. Sygnał zajętości bufora można odebrać na innym wejściowym porcie GPIO.
  • #10
    andrzejlisek
    Level 29  
    Od wczoraj wykorzystuję ten wyświetlacz do testów z jednym układem na ATMega328. Na linii danych jest stan wysoki, napięcie zasilania trochę spada (niewystarczająca wydajność prądowa USB lub PS/2 z którego zasilam wszystko). Napięcie mierzone woltomierzem wynosi ok. 4,5-4,8V. Stwierdziłem, że jak jest stan wysoki na linii danych, to jak wyłączam ATMega32 wyłącznikiem (jest on na schemacie, drugi wyłącznik wyłącza podświetlenie, wyłączanie kontrolera wyświetlacza nie jest przewidziane), to zachowuje się, jakby zasilanie było cały czas, tylko jakby napięcie było obniżone lub niestabilne. Układ pracuje, ale nieprawidłowo. Pomyślałem, że wyłącznik się popsuł lub zrobiło się zwarcie. Po dokładniejszej analizie nic z tych rzeczy. Odłączanie kabla komunikacyjnego (w tym przypadku był poziom napięć 5V i zamiast układu MAX232 były zrobione odpowiednie zwarcia w podstawce, ten sam kabel zapewnia zasilanie 5V) powodowało prawidłowy reset.

    Dorobiłem trzeci przycisk, który zwiera wyjście RESET z masą i jeżeli w celu zmiany trybu pracy wciskam ten przycisk zamiast wyłączać ATMega32 (tak postępowałem wcześniej), to działa prawidłowo. Nawet, jak jest włączone podświetlenie, wyświetlacz działa prawidłowo z tą różnicą, że treść jest ledwo widoczna.