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

Używanie dwóch timerów w BASCOM (atmega2560) - pobieranie danych z tablicy i sterowanie PORTB

marekms1 17 Mar 2023 08:55 708 17
  • #1 20493511
    marekms1
    Poziom 13  
    Program ma pobierać dane z tablic i ustawiać odpowiednie bity na PORTB. Timer0 ma co 0,5s pobrać z tabeli aktualną prędkość z jaką timer2 ma zmieniać stan na PORTB. Osobno timer'y działają, razem nie chcą .

    Kod: VB.net
    Zaloguj się, aby zobaczyć kod



    Uruchamiam ten program na płytce ARDUINO MEGA2560.

    Marek
  • Pomocny post
    #2 20494220
    ZbeeGin
    Poziom 39  
    1. W jakim celu konfigurujesz liczniki, wpisujesz im wartości początkowe, a potem wywołujesz ich zatrzymanie przez STOP TIMER0/TIMER2 skoro nigdzie indziej ich ponownie nie uruchamiasz?
    2. Jakim cudem kompilator nie protestuje gdy w pętli głównej umieszczasz samo ON TIMER0/TIMER2 nie podając trzeciego słowa kluczowego GOTO/GOSUB i ostatniego ich parametru?
    3. Co w ogóle robi polecenie GOSUB w przerwaniu? Chcesz przepełnić stos?
  • #3 20494538
    marekms1
    Poziom 13  
    Ad1. Ponieważ jest to mój drugi poważniejszy program w Bascom . Po za tym to wycinek całości, więc możliwe są braki w programie.
    Ad2. Chyba zrozumiałem na czym polega błąd. Powinienem skonfigurować timery i skok do podprogramu a w programie tylko stosować start/stop TIMERx.
    Ad3. Właśnie ten skok do podprogramu przy obsłudze przerwania też mi nie pasuje ale na razie nie mam pomysłu jak wprowadzić odczyt wartości z właściwego zbioru danych, bo tylko po odczyt skacze do konkretnego podprogramu .

    Marek
  • #4 20495366
    marekms1
    Poziom 13  
    Program poprawiłem, ale dalej jest problem z drugim timerem tzn. działa tylko z TIMER0 , działa klawiatura, funkcja rozpędzania wirnika. włączenie drugie timera wiesza program. Zamieszczony program (tylko z TIMER0) działa fizycznie.

    Kod: VB.net
    Zaloguj się, aby zobaczyć kod





    Marek
  • Pomocny post
    #5 20495492
    ZbeeGin
    Poziom 39  
    Proszę tak napisać program by nie było w nim ani jednej instrukcji GOTO, zwłaszcza w podprogramach oraz przytoczyć go w całości.
  • #6 20495583
    marekms1
    Poziom 13  
    Zamieściłem praktycznie cały program, wycięte jest menu ale ono nic nie zmienia. TIMER2 jest wykomentowany żeby uruchomić program na płytce. Co do instrukcji GOTO niestety nie umiem inaczej zapętlić danego podprogramu w celu oczekiwania np na naciśnięcie przycisku.
    Marek
  • Pomocny post
    #7 20496046
    ZbeeGin
    Poziom 39  
    Tak po krótce przeanalizowałem wątek TIMER2 tego nowego programu. Po prześledzeniu kilku instrukcji i "śladów skoków" mogę stwierdzić, że nie jest dziwne, że gdy aktywny jest TIMER2 i jego przerwania to wszystko siada.
    Pojawia się przerwanie TIMER2, program wskakuje do jego obsługi a tam napotyka: GOSUB w inne miejsce, gdzie napotyka GOTO w jeszcze inne miejsce, a na samym początku tego trzeciego miejsca napotyka... WAIT 1. (Szok!) I potem następuje cała seria przeskoków między podprogramami, która nie doprowadza do powrotu do kluczowego polecenia RETURN znajdującego się na końcu "Jeden_stopien".

    Pamiętaj, że RETURN z podprogramu a RETURN z przerwania to inne instrukcje wykonywane przez procesor. W tym drugim przypadku musi wykonać się jeszcze automatyczne wznowienie przyjmowania dalszych przerwań.

    Aha. I jeszcze jedno co mi umknęło. TIMER2 w układzie ATmega2560 ma tylko 8 bitów.
  • #8 20498514
    marekms1
    Poziom 13  
    No cóż, wychodzi na to że programista ze mnie żaden (delikatnie rzecz ujmując).
    Bardzo dziękuję koledze ZbeeGin za okazane zainteresowanie i wytknięcie poważniejszych błędów.

    Temat zamykam ponieważ nie mam czasu dalsze prace nad tym projektem.

    Marek
  • #9 20523810
    marekms1
    Poziom 13  
    Zgodnie z sugestią ZbeeGin napisałem od nowa program pozbywając się większości goto, niestety dalej wychodzi na to że program w pętli głównej działa zbyt długo i nie zdąża z odczytem wartości z tabeli pomiędzy kolejnymi przerwaniami.
    Kod: VB.net
    Zaloguj się, aby zobaczyć kod



    Marek
  • #10 20525618
    ZbeeGin
    Poziom 39  
    Niestety Bascom AVR jest nieoptymalny pod względem przerwań, bo obligatoryjnie zrzuca większość rejestrów na stos i je zdejmuje przed wykonaniem treści przerwania.
    Poza tym, zastanów się czy masz prawidłowo obliczone timingi, bo LOAD 1 nie powoduje, że do licznika wpisywane jest 1, tylko wynik operacji 65536-1, a zatem przy obecnym preskalerze co 8 taktów zegara masz przerwanie!

    Dodatkowo myślę, że powinieneś się zainteresować biblioteką "lcd4busy.lbx", która to w stosunku do wbudowanej nie ma stałych opóźnień, tylko wykorzystując komunikację zwrotną z LCD bierze pod uwagę bity statusu. Oczywiście wiąże się to z pewnymi konsekwencjami w postaci poświęcenia jednego pełnego portu na komunikację z wyświetlaczem.
  • #11 20525698
    marekms1
    Poziom 13  
    Potrzebuję przepisywać zawartość tabeli do portu wyj. z częstotliwością od 0Hz lub bliskiej 0Hz do 16kHz i przy prescalerze 64 źle wychodzą mi założone częstotliwości, ale to jest problemem drugorzędnym, bardziej interesuje mnie dokładność w ustawieniu portu wyj. czyli że wartości z tabeli będą się pojawiać na wyjściu po założonym odcinku czasu pomiędzy wynikami i koniecznie kolejno.
    Co do lcd w ATMEGA 2560 dodatkowe 4piny to nie problem. Zastanawiam się czy AVR da radę, ponieważ potrzebuję jeszcze kilku funkcji.

    Marek
  • #12 20525873
    ZbeeGin
    Poziom 39  
    Jeśli chcesz uzyskać takie szybkie przedziały czasowe to proponuję popędzić licznik TIMER1 bez preskalera i ustawić go w tryb CTC by sam się przeładowywał. W przypadku gdy zliczy 1000 impulsów to przerwania właśnie będą generowane z częstotliwością 16kHz (To daje jakieś 400 instrukcji maszynowych możliwych do wykonania między przerwaniami). Niestety bliskiego 0Hz nie uzyskasz w ten sposób, bo licznik nawet liczący swój pełny zakres da co najwyżej 244,14Hz.
    Najniższe częstotliwości musiałbyś ogarnąć nieco inaczej lub zrobić sobie przedziały częstotliwości gdzie zmieniałbyś dynamicznie stopień podziału preskalera.
  • #13 20525948
    marekms1
    Poziom 13  
    Timer to nie główny problem, kłopot mam z pętlą główną która nie nadążą czytać zawartość z tabeli aby po zliczeniu określonej ilości przerwań ustawić port.


    Marek
  • Pomocny post
    #14 20526061
    bart-projects
    Poziom 29  
    Kolego patrzę na ten kod ze zgrozą, ale załadowałem do swojego Bascoma i trochę więcej zrozumiałem bo mozna sprawdzać referencje i skakać po kodzie.

    W przerwaniu co osiem taktów (nierealne) timer ma zliczać te twoje "niby" OCR. (Incr Licz_timera1 : If Licz_timera1 >= Ooo Then)

    Te OCR jest ładowane z tabeli gdzie najmniejsza wartość to 127 a najwieksza 6666
    Timer może takie rzeczy liczyć sam jeśli tylko najwiekszą wartością byłoby 65535 czyli jego pojemność.
    To jest uproszczony przykład. Przy 127x8(prescaler)=1016 masz przy największej predkości jeszcze ponad tysiac taktów zapasu na inne sprawy.
    Rozumem że to 16MHz/1016=15748 ma dać te 16kHz :D

    Kod: VB.net
    Zaloguj się, aby zobaczyć kod


    AVR spokojnie sobie da radę jak mu porządny soft napiszesz. Mam projekt gdzie generuję sinusoidę od 50Hz do 1500Hz ładując w przerwaniu jednego timera PWM drugiego. Mam też projekt gdzie generuję trzy sinusoigy 50Hz przesuniete w fazie o 120stopni. Naprawdę się da.
  • #15 20526093
    marekms1
    Poziom 13  
    Tak jak napisałem wcześniej jestem początkujący w dziedzinie programowania więc szukam porad na forum.

    Marek
  • #16 20527792
    marekms1
    Poziom 13  
    Nareszcie działa.
    Marek
  • #18 20528703
    marekms1
    Poziom 13  
    Działa cały program. Tak jak pisałem wcześniej problem polegał na tym że program w pętli głównej nie nadążał z odczytem zawartości tabeli danych. W symulatorze działał, nie miałem żadnych skoków przysłowiowe maliny ale na płytce już nie. Myślałem że jest problemem jest program w pętli głównej a konkretnie odczyt danych przez LOOKUP a okazało się że procesor zajmował się zbyt często wywoływaną obsługą przerwania od TIMER1 i nie miał już czasu na pętlę DO LOOP. Po zastosowaniu poprawki od forumowicza Bart-projects dane pojawiają się we właściwej kolejności i czasie.
    Bardzo dziękuję koledze Bart-projects za pomoc.
    Wychodzi brak wiedzy i doświadczenia w pisaniu programów.

    Marek

Podsumowanie tematu

Użytkownik starał się skonfigurować dwa timery w BASCOM dla mikrokontrolera ATmega2560, aby pobierać dane z tablicy i sterować PORTB. Timer0 miał co 0,5 sekundy aktualizować prędkość działania Timer2, jednak wystąpiły problemy z synchronizacją i działaniem obu timerów jednocześnie. W trakcie dyskusji poruszono kwestie dotyczące błędów w kodzie, takich jak nieprawidłowe użycie instrukcji GOTO oraz problemy z obsługą przerwań. Użytkownik poprawił program, eliminując GOTO, ale nadal miał trudności z odczytem danych z tabeli w odpowiednim czasie. Ostatecznie, po zastosowaniu poprawek, program zaczął działać poprawnie, a dane były odczytywane w odpowiedniej kolejności i czasie.
Podsumowanie wygenerowane przez model językowy.
REKLAMA