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.

Atmega8 - Tym razem; przerwanie sprzętowe - nie działa

Michał 911 31 Mar 2013 21:20 3357 30
  • #1 31 Mar 2013 21:20
    Michał 911
    Poziom 18  

    Witam,

    Od jakiegoś czasu próbuję włączyć przerwanie sprzętowe w uC ATmega8, robie wszystko zgodnie z datasheetem i nie działa :|

    Kto mi powie co tu jest nie tak? ;

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0 29
  • #2 31 Mar 2013 21:33
    tadzik85
    Poziom 38  

    podpowiedz..."vol..."

    0
  • #3 31 Mar 2013 21:37
    KKK14
    Poziom 9  

    Jak zmienna używasz w przerwaniu i pętli głównej to musisz to zaznaczyć.
    "volatile int"

    0
  • #4 31 Mar 2013 21:44
    Michał 911
    Poziom 18  

    Ale nie tylko zmienna, a nawet samo ustawianie portu nie działa

    0
  • Pomocny post
    #5 31 Mar 2013 21:55
    excray
    Poziom 39  

    SIGNAL(SIG_OVERFLOW0) - w ten sposób definiowały obsługę przerwania jeszcze nasze babcie i jeszcze za ich czasów wprowadzono nowy sposób - ISR(TIMER0_OVF_vect)
    3-sekundowy delay w przerwaniu? "Super" pomysł.

    0
  • #6 31 Mar 2013 22:02
    Michał 911
    Poziom 18  

    Cytat:

    SIGNAL(SIG_OVERFLOW0) - w ten sposób definiowały wektor przerwania jeszcze nasze babcie i jeszcze za ich czasów wprowadzono nowy sposób - ISR...


    Aha, to sobie poszukam...

    Cytat:

    3-sekundowy delay w przerwaniu? "Super" pomysł.


    To taka desperacka próba zauważenia czegokolwiek (testowo) - teoretycznie powinien się ten port na stałe ustawić, ale tak się zastanawiałem, czy przerwanie może w jakiś sposób go nie przestawia, więc na wszelki wypadek dałem delay'a

    0
  • Pomocny post
    #7 31 Mar 2013 22:46
    Sparrowhawk
    Poziom 21  

    Wyrzuć te delay'e. Zmienną licznik jak radzili koledzy zmień na volatile. Zmień sei(); na SREG |= (1<<7);

    Jeśli będzie działać, to zapytam jakiej wersji avr studio używasz?

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0
  • #8 31 Mar 2013 23:26
    Michał 911
    Poziom 18  

    Działa!
    Przynajmniej tak ogólnie mogę to stwierdzić, bo sprawdzałem tylko tak na sztywno ustawianie jakiegoś portu w przerwaniu, jutro spróbuję z tym coś więcej zrobić.

    Cytat:
    Jeśli będzie działać, to zapytam jakiej wersji avr studio używasz?


    Używam AtmelStudio 6.0

    0
  • #9 01 Kwi 2013 09:41
    excray
    Poziom 39  

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Sparrowhawk napisał:
    Zmień sei(); na SREG |= (1<<7);
    To to samo więc jeśli została (a została) dołączona biblioteka interupt.h to nie ma różnicy.

    0
  • #10 01 Kwi 2013 10:03
    Sparrowhawk
    Poziom 21  

    Zerowanie TCNT0 jest zbędne ale też niczemu nie przeszkadza. Co do makra sei(). Testowałem ten kod w debugerze AVR Studio 6 i w nim to makro nic nie robiło. Nie wiem, czy kolega Michał testował ten program w układzie, czy też w debugerze tylko. W każdym razie zauważ, że u niego makro sei() również nie działało. Wczoraj trudno mi było znaleźć informacje na ten temat, ale spotkałem się z opinią, że w najnowszym AVR Studio są z tym makrem problemy.

    0
  • #11 01 Kwi 2013 10:44
    piotrva
    Moderator na urlopie...

    Ogólnie powiem z całym szacunkiem, że z najnowszym AVR Studio jest sporo problemów.
    Dla początkujących do nauki polecam AVRStudio 4.18 - tam w zakresie podstawowych kostek serii Tiny AVR i Mega AVR wszystko działa poprawnie. (Jedynie najmniejsze kostki Tiny10/9/5/4 są w wersji 4.18 obsługiwane nieprawidłowo, serii XMega nie testowałem szczegółowo w tym IDE).

    0
  • #12 01 Kwi 2013 17:21
    adam74m
    Poziom 11  

    A ja polecam Eclipse. Z sei() nie ma problemu. Poza tym działa i w Windows i Linux (u mnie na Ubuntu).

    0
  • #13 01 Kwi 2013 17:55
    excray
    Poziom 39  

    adam74m napisał:
    A ja polecam Eclipse. Z sei() nie ma problemu. Poza tym działa i w Windows i Linux (u mnie na Ubuntu).

    Symulator/debugger też działa?

    0
  • #14 02 Kwi 2013 11:49
    Michał 911
    Poziom 18  

    Kolej problem (myślę, że to też może być wina AS);

    pętla for(){} działa jak while(){}, czyli program wchodzi w for i nie wychodzi z niego dopóki warunek nie przestanie być spełniony

    Może po prostu coś źle robię, bo pierwszy raz używam przerwań sprzętowych.
    Pętla na której zatrzymuje się program wygląda tak;

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Aha i jeszcze jedno dziwne zachowanie for'a;
    jak mam takie coś (sekundnik dodaje się o 1 co każde przerwanie, zeruje jeśli jest większy od 36);
    Kod: c
    Zaloguj się, aby zobaczyć kod


    dalej takie coś;
    Kod: c
    Zaloguj się, aby zobaczyć kod


    i jeżeli w tych case'ach wpiszę że dioda ma się włączać jak sekundnik =1, a wyłączać jak jest = 7, potem znowu włączać jak jest = 22 i wyłączać jak jest 31, to włączy się tylko raz (między 22 a, 31)
    Czyżby ten for powyżej (od buzzera) coś robił z wartością sekundnik?



    Jeżeli z tego nic nie wynika, to tu na wszelki wypadek wstawiam cały kod;
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #15 02 Kwi 2013 12:10
    BlueDraco
    Specjalista - Mikrokontrolery

    Pętla for w C działa tak, jak while. Zapis for (a; b; c) to to samo co:
    a;
    while (b)
    {
    ...
    c;
    }

    Zdefiniuj jako stałe preprocesora numery bitów LED i przycisków i używaj ich w kodzie - te maski bitowe nie są czytelne, a ich zmiana wymaga edycji wielu linii kodu.

    0
  • #16 02 Kwi 2013 12:12
    Sparrowhawk
    Poziom 21  

    Co to za konstrukcja?

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Chyba powinno być:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0
  • #17 02 Kwi 2013 12:55
    excray
    Poziom 39  

    A ja dodam od siebie:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #18 02 Kwi 2013 12:56
    BlueDraco
    Specjalista - Mikrokontrolery

    Akurat nie, bo ++ jest w obsłudze przerwania. Dziwnawe rozwiązanie, ale jakoś tam działa.

    0
  • #19 02 Kwi 2013 14:20
    Michał 911
    Poziom 18  

    To jeżeli for'em nie da się tego zrobić, to jak coś takiego zrobić, żeby to;

    Kod: c
    Zaloguj się, aby zobaczyć kod

    wykonywało się przez określony czas (100 przerwań) i żeby nie zatrzymywało programu?

    0
  • #20 02 Kwi 2013 17:09
    BlueDraco
    Specjalista - Mikrokontrolery

    To może po kolei:
    1. Co chcesz uzyskać i jak w związku z tym chcesz zaprogramować timery?
    2. Jaka jest częstotliwość procesora i czy ją poprawie zdefiniowałeś?
    3. Nie uruchamiaj timera przed jego zaprogramowaniem - robisz to obecnie z oboma timerami.
    4. Popraw tę bzdurę:
    licznik = 0;
    for(licznik==0;licznik<100;)
    5. Wyrzuć ze swojego kodu przełączanie trybów pracy - najpierw uruchom jeden z nich.

    0
  • #21 02 Kwi 2013 18:03
    Michał 911
    Poziom 18  

    1. Układ wygląda tak;
    -jest 7 przełączników, 3 przyciski,
    -10 diod, które;
    *1-3, 5-7 mają po prostu gasnąć po przełączeniu hebla i na określony czas ustawiać PWM na konkretom wartość - przypisaną dla każdego przełącznika (tutaj PWM ma się ustawić tylko raz, a potem jak już dioda zgasła to ta linia ma być "nieczynna")
    *dioda 4 - od buzzera po przełączeniu hebla ma migać i co jakiś czas (co kilka przerwań) na jakiś czas ustawiać PWM na wartość przypisaną dla "tego przełącznika"
    *dioda 8 - stroboskopy, ta funkcja jest sterowana przyciskiem monostabilnym, ale w programie to zmieniłem, że działa jak bistabilny. Ta funkcja podobnie jak ta od buzzera ma co chwilę zmieniać wartość PWM (czyli np. jeżeli jest włączony buzzer i stroboskop to; ustaw PWM na 200, ustaw na 500, ustaw na 50-wartość domyślna i cały taki cykl trwa ok 1sek.), od buzzera różni ją jeszcze to, że mają być 2 mignięcia tej diody - przerwa, 2 mignięcia -przerwa ...
    *dioda 9,10 - światła - po wciśnięci przycisku monostabilnego diody mają się świecić cały czas, po ponownym wciśnięciu zostać wyłączone, kiedy są włączone PWM też musi się co chwilę zmieniać.

    Teraz właśnie tak to działa, ale jak przełączę przełącznik od diody 1-3, 5-7, to wtedy, program się na chwilę zatrzymuje - te diody co miały migać przestają migać, po upływie tego czasu (wyjściu z tej pętli for na której program się zatrzymuje) dalej wszystko działa normalnie

    2.

    Cytat:
    2. Jaka jest częstotliwość procesora i czy ją poprawie zdefiniowałeś?

    O co chodzi z tym ponownym zdefiniowaniem?
    Procesor jest taktowany na 8MHz na wewnętrznym rezonatorze.

    3.
    Cytat:
    3. Nie uruchamiaj timera przed jego zaprogramowaniem - robisz to obecnie z oboma timerami.

    Zaprogramowaniem, czy zdefiniowaniem?
    Czy o co chodzi?

    4.Pozmieniałem to we wszystkich for'ach, tylko nie w tym od buzzera, bo wtedy działa trochę inaczej (inaczej jak jest zmienione na sekundnik = 0; ); jak jest włączony stroboskop i włączę buzzer do dioda od stroboskopu przestaje migać (świeci się cały czas) i od buzzera też.

    5. To nawet nie wiedziałem, że mam to włączone. O który kawałek dokładnie chodzi?

    Tutaj wstawiam jeszcze raz trochę bardziej czytelny cały kod;
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wszystko pięknie działa oprócz;
    *w tym switch'u na dole ten PWM nie ustawia się na 800, albo ustawia i od razu spowrotem przestawia na domyślną wartość 50.
    *tego opóźnienia powstałego na for'ach

    0
  • #22 02 Kwi 2013 18:08
    dondu
    Moderator Mikrokontrolery Projektowanie

    Koledzy wyżej po raz kolejny zwracają Ci uwagę, ale Ty nadal nie widzisz błędu, więc porównaj:
    - operator przypisania
    - operator relacji
    a na końcu zaglądnij do pętli for.


    Michał 911 napisał:
    4.Pozmieniałem to we wszystkich for'ach, tylko nie w tym od buzzera, bo wtedy działa trochę inaczej (inaczej jak jest zmienione na sekundnik = 0; ); jak jest włączony stroboskop i włączę buzzer do dioda od stroboskopu przestaje migać (świeci się cały czas) i od buzzera też.

    Jak ma działać konkretnie ten fragment?

    0
  • #23 02 Kwi 2013 18:27
    Michał 911
    Poziom 18  

    Cytat:
    Koledzy wyżej po raz kolejny zwracają Ci uwagę, ale Ty nadal nie widzisz błędu, więc porównaj:
    - operator przypisania
    - operator relacji

    Tzn., wiem jak działa przyrównanie i przypisanie, ale myślałem, że w pętli for może to być inaczej.

    Cytat:

    Michał 911 napisał:
    4.Pozmieniałem to we wszystkich for'ach, tylko nie w tym od buzzera, bo wtedy działa trochę inaczej (inaczej jak jest zmienione na sekundnik = 0; ); jak jest włączony stroboskop i włączę buzzer do dioda od stroboskopu przestaje migać (świeci się cały czas) i od buzzera też.

    Jak ma działać konkretnie ten fragment?

    Otóż tak ma działać, że jak jest włączony buzzer (dioda miga) i stroboskop (2 mignięcia przerwa) i zostanie przełączony hebel np. od LED3, to wypełnienie PWM ma zostać zmienione na 300- LED3 gaśnie, tylko, że w międzyczasie jak ten PWM jest generowany (przez czas 100 przerwań) żeby diody od stroboskopu i buzzera nie przestawały migać, tylko migały swoim rytmem.

    Cytat:
    a na końcu zaglądnij do pętli for.

    Chyba właśnie mnie oświeciło, zaraz zobaczę, czy będzie działać.

    0
  • #24 02 Kwi 2013 19:08
    BlueDraco
    Specjalista - Mikrokontrolery

    W kodzie masz mnstwo bzdur. Przeanalizuj uwagi, które napisałem wcześniej. Są dość precyzyjne - po prostu czytaj i patrz w kod.
    W każdym obiegu pętli głównej ustawiasz OCR1A, ale oprócz tego w różnych instrukcjach warukowych zmieniasz tę wartość. Zmieniasz ją również wielokrotnie w tej nieszczęsnej pętli for - po co tyle razy?
    Ta pętla w ogóle jest dość bezsensowna, bo w kółko powtarzasz w niej to samo, a przecież w czasie jej wykonywania nie zmieni się ani stan diody, ani znacznika b.
    Sama struktura kodu jest taka, że wątpię, że to ma szansę działać zgodnie z założeniami, np. w kręcąc się w tej pętli for nic innego nie zrobisz.

    Nadmierne odstępy pionowe (puste linie) sprawiają, że kod trudniej się czyta.

    0
  • #25 02 Kwi 2013 19:36
    Michał 911
    Poziom 18  

    Dobra, z diodami już sobie poradziłem, ale takie nijakie to moje rozwiązanie, bo po prostu zamiast tych pętli for dałem switch i diody działją, ale teraz PWM nie działa przestawia się co każde przejście pętli. Jeden z if'ów;

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Tylko jak to zrobić, żeby za każdym przejściem pętli ten PWM się nie zmieniał?

    Cytat:
    W każdym obiegu pętli głównej ustawiasz OCR1A, ale oprócz tego w różnych instrukcjach warukowych zmieniasz tę wartość. Zmieniasz ją również wielokrotnie w tej nieszczęsnej pętli for - po co tyle razy?

    Aha, no faktycznie, czyli to ustawianie na wartość domyślną trzeba jakoś zmienić, np. że ustaw ją tylko, jeżeli, żadna funkcja nie jest włączona.

    Cytat:
    Ta pętla w ogóle jest dość bezsensowna, bo w kółko powtarzasz w niej to samo, a przecież w czasie jej wykonywania nie zmieni się ani stan diody, ani znacznika b.


    No tak, dlatego zastąpiłem to case'em ale teraz PWM w ogóle się zepsuł bo w ciągu 1 przejścia pętli zmienia się kilka razy, czyli bardzo szybko.

    0
  • #26 02 Kwi 2013 19:50
    BlueDraco
    Specjalista - Mikrokontrolery

    Pomyśl o zrobieniu wszystkeigo w przewaniu timera. Trudno coś dokładniej doradzić, bo Twoje opisy co do tego, co to ma robić, są strasznie mętne.

    0
  • #27 03 Kwi 2013 15:53
    Michał 911
    Poziom 18  

    Już by mi wszystko działało tak jak chcę, ale przerwanie nie generuje się co 32ms (tak jak powinno), tzn. generuje się co taki czas, ale jeżeli nie jest w pętli for, jeżeli wejdzie w jakąś pętlę for, to najpierw musi z niej wyjść i dopiero potem się generuje, czy to normalne zachowanie przerwania?

    Teraz zmieniłem tylko końcówkę kodu od LED8 w dół (ale nawszelki wypadek stawiam cały);

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #28 03 Kwi 2013 16:40
    stanleysts
    Poziom 27  

    Za dużo if-ów do czytania przełącznik zrób jako tablicę i pętla do tego.

    Przerwanie się wykonuje w zasadzie od razu (aktualna instrukcja się wykona a potem powinna iść obsługa przerwania) - tak mniej więcej bo to oczywiście zależy czy nie ma np. wywłaszczania przerwań, ale ogólnie żaden for ani inna pętla na to nie wpływa.

    Tak przy okazji to na jakiej podstawie stwierdzasz, że przerwanie generuje się później niż określony, założony czas?

    0
  • #29 03 Kwi 2013 17:03
    BlueDraco
    Specjalista - Mikrokontrolery

    Znów pokazujesz kod, w którym jest mnóstwo błędów. Jeśli modyfikujesz ten sam port w przerwaniu i poza nim, to na czas modyfikacji w pętli (co jest tutaj zresztą zbędne, bo wszystko powinno chodzić w przerwaniu) musisz blokować przerwania.

    0
  • Pomocny post
    #30 03 Kwi 2013 17:53
    DawwidW
    Poziom 15  

    Weź uporządkuj ten kod, bo aż boli jak się to czyta :?

    0