Skocz do zawartości

[C] [STM32] Nucleo z STM32F30xx - Przerwania zewnętrzne


kost

Pomocna odpowiedź

Witam Serdecznie,

Jestem w trakcie kursu STM32 i nie mogę przejść etapu z przerwaniami zewnętrznymi, posiadam płytkę STM32F303RE, wszystko wykonane zgodnie z kursem zmienione pod płytkę STM32F3.



#include "stm32f30x.h"


volatile uint32_t timer_ms = 0;

void SysTick_Handler()
{
if (timer_ms) {
	timer_ms--;
}
}

void delay_ms(int time)
{
timer_ms = time;
while (timer_ms) {};
}





void EXTI15_10_IRQHandler(void)
{

if (EXTI_GetITStatus(EXTI_Line13)) {
		if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13) == 0) { // jesli przycisk jest przycisniety
			GPIO_SetBits(GPIOA, GPIO_Pin_5); // zapal diode
		} else {
			GPIO_ResetBits(GPIOA, GPIO_Pin_5);
		}

		EXTI_ClearITPendingBit(EXTI_Line13);
	}


}

int main(void)
{

GPIO_InitTypeDef gpio;
EXTI_InitTypeDef exti;
NVIC_InitTypeDef nvic;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

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);

gpio.GPIO_Pin = GPIO_Pin_13;
gpio.GPIO_Mode = GPIO_Mode_IN;
gpio.GPIO_PuPd =  GPIO_PuPd_UP;
gpio.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOC, &gpio);

gpio.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
gpio.GPIO_Mode =  GPIO_Mode_OUT;
gpio.GPIO_OType =  GPIO_OType_PP;
GPIO_Init(GPIOC, &gpio);

SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource13);

EXTI_StructInit(&exti);
exti.EXTI_Line = EXTI_Line13;
exti.EXTI_Mode = EXTI_Mode_Interrupt;
exti.EXTI_Trigger = EXTI_Trigger_Falling;
exti.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti);

nvic.NVIC_IRQChannel = EXTI15_10_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority = 0;
nvic.NVIC_IRQChannelSubPriority = 0;
nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic);

uint32_t led = 0;

SysTick_Config(SystemCoreClock / 1000);

while (1) {
	GPIO_SetBits(GPIOC, 1 << led); // zapal diode
			delay_ms(150); // poczekaj
			GPIO_ResetBits(GPIOC, 1 << led); // zgas diode
			if (++led >= 10) { // przejdz do nastepnej
				led = 0;
			}

}
}

W pętlę while włożyłem kod z przesuwającą się diodą LED na linijce świetlnej, żeby móc obserwować pracę mikrokontrolera. Po naciśnięciu przycisku program się zatrzymuje (dioda się nie przesuwa) a dioda na płytce Nucleo się nie zapala. Wygląda to tak jakby przerwanie zostało wywołane i mikrokontroler w nim pozostał.

Gdzie popełniłem błąd? czy jest coś jeszcze co powinno zostać zmienione z uwagi na inny mikrokontroler niż ten w kursie?

Link do komentarza
Share on other sites

Cześć,

Trochę to trwało, ale udało mi się rozwiązać problem z przerwaniami dla Nucleo F303RE.

Problem tkwi w kodzie dla Startup (startup_stm32.s) brak w nim odwołania do przerwań:

/******************************************************************************
*
* The minimal vector table for a Cortex-M.  Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
	.section	.isr_vector,"a",%progbits
.type	g_pfnVectors, %object
.size	g_pfnVectors, .-g_pfnVectors

g_pfnVectors:
.word	_estack
.word	Reset_Handler
.word	NMI_Handler
.word	HardFault_Handler
.word	MemManage_Handler
.word	BusFault_Handler
.word	UsageFault_Handler
.word	0
.word	0
.word	0
.word	0
.word	SVC_Handler
.word	DebugMon_Handler
.word	0
.word	PendSV_Handler
.word	SysTick_Handler
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0
.word	0

Podmieniłem jego zawartość z pliku startup_stm32f30x.s znajdującego się u mnie:

STM32F30x_DSP_StdPeriph_Lib_V1.2.1\Libraries\CMSIS\Device\ST\STM32F30x\Source\Templates\gcc_ride7

W rozwiązaniu problemu pomógł mi ten wątek, na forum STM: Klik

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

Jak ja się cieszę, że na to wpadłem, bo już zaczynałem drugi litr kawy i szukałem błędu u siebie. 😃

Żeby nie bawić się w taką podmiankę za każdym razem polecam edytować template_startup_stm32.s.

U mnie to było w:

C:\Program Files\Ac6\SystemWorkbench\plugins\fr.ac6.mcu.ide_1.3.0.201507241045\resources\bare_project\template_startup_stm32.s

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.