Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

STM32 - Przerwanie zewnętrzne

20 Kwi 2014 11:18 2658 18
  • 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
  • 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.
  • 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
  • Poziom 28  
    A co robi w kodzie takie coś? Nawet masz komentarz napisany.
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • 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ę?
  • 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
  • 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?
  • 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.
  • Poziom 18  
    Jeśli tam jest while(1) to się zawiesi dlaczego ma się zawieszać?
  • 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.
  • 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
  • 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
  • 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!!!
  • Poziom 10  
    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:)
  • Poziom 10  
    ^ Fakt, niedopatrzenie... dziękuję za uwagę :) przerwanie jednak nadal nie wykonuje tego, co zaplanowałem. Jakieś inne pomysły ?
  • 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ę.
  • Poziom 10  
    @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.