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

ATmega8/ADC/przerwanie - uC nie wchodzi w procedurę przerwania

kremir 20 Sty 2013 01:03 2196 8
REKLAMA
  • #1 11813704
    kremir
    Poziom 11  
    Witam,

    Tak jak w tytule mam dość dziwny problem. Napisałem sobie bardzo prosty program w którym chciałem zobaczyć jak działa ADC + sterowanie serwem modelarskim. Doświadczenia robię na płytce stykowej.
    Wygląda to tak że jeśli odczytuję rejestr ADCH w nieskończonej pętli programu (mam ustawiony tryb free running) to wszystko działa ok. Natomiast jeśli chcę odczytać ten rejestr w procedurze przerwania, to nic się nie dzieje. Ustawiłem sobie dla celów diagnostycznych zaświecenie diody LED jeśli program wejdzie w procedurę przerwania i oczywiście dioda się nie zaświeciła. Przejrzałem kilka razy datashit atmegi ale nie potrafię znaleźć błędu, stąd prośba o pomoc.
    Oto fragment kodu:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Do obsługi serwa wykorzystuję przerwanie CTC Timer2 więc ogólnie przerwania chodzą, jedynie ADC nie chce się uruchomić.
    Gdyby ktoś pytał dlaczego się uprałem skoro działa bez przerwania to odpowiadam - dlatego że chcę się nauczyć je uruchamiać.
  • REKLAMA
  • #2 11813825
    McMonster
    Poziom 32  
    Słowo kluczowe volatile. Poszukaj, łatwo znajdziesz, o co chodzi. Jak już podajesz kod, to cały kod poprawnie wstawiony w znaczniku syntax.
  • REKLAMA
  • #3 11814213
    kremir
    Poziom 11  
    Witam,
    W regulaminie znalazłem znacznik syntax
    Cytat:
    [syntax=<Język programowania z listy dostępnych>]Kod tu...[/syntax]

    więc tak wkleiłem kod ale się nie sformatował - nie wiem więc jak to zrobić poprawnie.
    A co do volatile to oczywiście zmienna wchodząca do procedury przerwania została zadeklarowana z tym słowem kluczowym.
    Problem jak widać z opis jest taki że uC nie wchodzi w ogóle w ISR(...) bo gdyby wszedł, dioda by to zasygnalizowała (na stałe by się świeciła).
  • #4 11814288
    mi14chal
    Poziom 28  
    Ta linijka: ADCSRA |= 1 << ADSC; powinna być po sei(); i potem w przerwaniu znów zapomniałeś dodać na końcu linijki ADCSRA |= 1 << ADSC;
  • REKLAMA
  • #5 11814427
    kremir
    Poziom 11  
    O ile wiem ta kolejność (sei() i ustawienie bitu startującego) nie ma znaczenia, jak również w samej procedurze przerwania nie trzeba za każdym razem ustawiać bitu startującego jeśli używam "free running mode".
    Żeby jednak nie bić niepotrzebnie piany :D , zrobiłem proponowane zmiany i nadal nie wchodzi mi w procedurę przerwania - dioda się nie świeci a serwo milczy.
  • REKLAMA
  • #6 11814682
    BlueDraco
    Specjalista - Mikrokontrolery
    Czy to, co pokazałeś, to jest cały kod? Jeśli tak - po czym poznajesz, że działa / nie działa?

    Obsługa przerwania ADC w trybie ciągłej konwersji ma mały sens, bo przerwanie jet zgłaszane zbyt często, zresztą w ogóle w praktyce mało jest przypadków, gdy należy używać przerwania ADC - zwykle łatwiej i sensowniej zrobić pomiary w przerwaniu timera.
  • #7 11814747
    kremir
    Poziom 11  
    Nie to nie jest cały kod. Mam problem z wklejeniem z tagami syntax, ale spróbuję to jeszcze zrobić.
    W moim przypadku, to że przerwanie będzie generowane zbyt często nie ma praktycznie znaczenia bo korzystam z jednego kanału i nie muszę się martwić o gubienie pomiarów czy jakieś błędy. Ten programik jest tylko dla celów nauki.
    W obsłudze przerwania ustawiłem zaświecenie diody LED lecz nic się z nią nie dzieje. Druga sprawa, to odczyty nawet tak częste działają, jeśli nie korzystam z przerwania tylko odczytuję wartość z ADC w pętli głównej programu. Wówczas działa skręcenie serwem przy użyciu potencjometru.

    Oto cały kod:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #8 11815446
    BlueDraco
    Specjalista - Mikrokontrolery
    Chwila. Timer bez preskalera, częstotliwość procesora nieznana, załóżmy, że 1 MHz (nieistotne). Timer zgłasza przerwanie co 21 cykli zegara, czyli ATmega zajmuje się na okrągło obsługą przerwań timera, nie mając szans obsłużyć żadnych przerwań o niższym priorytecie (ADC).
  • #9 11815831
    kremir
    Poziom 11  
    BlueDraco napisał:
    Chwila. Timer bez preskalera, częstotliwość procesora nieznana, załóżmy, że 1 MHz (nieistotne). Timer zgłasza przerwanie co 21 cykli zegara, czyli ATmega zajmuje się na okrągło obsługą przerwań timera, nie mając szans obsłużyć żadnych przerwań o niższym priorytecie (ADC).


    Tak, timer był ustawiony na 1 MHz (było to wpisane w komentarzu prescalera dla timer2). Po przestawieniu taktowania na 8MHz i odpowiednim przeskalowaniu liczników, zięki temu że obsługa przerwania timera zajęła mniej taktów, program wszedł w obsługę przerwania ADC !!!

    BlueDraco - bardzo Ci dziękuję. Problem rozwiązany.
REKLAMA