Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

STM32 - Przerwanie zewnętrzne

kornik280 20 Apr 2014 11:18 2829 18
  • #1
    kornik280
    Level 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?
    Code: cpp
    Log in, to see the code
  • #2
    el2010tmp
    Level 25  
    kornik280 wrote:
    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 wrote:
    void EXTI0_IRQHandler(void)

    na:
    void EXTI9_5_IRQHandler(void)

    kornik280 wrote:
    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.
  • #3
    kornik280
    Level 18  
    Model procesora to STM32F103RB
    Dokonałem zmian:
    Code: cpp
    Log in, to see the code


    Teraz dioda na PA10 zapala się od razu po starcie programu pomimo że pin PA9 jest podciągnięty do 3,3V
  • #4
    mi14chal
    Level 28  
    A co robi w kodzie takie coś? Nawet masz komentarz napisany.
    Code: c
    Log in, to see the code
  • #5
    kornik280
    Level 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ę?
  • #6
    el2010tmp
    Level 25  
    kornik280 wrote:
    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
  • #7
    kornik280
    Level 18  
    Dobrze, problem rozwiązany

    1.Mam pytanie do SysTick:
    Code: cpp
    Log in, to see the code

    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?
  • #8
    el2010tmp
    Level 25  
    kornik280 wrote:
    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.
  • #9
    kornik280
    Level 18  
    Jeśli tam jest while(1) to się zawiesi dlaczego ma się zawieszać?
  • #10
    el2010tmp
    Level 25  
    kornik280 wrote:
    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:
    Code: c
    Log in, to see the code

    daj:
    Code: c
    Log in, to see the code

    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.
  • #11
    habrat
    Level 10  
    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.
    Code: cpp
    Log in, to see the code
  • #12
    szczywronek
    Level 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:
    Code: c
    Log in, to see the code

    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
  • #13
    habrat
    Level 10  
    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!!!
  • #14
    mwtyczek
    Level 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.

    Code: cpp
    Log in, to see the code

    konifguracja przerwań
    Code: cpp
    Log in, to see the code


    "Trefne" przerwanie:
    Code: cpp
    Log in, to see the code


    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:)
  • #16
    mwtyczek
    Level 10  
    ^ Fakt, niedopatrzenie... dziękuję za uwagę :) przerwanie jednak nadal nie wykonuje tego, co zaplanowałem. Jakieś inne pomysły ?
  • #18
    BlueDraco
    MCUs specialist
    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ę.
  • #19
    mwtyczek
    Level 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.