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.

STM32 - Przerwanie zewnętrzne

kornik280 20 Kwi 2014 11:18 2469 18
  • #1 20 Kwi 2014 11:18
    kornik280
    Poziom 18  

    Chciałbym wywołać przerwanie po naciśnięciu przycisku.Przycisk mam na porcie PA9, po naciśnięciu chciałbym zapalić diode na porcie pa10 niestety nie działa mi, co robie nie tak?

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0 18
  • #2 20 Kwi 2014 13:03
    el2010tmp
    Poziom 25  

    kornik280 napisał:
    NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;

    Deklarujesz przerwanie na pin0 a oczekujesz go na pin9. Ustaw przerwanie na pin9 albo podepnij przycisk po pin0. Jaki to procesor? Niektóre STM32 mają łączone sygnały przerwań np.: STM32f100 ma pin9 na EXTI9_5_IRQn oczywiście mósisz wówczas zmienić również nagłówek:
    kornik280 napisał:
    void EXTI0_IRQHandler(void)

    na:
    void EXTI9_5_IRQHandler(void)

    kornik280 napisał:
    if(EXTI_GetITStatus(EXTI_Line9) != RESET)
    {
    GPIO_SetBits(GPIOA, GPIO_Pin_10);
    EXTI_ClearITPendingBit(EXTI_Line9);
    }

    W jakim celu warunkujesz kasowanie flagi? Taki zapis jest pozbawiony sensu bo skoro przerwanie zostało wywołane to chyba należny skasować flagę [bezwarunkowo]. Chyba że to samo przerwanie może być wywoływane z wielu źródeł. Natomiast jeżeli używasz tylko jednego źródła to kasowanie flagi powinno być na początku bez żadnego warunku.

    0
  • #3 20 Kwi 2014 14:53
    kornik280
    Poziom 18  

    Model procesora to STM32F103RB
    Dokonałem zmian:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Teraz dioda na PA10 zapala się od razu po starcie programu pomimo że pin PA9 jest podciągnięty do 3,3V

    0
  • #4 20 Kwi 2014 15:05
    mi14chal
    Poziom 28  

    A co robi w kodzie takie coś? Nawet masz komentarz napisany.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #5 20 Kwi 2014 15:17
    kornik280
    Poziom 18  

    A co tu mam wpisac? Przecież, czekam na przerwanie na pinie 9?
    EDIT:
    Rozumie :D

    Tylko dalej to przerwanie nie działa jak sciągam pin PA9 do masy to dioda PA10 nie zapala się?

    0
  • #6 20 Kwi 2014 19:13
    el2010tmp
    Poziom 25  

    kornik280 napisał:
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; //wejscie z zewnetrznym rezystorem podcigajacym

    Masz podpięty zewnętrzny rezystor? Jeśli nie to napisz:
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;// wejście z rezystorem wewnętrznym Pull-Up

    0
  • #7 21 Kwi 2014 10:37
    kornik280
    Poziom 18  

    Dobrze, problem rozwiązany

    1.Mam pytanie do SysTick:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Po co jest tam pętla nieskończona?
    2.Pytanie dotyczy ADC, czy napięcie odniesienia W STM32 to jest napięcie zasilania 3,3V czy można doprowadzić zewnętrzne napięcie odniesienia tak jak w AVR np 2,048V?

    0
  • #8 21 Kwi 2014 10:51
    el2010tmp
    Poziom 25  

    kornik280 napisał:
    Po co jest tam pętla nieskończona?

    Jeżeli funkcja
    SysTick_Config(Sys_TickFrequancy/1000)
    zwróci wartość różną od zera [błąd] to program się zatrzyma.
    Ad2. Tak.

    0
  • #9 21 Kwi 2014 11:00
    kornik280
    Poziom 18  

    Jeśli tam jest while(1) to się zawiesi dlaczego ma się zawieszać?

    0
  • #10 21 Kwi 2014 12:36
    el2010tmp
    Poziom 25  

    kornik280 napisał:
    Jeśli tam jest while(1) to się zawiesi dlaczego ma się zawieszać?

    Program się zatrzyma tylko w przypadku wystąpienia błędu. Można wówczas przed while(1); dodać np. komunikat na wyświetlacz informujący o błędzie lub podjąć inne działania.
    Jeśli nie chcesz aby tak się działo to wówczas zamiast:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    daj:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    i program będzie działał nawet przy błędnej konfiguracji SysTick. Oczywiście wówczas program może działać niekoniecznie zgodnie z Twoimi założeniami.

    0
  • #11 01 Sie 2014 19:29
    habrat
    Poziom 9  

    witam, mam podobny problem, nie wiem co robię źle, chcę zapalić diodę podłączoną do PB0 za pomocą przerwania od przycisku podłączonego do PC7 lub 8.
    po wgraniu kodu przerwanie od SYSTICK ładnie działa, zapala i gasi na zmianę diodę na PB1, natomiast dioda na PB0 swieci się cały czas i nie ma żadnej reakcji na naciskanie przycisku....

    poniżej kod.

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0
  • #12 01 Sie 2014 20:47
    szczywronek
    Poziom 27  

    @habrat włączasz taktowanie AFIO?

    Dodano:
    Tak sobie myślę, że grono osób chętnych do analizowania Twojego kodu byłoby większe, gdyby był ładnie sformatowany i ogołocony ze wszystkiego co nie potrzebne, ale to Tobie powinno zależeć ;) Bo teraz to... szybciej można to napisać od zera:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    SysTick zapala diodę na PB0 co około 3s. Przerwanie z PB2 gasi diodę.

    Jeszcze luźne uwagi do Twojego kodu:
    - nie musisz zmieniać priorytetów przerwań
    - nie musisz nic robić z tablicą wektorów
    - ustawianie prędkości wejść nie ma sensu
    - flagę kasuj na początku procedury przerwania

    0
  • #13 02 Sie 2014 15:04
    habrat
    Poziom 9  

    Wiem wiem że nie ładnie wygląda, trochę się też poprzesuwały linie po skopiowaniu, ale nie miałem już czasu wczoraj poprawiać tego bo musiałem wyjść, ale faktycznie masz racje, następnym razem bardziej muszę się postarać! obiecuje;)

    Co do programu faktycznie brakowało włączenia traktowania AFIO, teraz na działającym mogę sobie już poeksperymentować jak i co na co wpływa zgodnie z Twoimi uwagami na koniec.
    Dzięki!!!

    0
  • #14 17 Sty 2015 22:49
    mwtyczek
    Poziom 9  

    Odkopuję temat, ponieważ mój problem również tyczy się przerwania od przycisku, przy użyciu tych nieszczęsnych bibliotek :)

    Wydaje mi się, że wszystko jest włączone i zainicjowane jak należy... Dokładnie przeszedłem przez UM, oraz posiłkowałem się tematami na 'stackoverflow'. Przerwanie następuje, ale trwałe, tzn wszystko się zatrzymuje migająca dioda nr 1 (LED_Pin_1), zatrzymuje się na aktualnym stanie po naciśnięciu przycisku. Reszta nie reaguje. Kodu do obsługi tej "reszty" nie zamieszczam.

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    konifguracja przerwań
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    "Trefne" przerwanie:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Czyli w skrócie, przerwanie powinno odwrócić stan diody nr 2 (LED_Pin_2), która jest zapalona cały czas. Dioda nr 1 gaśnie i zapala się co ok. pół sekundy. Na płytce uniwersalnej jest dioda (USER_Pin_1) dla dodatkowej sygnalizacji działania przycisku Button_Pin_1 (w tym przypadku). Konifguracji GPIO nie wrzucam - Diody push pullup, przyciski in floating. Obsługa BUTTON_Pin_1 (czyli ta bez przerwań) działa bez zarzutu.
    Jednak potrzebuję pokazać na wyświetlaczu id ramki CAN, która została odebrana/wysłana, dlatego chciałbym to realizować za pomocą przerwań.
    Proszę o jakieś sugestie:)

    0
  • #16 18 Sty 2015 15:23
    mwtyczek
    Poziom 9  

    ^ Fakt, niedopatrzenie... dziękuję za uwagę :) przerwanie jednak nadal nie wykonuje tego, co zaplanowałem. Jakieś inne pomysły ?

    0
  • #18 18 Sty 2015 17:08
    BlueDraco
    Specjalista - Mikrokontrolery

    Przyciski "floating" - czyli pryz zwolnionym przycisku mamy losowy stan wejścia z możliwymi oscylacjami. W dodatku używasz przerwań od przycisków, o których co tydzień tu piszę, że to nie jest dobry sposób na przyciski. Ignorowania drgań ani śladu w oprogramowaniu. To chyba nie ma prawa działać.

    Zacznij od przerwania timera - tam testuj stan przycisku i reaguj na zmianę.

    0
  • #19 18 Sty 2015 17:43
    mwtyczek
    Poziom 9  

    @szczywronek LCD_WriteText nie ma żadnych opóźnień od innych przerwań. Funkcja zawiera jedną instrukcję...która pośrednio odnosi się do jeszcze 3 innych funkcji.
    Jednak żadna z nich nie wykorzystuje przerwań.
    Tak, posiadam debugger. Działam na openocd+eclipse oraz startupie Freddiego.

    @BlueDraco Dziś podczas kolejnych nieudanych prób ten sam pomysł mi zaświtał, że lepiej będzie to podpiąć pod timer.

    0