Skocz do zawartości

[STM32] Obsługa przerwań zewnętrznych


hagop

Pomocna odpowiedź

Witam

STM32F746-Disco

Kombinuję z przerwaniami zewnętrznymi i nie mogę sobie z tym poradzić. Program zatrzymuje mi się w pętli while();

W debuger wchodzi mi do pętli while() i na tym koniec (nie reaguje na naciśnięcie przycisku). Co zrobiłem źle?

int main(void){

RCC->AHB1ENR |= RCC_AHB1ENR_GPIOIEN;		//Włączenie zegara dla GPIO
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;		//Włączenie zegara dla SYSCFG

gpio_pin_cfg(GPIOI, PI1, gpio_mode_output_PP_LS);		//Konfiguracja pinu diody PI1
gpio_pin_cfg(GPIOI, PI11, gpio_mode_in_floating);		//Konfiguracja pinu przyciku PI11

/*
  Konfiguracja przerwania zewnętrznego od pinu
  EXTICR[x] gdzie x
	0 dla linii 0-3 (Rejestr EXTICR1)
	1 dla linii 4-7 (Rejestr EXTICR2)
	2 dla linii 8-11 (Rejestr EXTICR3)
	3 dla linii 12-15 (Rejestr EXTICR4)

*/
SYSCFG->EXTICR[2] = SYSCFG_EXTICR3_EXTI11_PI;		//Ustawiam przerwanie od przycisku EXTUCR[2] (EXTICR3) ponieważ pin przycisku to 11
EXTI->RTSR = EXTI_FTSR_TR11;						//Wywołanie przerwania zboczem narastającym
EXTI->IMR = EXTI_IMR_MR11;							//Zezwolenie na przerwania od pinu 11

NVIC_EnableIRQ(EXTI3_IRQn);							//Włączenie przerwań od EXTI3
GPIOI->ODR |= GPIO_ODR_ODR_1;

while(1){

}

}

void EXTI3_IRQHandler(void) {
if ( EXTI->PR & EXTI_PR_PR11) {
	EXTI->PR = ~EXTI_PR_PR11;
	GPIOI->ODR ^= GPIO_ODR_ODR_1;
}
}

Schemat podłączenia przycisku:

Link do komentarza
Share on other sites

Cześć!

Widzę, że mamy podobny problem dlatego pozwolę sobie wrzucić tutaj również mój kod do przeanalizowania to może ktoś połapie wątki i wychwyci o co tu chodzi i pomoże nam obu. Próbuję wywołać przerwanie zewnętrzne przy pomocy przycisku znajdującego się na płytce NUCLEO F446RE ale tak jak u kolegi nie ma reakcji...

#include "stm32f4xx.h"
#include "stm32f4xx_exti.h"
#include "stm32f4xx_syscfg.h"
#include "misc.h"

void Configure_LED(){
/*Set variables used*/
GPIO_InitTypeDef gpio; 	
/*Enable clock for GPIOA*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
/*Set pin as output*/
GPIO_StructInit(&gpio); 
gpio.GPIO_Pin = GPIO_Pin_5; 
gpio.GPIO_Mode = GPIO_Mode_OUT; 
gpio.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA, &gpio); 
}

void Configure_PC13(void) {
   /* Set variables used */
   GPIO_InitTypeDef GPIO_InitStruct;
   EXTI_InitTypeDef EXTI_InitStruct;
   NVIC_InitTypeDef NVIC_InitStruct;
   /* Enable clock for GPIOC */
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
   /* Enable clock for SYSCFG */
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
   /* Set pin as input */
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
   GPIO_Init(GPIOC, &GPIO_InitStruct);

   /* Tell system that you will use PC13 for EXTI_Line13 */
   SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource13);

   /* PC13 is connected to EXTI_Line13 */
   EXTI_InitStruct.EXTI_Line = EXTI_Line13;
   /* Enable interrupt */
   EXTI_InitStruct.EXTI_LineCmd = ENABLE;
   /* Interrupt mode */
   EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
   /* Triggers on rising and falling edge */
   EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
   /* Add to EXTI */
   EXTI_Init(&EXTI_InitStruct);

   /* Add IRQ vector to NVIC */
   /* PC13 is connected to EXTI_Line13, which has EXTI15_10_IRQn vector */
   NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
   /* Set priority */
   NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
   /* Set sub priority */
   NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01;
   /* Enable interrupt */
   NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
   /* Add to NVIC */
   NVIC_Init(&NVIC_InitStruct);
}
/* Set interrupt handlers */
/* Handle PC13 interrupt */
void EXTI15_10_IRQHandler(void) {
   /* Make sure that interrupt flag is set */
   if (EXTI_GetITStatus(EXTI_Line13) != RESET) {
       /* Do your stuff when PC13 is changed */    	
   	GPIO_ResetBits(GPIOA, GPIO_Pin_5); // turn LED off
       /* Clear interrupt flag */
       EXTI_ClearITPendingBit(EXTI_Line13);
   }
}

int main(void) {
   /* System init */
   SystemInit();
   /*Configure LED on PA5*/
   Configure_LED();
   /* Configure PC13 as interrupt */
   Configure_PC13();
   GPIO_SetBits(GPIOA, GPIO_Pin_5); // turn LED on

   while (1) {
   }
}
Link do komentarza
Share on other sites

Twój kod jest zupełnie poprawny. Uruchomiłem go na Nucleo bez żadnych modyfikacji i działał poprawnie. Dioda się włączyła a przycisk ją wyłączył. Może coś było nie tak z kodem startowym.

Wątek stary, ale wyskoczył mi w Google i pewnie więcej osób też na niego natrafia. Dlatego potwierdzam, że kod jest OK 🙂

Co do pierwszego kodu, to nie mam niestety STM32F746-Disco, a tak na sucho wydaje się być w porządku.

  • Lubię! 1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.