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

atmega8535 - ADC w trybie ciągłym, przerwania działają tylko raz po starcie

prociomen007 07 Lis 2013 12:08 1581 8
  • #1 12924879
    prociomen007
    Poziom 18  
    No i znowu natknąłem się na jakiś dziwaczny problem. Próbuje uruchomić konwersję ADC w trybie ciągłym z obsługą przerwań. Czyli zawsze po zakończonej konwersji powinna nastąpić obsługa przerwania. Niestety, procedura obsługi przerwania nie wiedzieć czemu występuje tylko raz po podłączeniu procesora do prądu.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    No i niestety zmienna dane nie zmienia swojej wartości podczas zmian napięcia na wejściu przetwornika ADC. Funkcja wykonuje się tylko raz na starcie kodu i potem jest głucho.
  • #2 12924938
    dondu
    Moderator na urlopie...
    prociomen007 napisał:
    No i znowu natknąłem się na jakiś dziwaczny problem.

    No i niestety zmienna dane nie zmienia swojej wartości podczas zmian napięcia na wejściu przetwornika ADC.

    Pokaż cały program, a w szczególności jak definiujesz zmienną dana.
    Użyłeś magicznego słowa volatile?: http://mikrokontrolery.blogspot.com/2011/04/problemy-c-volatile.html

    prociomen007 napisał:
    Funkcja wykonuje się tylko raz na starcie kodu ...

    Na jakiej podstawie ten wniosek?
  • #3 12924979
    prociomen007
    Poziom 18  
    Kod aktualnie jest taki:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Kiedy układ podłączam do prądu wszystko się ładnie wzbudza i na oscylu mam przebieg z generatora PMW. Niestety zmiany napięcia na wejściu ADC nie przynoszą skutku w postaci zmiany długości impulsu. ( Kiedy te wartości zmieniam programowo 'ręcznie wszystko działa ). Kiedy wyłączę układ i następnie zmienię wartość napięcia na adc a potem podłącze go ponownie to wartość zostaje odczytana i długość impulsu ustawia się prawidłowo. Nie mogę niestety podczas działania programu jej zmieniać. Wygląda to zupełnie tak jak by procedura od przerwań nie była uruchamiana.
  • #4 12925040
    mi14chal
    Poziom 28  
    Bo zmienne które używasz w przerwaniu muszą być typu volatile inaczej nie będzie działać.
  • #5 12925106
    prociomen007
    Poziom 18  
    To nie pomaga. Wygląda to tak jak by przerwanie w ogółe nie było wywoływane. Tylko raz na początku programy.
  • #6 12925166
    dondu
    Moderator na urlopie...
    Wróć do swojego programu z pierwszego postu:
    - wyrzuć funkcję timer_on().
    - zostaw tylko main() z ustawieniami ADC i przerwań, oraz funkcję ISR(),
    - w ISR zmieniaj stan wybranego wyjścia, do którego podłączysz diodę LED na przeciwny.
    - ustaw tak F_CPU i preskaler ADC, by móc spokojnie zaobserwować diodę no chyba, że masz oscyloskop.

    Dopiero na tej podstawie będziesz mógł stwierdzić stanowczo, że przerwanie wykonuje się tylko raz, albo wcale.

    Napisz o rezultatach pokazując swój program.
  • #7 12925187
    Konto nie istnieje
    Poziom 1  
  • #8 12925284
    prociomen007
    Poziom 18  
    No więc zgodnie z radą taki mam kod:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Prościej się nie da. No i skutkuje to tym że wyjścia na porcie C mam w stanie wysokim wyłącznie ( testowane na oscyloskopie ). Zmiana napięcia na wejściu adc nie przynosi kompletnie żadnego rezultatu. A skoro wyjścia są w stanie wysokim to oznacza to że przerwanie zostało raz wykonane. Co ciekawe jeśli do pętli while(1) wrzucę zapis ADCSRA |= (1<<ADSC); który wymusza pojedyncza konwersję to przerwania zgłaszane są prawidłowo.
  • #9 12925411
    dondu
    Moderator na urlopie...
    Jeśli dobrze sprawdziłem dokumentację, to przy takim programie powinieneś mieć falę prostokątną na pinach portu C, ponieważ bity ADTS2-0, są domyślnie ustawione w SFIOR na Free Running, co na pewno wziąłeś pod uwagę. Chyba, że coś pominąłem, a co jest specyficzne dla tego uC.

    Hmm, jaką masz włączoną optymalizację?
    Wklej zawartość pliku .lss
REKLAMA