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

[Attiny2313][c]Szybkie przenoszenie danych poza przerwanie

smajlas 01 Maj 2011 19:33 2099 18
REKLAMA
  • #1 9458608
    smajlas
    Poziom 12  
    Witam
    Próbuję napisać obsługę pilota, który używa kodowania NEC. Następnie chcę przesłać kod na okno terminala za pomocą USART.
    Próbuję to realizować bez użycia funkcji typu delay_ms(), zamiast tego chcę użyć przerwań.
    Idea jest taka, że po pojawieniu się pierwszego zbocza od odbiornika podczerwieni, wywoływane jest przerwanie, uruchamiany jest timer1, liczy aż do pojawienia się następnego przerwania. Wtedy odczytywana jest wartość timera, sprawdzam, czy jest w przedziale czasowym pasującym do 1-ki, jak tak to przesuwam jedynkę w zmiennej value w lewo. W zależności od zmiennej licznikowej k.
    Kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Problem jest taki, że zmienna value się nie zmienia, za to na terminalu, po każdym naciśnięciu klawisza na pilocie otrzymuję dwukrotnie napis:
    "Test
    wysylania - odbioru"
    Przyciśnięcie klawisza "a" powoduje pokazanie na terminalu:
    "a2" <-- to jest zrozumiałe, ale value, pomimo zdefiniowania jako volatile nie zmienia wartości w przerwaniu.
    Proszę o wskazówki, jak poprawić.
  • REKLAMA
  • Pomocny post
    #2 9458731
    michalko12
    Specjalista - Mikrokontrolery
    Wskazówka:

    Pomyśl jakie są konsekwencje tej linii:


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #3 9463076
    smajlas
    Poziom 12  
    Hmmm... zezwalam na wywołanie przerwania przy przepełnieniu Timer1. A obsługi przerwania nie ma. (Co się wtedy stanie?). Tylko, czy w przypadku NIEustawienia TIMSK TC1 będzie zliczał nadal?
    Zaraz sprawdzam, dziękuję za pierwszą wskazówkę.
  • #4 9463094
    excray
    Poziom 41  
    smajlas napisał:
    Hmmm... zezwalam na wywołanie przerwania przy przepełnieniu Timer1. A obsługi przerwania nie ma. (Co się wtedy stanie?)...

    Procesor pójdzie dalej i trafi na wywołanie kolejnego w liście przerwania i je wykona albo jeśli nie masz innych przerwań to będzie lecieć dalej aż trafi na jakiś kod.
    smajlas napisał:
    ...Tylko, czy w przypadku NIEustawienia TIMSK TC1 będzie zliczał nadal?

    Oczywiście. Co ma TIMSK do zliczania? Nic. TIMSK to tylko zezwolenia na poszczególne przerwania.
  • REKLAMA
  • #5 9463163
    smajlas
    Poziom 12  
    Sprawdziłem. Działa jak trzeba, nie wywala "dodatkowych napisów". Dzięki wielkie.
    Ale: teraz, dopóki nie przycisnę "a", na ekranie terminala nie pojawia się nic.
    Co zrobić, żeby po odebraniu 32-go bitu na ekranie terminala pojawiła się zawartość zmiennej value? Spróbować coś wrzucić do bufora w przerwaniu? Jakiś sposób to jest, ale wydaje mi się mało estetyczny...
  • #7 9463234
    smajlas
    Poziom 12  
    dondu:
    Tak, wyjaśnienie znajduje się w komentarzu.
    A działa tak:
    1 zbocze, a==1 więc wykonuje się wszystko co w klamrach, przypisanie a=0,
    2 zbocze, a==0, zmiana a na 1 i nic więcej się nie dzieje
    3 zbocze, a==1, to co w klamrach itede...

    Jest lepszy sposób, ale wymagana jest ingerencja w hardware. Muszę przenieść czujnik podczerwieni na PIN INT0, i tam można sobie zdefiniować na jakie zbocze chcemy reagować, czy to chciałeś zasugerować?
    A może jakieś inne sprytne wyjście?
    Chętnie posłucham.
  • REKLAMA
  • #8 9463258
    dondu
    Moderator na urlopie...
    Chciałem się tylko upewnić, że tak ma działać.

    Oczywiście warto wykorzystywać wejścia INT z reakcją na zbocze.
    Jeżeli masz taką możliwość to jak najbardziej wykorzystaj.
    Ja zawsze staram się zrzucić maks ilość pracy na dostępne sprzętowe możliwości.
  • #9 9463349
    smajlas
    Poziom 12  
    dondu: Słuszna uwaga, zaraz się tym zajmę.

    Mam następny problem:
    Odnoszę wrażenie, że modyfikacja zmiennej value zajmuje zbyt dużo czasu i niektóre "jedynki" są pomijane (tzn niewykryte). Stwierdzam to po obejrzeniu przebiegów z diody podpiętej do PD3 i przebiegu z czujnika IR.
    Wiem, że mogę zmienić taktowanie mikroprocesora na szybsze (teraz mam 1MHz), to pewnie załatwi problem, ale czy jest jakaś inna możliwość? (Jezu, już wiem, pewnie... wskaźniki, brr)
  • REKLAMA
  • #10 9463697
    excray
    Poziom 41  
    Tak. Optymalizacja kodu źródłowego. Powiem Ci że ja robiłem kiedyś odbiornik do takiego samego pilota i kod źródłowy zawarł się w kilkunastu linijkach a to był na dodatek assembler. Więc musisz przemyśleć i zmodyfikować pod kątem szybkości swój kod.
  • #11 9463907
    janbernat
    Poziom 38  
    Masz opóźnienia- tyko ich na pierwszy rzut oka nie widać.
    Obsługa USART- czekasz w pętli while aż coś się pojawi w buforze UCSRA.
    A można to też zrobić w przerwaniu- po ustawieniu bitu RXCIE w UCSRB.
    Podobnie przy nadawaniu.
    Bo przy takiej obsłudze USART jak masz zwiększenie częstotliwości zegara pewnie nic nie da.
    Raczej szybkość transmisji może mieć wpływ.
    No i ew. bufor cykliczny.
    Druga sprawa- czas obsługi przerwania powinien być jak najkrótszy.
    W przerwaniu należy ustawić tylko flagę- sprawdzać w głównej pętli czy ustawiona- jak tak to obsłużyć i wykasować jak nie to pominąć.
    Co do wskaźników- do wszystkiego można się przyzwyczaić- jak powiedział skazaniec idący na szubienicę.
    P.S.
    byłbym zapomniał:
    http://atnel.pl/wydawnictwo
  • #13 9464001
    janbernat
    Poziom 38  
    Warto- nic lepszego nie ma.
    Chociaż- mało.
    Ma podobno być następny tom.
    A poza tym w tym miesiącu ma się ukazać książka kol. tmf w wyd. Helion.
    Czekam niecierpliwie.
  • #14 9464860
    smajlas
    Poziom 12  
    janbernat:
    Kiedy obsługa USART znajdowała się w przerwaniu, to rzeczywiście, nic nie działało jak trzeba. Dlatego przeniosłem ją do pętli głównej, tam nic nie psuje.
    Pytałem o możliwość szybszej modyfikacji zmiennej value. Jeśli pozbędę się linii
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    to wszystkie stany zostają dobrze wykryte.
    Poniżej dwa zdjęcia z oscyloskopu. Każda zmiana stanu to wykryta jedynka (patrz listing, track 1 to przebieg z sondy podłączonej do PD3)
    Z linią value|=0x01<<(k-2); (pominięte niektóre jedynki)
    [Attiny2313][c]Szybkie przenoszenie danych poza przerwanie

    A teraz linia value|=0x01<<(k-2); usunięta:
    [Attiny2313][c]Szybkie przenoszenie danych poza przerwanie

    Wszystkie jedynki wykryte bezproblemowo.
    USART-em zajmę się później, na razie jest tutaj tylko w celach "diagnostyczno - dydaktycznych".
    ---
    Książkę właśnie zamówiłem :D
  • #15 9465460
    janbernat
    Poziom 38  
    Używałeś USART_RX_vect i było gorzej?
    Oczywiście wtedy nie czeka się na wypełnienie byfora odbiorczego- wystapienie przerwania oznacza że jest pełny.
    Na razie może zakomentuj obsługę UARTA.
    Jakbyś jeszcze podał ile us/div.
    No i jeszcze jedno- ale tu mogę być głęboko pomylony:
    dla k==2 przesuwamy 1 na pozycję zero.
    Dla k==34 przesuwamy o 32 pozycje w lewo.
    Z zerem- na pozycję 33.
    a long int ma 32.
  • #16 9466013
    smajlas
    Poziom 12  
    5ms/div
    USART_RX_vect nie używałem.
    Spróbuję zakomentować USART, zobaczę co się stanie, chociaż nie wydaje mi się, żeby to coś zmieniło. W działaniu programu transmisja na USART działa tylko:
    1. na początku programu, do wyswietlenia Test - wysylania odbioru i
    2. kiedy nacisnę "a" - wyrzuca wtedy zawartość value w postaci dziesiętnej
  • #17 9466371
    janbernat
    Poziom 38  
    No dalej nie wiem ile jest us/div na oscyloskopie.
    Bo to aż nieprawdopodobne żeby jedna instrukcja podstawienia i przesunięcia bitów tyle czasu zajmowała żeby w czasie obsługi przerwania przychodziło następne.
    Większość instrukcji wykonuje się 1us przy tym zegarze.
    A ile to zajmie- 200-500us?
  • #18 9467693
    smajlas
    Poziom 12  
    Odpowiedź jest wyżej: 5ms/div

    Zrobiłem zgodnie z propozycją: zakomentowałem linie dotyczące USART.
    Wynik: USART zakomentowany, linia z przesuwaniem value "aktywna".
    [Attiny2313][c]Szybkie przenoszenie danych poza przerwanie
    Niektóre jedynki są pomijane.

    Nadal obstaję przy swoim, że modyfikowanie value w przerwaniu trwa zbyt długo, a USART nie ma tu wiele do rzeczy. Obiło mi się o uszy, że zmiana wartości zmiennych typu volatile może zająć trochę więcej czasu. Czy to prawda?

    I drugie pytanie: Jeżeli chciałbym zmodyfikować program tak, żeby skorzystać w tym miejscu z tablicy i wskaźników, to (w celu oszczędności miejsca) muszę użyć 32-elementowej tablicy typu char? Bo w zasadzie chcę gromadzić tylko zera i jedynki.
  • #19 9471535
    smajlas
    Poziom 12  
    Zmieniłem zegar i dostosowałem program do 4MHz.
    Modyfikacja zmiennej value przebiega jak trzeba, w przerwaniu nie "gubię" jedynek.
    Główny problem rozwiązany, chociaż trochę "siłowym" sposobem.
    Dziękuję wszystkim za pomoc.
REKLAMA