Saya sedang mengerjakan proyek yang melibatkan STM32 MCU (pada papan STM32303C-EVAL tepatnya) yang harus menanggapi gangguan eksternal. Saya ingin reaksi terhadap interupsi eksternal secepat mungkin. Saya telah memodifikasi contoh pustaka periferal standar dari halaman web ST dan program saat ini hanya menyalakan LED di setiap sisi kenaikan berturut-turut pada PE6:
#include "stm32f30x.h"
#include "stm32303c_eval.h"
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
static void EXTI9_5_Config(void);
int main(void)
{
/* Initialize LEDs mounted on STM32303C-EVAL board */
STM_EVAL_LEDInit(LED1);
/* Configure PE6 in interrupt mode */
EXTI9_5_Config();
/* Infinite loop */
while (1)
{
}
}
// Configure PE6 and PD5 in interrupt mode
static void EXTI9_5_Config(void)
{
/* Enable clocks */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Configure input */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Connect EXTI6 Line to PE6 pin */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource6);
/* Configure Button EXTI line */
EXTI_InitStructure.EXTI_Line = EXTI_Line6;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set interrupt to the highest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
Penangan interrupt terlihat seperti ini:
void EXTI9_5_IRQHandler(void)
{
if((EXTI_GetITStatus(EXTI_Line6) != RESET))
{
/* Toggle LD1 */
STM_EVAL_LEDToggle(LED1);
/* Clear the EXTI line 6 pending bit */
EXTI_ClearITPendingBit(EXTI_Line6);
}
}
Dalam kasus khusus ini, interupsi dibuat oleh generator fungsi eksternal yang dapat diprogram berjalan pada 100 Hz. Setelah memeriksa respons MCU pada osiloskop, saya agak terkejut bahwa dibutuhkan hampir 1,32 kita untuk MCU untuk mulai memproses interupsi:
Dengan MCU berjalan pada 72 MHz (saya telah memeriksa output SYSCLK pada pin MCO sebelumnya) ini berjumlah hampir 89 siklus clock. Bukankah seharusnya respons MCU terhadap interupsi jauh lebih cepat?
PS Kode ini dikompilasi dengan IAR Embedded Workbench dan dioptimalkan untuk kecepatan tertinggi.
if{}
pernyataan diperlukan karena rutin interupsi tidak tahu apa sumber interupsi itu.