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.

[M32][Bascom] Wstęp do warstwowej obsługi LCD oraz menu

Antystatyczny 11 Lip 2012 23:54 4702 38
  • #1 11 Lip 2012 23:54
    Antystatyczny
    Poziom 16  

    Naskrobałem coś taskiego, po przeczytaniu bloga Mirekk36:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Generalnie kod działa, tzn. skacze do podprogramów, które mają obsługiwać poszczególnie wybory w menu, ale zastanawi amnie to, że muszę wyświetlacz bardzo rzadko odświeżać. Początkowo pisałem program z właczonym internal 1MHz, ale nie działało. Zmieniłem na external xtal 16Mhz... też nie działało. Dopiero, gdy zaprzągłem do pracy 16 bitowy timer i dałem mu dość spory podzielnik, program, a konkretnie wyświetlacz LCD zaczął reagować. Aha, by sprawdzić, czy program działa... w każdej etykiecie była wpisana obsługa toggle "dioda na porta.x". Przy małym preskalerze diody nie reagowały.
    Zerknijcie proszę w kod i napiszcie, czy nie popełniam jakiegoś rażącego błędu... (poza użyciem tego nieszczęsnego debounce)

    Dodano po 3 [minuty]:

    Zapomniałem dodać, że to nie jest pełen program, bo on dopiero powstaje.

    Dodano po 3 [minuty]:

    w komentarzu programu jest bład: ddra = &B00001111 ' ma być input!

    0 29
  • #2 12 Lip 2012 09:35
    Krauser
    Poziom 26  

    Przerwanie masz teraz co 262ms. A sprawdź jak działa samo wyświetlanie:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    Jeśli tak będzie za wolno to daj znać.

    0
  • #3 12 Lip 2012 11:21
    Antystatyczny
    Poziom 16  

    Dzięki za odpowiedź. Rozumiem, że mam wykonać test bez wykorzystania przerwań, a Twój kod umieścić w pętli głównej, a następnie obserwować, czy zawartość wyświetlacza ulega zmianie, tak?

    Dodano po 1 [godziny] 14 [minuty]:

    Napisałem taki krótki test:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Sprawdzę prędkość działania wyświetlacza zaraz po powrocie do domu.

    0
  • #4 12 Lip 2012 22:09
    Antystatyczny
    Poziom 16  

    Powyższy kod działa poprawnie wyświetlając dwa zestawy stringów z dość dużą częstotliwością odświeżania. Na moje oko jakieś 15-20Hz. Można by rzec, że tworzą się juz duszki.

    Dodano po 37 [minuty]:

    Problem polega na tym, że jest to kolejny kod, w którym timery nie chcą mi pracować z preskalerem wiekszym od 64. Moduł uruchomieniowy własnej roboty zasilam zasilaczem z telefonu komórkowego(impulsowy). Może to ma jakiś wpływ na te timery? Może chodzi o jakieś zakłócenia?

    0
  • #5 13 Lip 2012 18:03
    Krauser
    Poziom 26  

    Nie pokazałeś schematu więc nic nie doradzę może poza przeglądnieciem http://mikrokontrolery.blogspot.com/ odnośnie minimalnego podłaczenia procesora. Napisz programik testowy dla timera1 z preskalerem 256 i zmianą stanu pinu portu w przerwaniu. Dla kwarcu 16MHz przerwanie wystąpi co około 1 sekundę. Jak to nie zadziała to może znalazłeś jakiś błąd i wtedy pokażę jak to zrobić poprzez wpis do rejestrów, a nie funkcje Config Timer1.

    0
  • #6 13 Lip 2012 21:53
    Antystatyczny
    Poziom 16  

    Dziś wykonałem testy wszystkich timerów z wszystkimi możliwymi preskalerami i sprzętowo wszystko jest OK. Wniosek jest taki, że zarówno bascom jak i ja nie jest doskonały. Poniżej prezentuję działający, lecz niedokończony program:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Mam teraz pytanie z innej beczki, ale dotyczące tego projektu. Chciałem zadeklarować tablicę o pojemności 16 bajtów, ale chciałbym je zapełniać zmiennymi typu char. Konstrukcja polecenia była następująca:
    Dim linia1(16) as string. Kompilator zwraca błąd. Gdzie popełniłem błąd? Nie doczytałem czegoś w helpie bascoma, czy raczej on tego nie obsługuje? Mam wersję 2.0.7.1. Teraz przyszło mi do głowy, że może mam deklarować jako char?
    Bardzo proszę o jakąś wskazówkę.

    Dodano po 4 [minuty]:

    W helpie bascom nie ma ani słowa o dim as char :(

    Dodano po 5 [minuty]:

    Aha, odnośnie minimalnego podłączenia, to brakuje mi jedynie dławika 10µH dla AVCC, ale nie używam ADC.

    0
  • #7 13 Lip 2012 21:58
    MArSTER_1
    Poziom 18  

    Dim linia1(16) as string * 10
    Gdzie 10 to długość stringa. Może oczywiście być inna.

    0
  • #8 13 Lip 2012 22:03
    Antystatyczny
    Poziom 16  

    Taka składnia zwraca błąd. Ćwiczyłem to już na wszystkie sposoby. Efekt jest taki, że kompilator wywala błąd "array expected" i kilka innych, co mnie w sumie nie dziwi, bo sie reszta programu rozjeżdża.

    0
  • #9 13 Lip 2012 22:06
    MArSTER_1
    Poziom 18  

    Używam wielu tak zadeklarowanych tablic. Czy mógłbyś zamieścić fragment kodu?

    0
  • #10 13 Lip 2012 22:08
    Antystatyczny
    Poziom 16  

    Bardzo proszę. Zmodyfikowałem program tak, by uzywał tablic. To jest mod pierwszego listingu:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Nie mam pojęcia, gdzie popełniam błąd.

    0
  • #11 13 Lip 2012 22:13
    MArSTER_1
    Poziom 18  

    Błąd jest nie w deklaracji tablicy a w jej wywołaniu w programie.

    Piszesz: Linia1 = "1.Menu 2.Czas "
    A powinieneś: Linia1(1) = "1.Menu 2.Czas "

    Popraw tez pozostałe i będzie dobrze.

    0
  • #12 13 Lip 2012 22:20
    Antystatyczny
    Poziom 16  

    Poprawiłem w menu głównym jak i w obsłudze przerwania. Bardzo dziękuję za podpowiedź. Mam jeszcze pytanie. Jeśli napiszę, że linia(5) = "1234" będzie znaczyło, że właśnie zapełniłem pole 5,6,7 i 8 tej tablicy cyframi 1, 2, 3 i 4?

    0
  • #13 14 Lip 2012 06:05
    MArSTER_1
    Poziom 18  

    To będzie znaczyło, że do komórki numer 5 wpisałeś tekst czteroznakowy 1234.

    0
  • #14 14 Lip 2012 09:03
    Antystatyczny
    Poziom 16  

    A jeśli zadeklaruję:
    Dim linia1(16) as string *1
    ... to :
    linia1(5) = "1234"
    ... spowoduje wpisanie pojedynczych cyfr do kolejnych komórek tablicy linia1()?

    Dodano po 3 [minuty]:

    To jest raczej błędna deklaracja, bo przekraczam rozmiar pojedynczej komórki... Kompilator zwraca mi błąd.

    0
  • #15 14 Lip 2012 09:12
    MArSTER_1
    Poziom 18  

    Aby zapisywać liczby musisz zadeklarować tablicę liczb nie stringów.
    na przykład
    dim tablica(4) as byte
    tablica(1) =1
    tablica(2) =2
    tablica(3) =3
    tablica(4) =4

    0
  • #16 14 Lip 2012 09:16
    Krauser
    Poziom 26  

    Co ty właściwie szukasz. Czy chcesz zużyć 17 bajtów - bo tyle zajmie string o długości 16 znaków czy 170 bajtów bo tyle zajmie tablica tych stringów. Znasz takie coś jak zakrywanie w bascomie.

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Zajmuje to w pamięci 17 bajtów, a do każdego znaku odnosisz się jak do komórki tablicy.

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #17 14 Lip 2012 09:23
    Antystatyczny
    Poziom 16  

    Może wyjaśnię, o co mi mniej więcej chodzi.
    Chcę stworzyć dwa bufory o pojemności 16 znaków, by móc przechowywać w nich dane dla wyświetlacza LCD. Wyobrażałem sobie, że jeśłi odwołam się do bufora w sposób np.: linia1(5) = "czas" spowoduję wpisanie do tablicy 4 liter, po jednej na każdą komórkę tablicy począwszy od komórki 5. Może są jakies inne mechanizmy? A może muszę każdą literę tekstu zapisać w postaci kodów ascii, a tablicę deklarować jako byte?

    Dodano po 5 [minuty]:

    Aha, o zakrywaniu nie miałem dotąd pojęcia.

    0
  • #18 14 Lip 2012 09:27
    Krauser
    Poziom 26  

    To spoko rozwiązanie jak powyżej

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #19 14 Lip 2012 09:30
    Antystatyczny
    Poziom 16  

    Rozumiem, że nałozyłem dane z tablicy na już istniejącą w pamięci RAM inną zmienną, tak? Bardzo fajne rozwiązanie. Hmm, a da się to ciut zautomatyzować, czy raczej do każdej komórki tablicy muszę odwoływać się osobno?

    0
  • #20 14 Lip 2012 09:45
    Krauser
    Poziom 26  

    Można też na odwrót

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    Problematyczne jest to że każdy string to dodatkowo pusty bajt oznaczający koniec napisu.

    Sprawdź jak zadziała takie coś:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #21 14 Lip 2012 20:50
    Antystatyczny
    Poziom 16  

    Sprawdzę zaraz po powrocie do domu i dam znać, teraz nie mam przy sobie modułu uruchomieniowego. Faktycznie, sprawa końca stringa może być pewnym kłopotem, ale przecież mogę w kolejnym poleceniu pokryć ten znak początkiem jakiejś innej zmiennej i w efekcie w buforze, po zakończeniu nakładania warstw, pozostanie tylko jeden znak końca stringa w komórce 17. Dobrze myślę?

    Dodano po 4 [godziny] 36 [minuty]:

    Najpierw kod:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Program opatrzony jest odpowiednim komentarzem. Nie wiem, dlaczego nie wyświetliły sie gwiazdki.

    Dodano po 3 [minuty]:

    Już wiem, chwilowe zaćmienie miałem...

    Dodano po 2 [minuty]:

    Bez usunięcia znaku NULL reszta znaków sie nie wyświetla (tylko gwiazdki), czyli zgodnie z przewidywaniami.

    Dodano po 4 [godziny] 41 [minuty]:

    Mam teraz następujący szkielet programu:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Jako, że mam się trzymać z daleka od instrukcji wait, bitwait i debounce, kombinuję z pętlą for next, by usunąć drgania styków. Działa to koszmarnie. Poza tym wydaje mi się, że pętla for next i tak marnuje czas procesora. Koledzy wspominali o uzyciu timera do tego, ale nie bardzo wiem, jak się do tego zabrać.
    Bardzo proszę o jakiekolwiek wskazówki.

    0
  • #22 14 Lip 2012 21:27
    LordBlick
    VIP Zasłużony dla elektroda

    Antystatyczny napisał:
    Koledzy wspominali o uzyciu timera do tego, ale nie bardzo wiem, jak się do tego zabrać.
    Bardzo proszę o jakiekolwiek wskazówki.
    Generalnie co każde przerwanie timera jakaś zmienna jest takim wyznacznikiem upływu czasu.

    0
  • #23 14 Lip 2012 21:46
    Antystatyczny
    Poziom 16  

    Mam już użyty timer0 do odświeżania wyświetlacza LCD. Przepełnia sie około 15 razy na sekundę. Mam zaprząc kolejny timer, czy kombinować z timer0? Nie bardzo wiem, jak się za to zabrać... Nie proszę o gotowy kod, ale o jakieś wskazówki, schemat blokowy, czy cos w tym stylu. Jakaś zasada w punktach też będzie dobra.

    Dodano po 4 [minuty]:

    Na dodatek nie wiem, czy jedno przerwanie nie zakłóci drugiego, nie znam priorytetów ( o ile takowe istnieją w M32). Im więcej wiem, tym mniej wiem :]

    0
  • #24 14 Lip 2012 23:13
    LordBlick
    VIP Zasłużony dla elektroda

    Antystatyczny napisał:
    Mam już użyty timer0 do odświeżania wyświetlacza LCD.
    To źle robisz. Obsługa wyświetlacza nie należy do błyskawicznej , więc nic więcej nie będzie działać, zanim się napisy nie wyświetlą, a przy tym Timer się przekręci kilkanaście razy, więc zgubisz tyle przerwań. W obsłudze przerwania nie robi się nic, co by miało trwać zbyt długo. Nadal odbywasz błyskawiczny kurs, po którym za dużo się nie dowiesz, np. co siedzi w obsłudze wyświetlacza, jak naprawdę działa mikrokontroler... Jeśli masz zamiar przesiadać się na inny język, to czas spędzony na programowaniu w Bascom jest czasem straconym, bo i tak w innym języku będziesz musiał zrobić wszystkie te same ćwiczenia od początku. Ten język jest dla ludzi chcących tylko coś uruchomić bez wnikania, natomiast nie jest dobry do nauki programowania od podstaw.

    0
  • #25 15 Lip 2012 08:25
    Antystatyczny
    Poziom 16  

    No to może w przerwaniu ustawię tylko flagę, a w pętli głównej będę odświeżał LCD pod warunkiem, że flaga jest ustawiona.

    Koledzy proponują mi m. in. przesiadkę na Eclipse. Dysponuję internetem z ograniczoną możliwością pobierania danych (limit 4GB/mies.) i powstaje pytanie... Ile zajmuje plik instalacyjny Eclipse?

    Dodano po 6 [minuty]:

    Już widzę, że eclipse to jedynie plugin do czegoś "grubszego"... Będę musiał samodzielnie kompilować gcc? Ostatnio, gdy chciałem zainstalować bodaj codeblocks z biblioteką alegro, konieczna była instalacja z kompilacją gcc, która to zakończyła się sromotną porażką.

    0
  • #26 15 Lip 2012 08:56
    Krauser
    Poziom 26  

    LordBlick napisał:

    Antystatyczny napisał:
    Mam już użyty timer0 do odświeżania wyświetlacza LCD.
    To źle robisz. Obsługa wyświetlacza nie należy do błyskawicznej , więc nic więcej nie będzie działać, zanim się napisy nie wyświetlą, a przy tym Timer się przekręci kilkanaście razy, więc zgubisz tyle przerwań. W obsłudze przerwania nie robi się nic, co by miało trwać zbyt długo.
    To znaczy ile ? Bo z tego co wiem to tylko CLS i Home trwają kilka ms, a wysłanie Bajtu(znaku) to już kilkadziesiąt us.

    Skoro przerwanie jest co 65ms to jest dłuzej niż drgania styków które wynoszą typowo 20ms, więc jeśli w przerwaniu sprawdzisz czy wciśnięty jest klawisz to będzie dobrze.
    Przesiadka na Eclipse to może dobry pomysł. Z książką Mika Kardasia masz DVD z Eclipse, które wystarczy skopiować na dysk i nie musisz nic ściągać, a gcc tak czy siak nie trzeba kompilować tylko ściągasz WinAVR albo Atmel AVR Toolchain. A odnośnie pytania to eclipse ma 143MB, ale potrzeba jeszcze javę JRE.

    0
  • #27 15 Lip 2012 09:10
    Antystatyczny
    Poziom 16  

    W obsłudze przerwania, oprócz wyświetlenia dwóch wierszy na LCD, mam IF'ami sprawdzić czy mam wciśnięte klawisze, a jeśli tak, to zeruję flagi... np. klawisz1-klawisz4, a w pętli głównej odwoływać się jedynie do tych flag, tak?

    0
  • #28 15 Lip 2012 09:20
    Krauser
    Poziom 26  

    Lepiej na odwrót. Na początku są wyzerowane. W przerwaniu ustawiasz. W pętli głównej sprawdzasz, wykonujesz jakieś działanie i flagę zerujesz.

    0
  • #29 15 Lip 2012 09:24
    Antystatyczny
    Poziom 16  

    Miałem na myśli to, że początkowo są ustawione, by zachowywały się tak jak stany logiczne na pinach portu, które sa obsadzone przyciskami. Tylko po to, by mi się nie zajączkowało. Problem w tym, że zmienna będzie mi się inkrementować co 65ms, czyli baaardzo szybko.

    PS. Wywaliłem AVR6.0 i zainstalowałem winavr. Teraz po prostu ściągnąć i zainstalować AVR plugin for eclipse?

    0