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.

Atmega 8 - Przekazywanie wartości zmiennych z przerwania do programu

krzysztofh 31 Sie 2012 12:12 1632 4
  • #1 31 Sie 2012 12:12
    krzysztofh
    Poziom 29  

    Jestem w trakcie pisania programu na Atmegę8.
    Mam zdefiniowane trzy przerwania:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Obecnie pierwsze przerwanie INT0 jest nieaktywne.
    Początkowo chciałem w przerwaniu timera sprawdzać stan jednego z portów C i w zależności od jego stanu ustawiać wartość flagi 0/1 w programie głównym.
    I tu ciekawa sprawa. Jeżeli port był w stanie niskim, to przy każdym wywołaniu przerwania na tym porcie pojawiał się na krótko wysoki stan, co widziałem na oscyloskopie jako krótki pik. Nie mam pojęcia dlaczego tak się działo (chętnie bym się dowiedział dlaczego).
    Było to działanie niepożądane i poradziłem sobie z tym tak, że w programie głównym w zależności od stanu tego portu definiowałem zmienną volatile uint8_t enable_flag, której wartość sprawdzałem w przerwaniu. Obecnie już na tym porcie jest OK.

    Ale mam inny problem.
    Chciałbym przekazywać wartość zmiennej pomiar do programu głównego w czasie kiedy program jest uwięziony w pętli while (w czasie naciśnięcia przycisku).
    Kiedy zwalniam przycisk wartość zmiennej pomiar jest uwzględniana w programie głównym i jest OK, ale nie wiem czy można spowodować aktualizację tej zmiennej do programu który jest uwięziony w pętli. W tym czasie w pętli jest tylko deklarowana wartość innego portu jako 1 lub 0.
    Zastanawiam się nad tym jak to zrobić bo w czasie kiedy program jest uwięziony, przerwania muszą się wykonywać co widzę na oscyloskopie w postaci przebiegu na porcie PC4. Sądzę że także jest odczytywana wartość napięcia przez przetwornik, tylko jak ją przekazać do programu głównego?

    0 4
  • #2 31 Sie 2012 12:40
    stanleysts
    Poziom 27  

    Przecież jak zadeklarujesz sobie zmienną pomiar jako zmienną globalną ulotną (volatile), to zawsze będziesz miał jej aktualną wartość wszędzie i nie musisz jej przecież nigdzie wysyłać z przerwania (zresztą się nie da).

    0
  • #3 31 Sie 2012 13:41
    krzysztofh
    Poziom 29  

    Chodzi o to, że zmiana napięcia na PC0 jest właściwie odczytywana przez przetwornik i zapisywana do zmiennej pomiar.
    Od tej wartości zależy częstotliwość przerwania. Następuje zmiana deklaracji OCR1A.

    Idea jest taka, że zmieniając napięcie na wejściu PC0 chcę uzyskać zmianę częstotliwości przerwania ISR(TIMER1_COMPA_vect).
    Wszystko jest w porządku do czasu kiedy przyciskam przycisk, wywołując pętlę while.
    W czasie kiedy program jest w tej pętli, nie reaguje na zmianę wartości zmiennej pomiar.
    tu kawałek programu:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Uwolnienie programu z pętli powoduje aktualizację zmiennej pomiar i jest OK, a ja chciałbym móc mieć wpływ na częstotliwość przerwania w czasie kiedy trzymam przycisk wciśnięty czyli while(sw).

    0
  • Pomocny post
    #4 31 Sie 2012 14:54
    stanleysts
    Poziom 27  

    No to zrób tak, że zmieniaj OCR1A w pprzerwaniu od adc:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #5 31 Sie 2012 19:22
    krzysztofh
    Poziom 29  

    Pomysł wydaje się być dobry, ale nie do końca.
    Teraz reakcja na kręcenie potencjometrem jest widoczna na oscyloskopie w postaci zmiany częstotliwości, także podczas przytrzymywania przycisku, ale obecnie nie da się sterować klawiszami.
    Tzn, teoretycznie się da, ale czas reakcji od naciśnięcia przycisku sw na wykonanie instrukcji wewnątrz pętli trwa kilka sekund. Naciśnięcie przycisku wywołuje tylko zmianę stanu jednego z portów C, nie licząc czasu na opóźnienia mające wyeliminować drgania styków. I im większa częstotliwość (częściej wywoływane przerwanie) tym dłuższe są reakcje na przycisk.
    Dodam, tylko, że warunków else if w przerwaniu od ADC_vect jest osiem.
    Myślę że jest jakiś konflikt pomiędzy czasem pomiaru i obsługą obu przerwań.
    Zegar jest 1MHz, a prescaler dla przetwornika ADC 8.
    Zmiana wartości pomiar pozwala na zmianę częstotliwości przerwania od timera w zakresie od 23 Hz do 625 Hz, czyli przerwania są dwukrotnie częstsze (każde przerwanie zmienia stan portu, a tym samym wyznacza pół okresu.

    0