1.初始化用来产生中断的 GPIO
本次实验采用按键产生中断,通过按键按下使得对应的GPIO产生外部中断,初始化代码如下:
//按键引脚初始化
void KEY_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//开漏输入
GPIO_Init(GPIOA,&GPIO_InitStruct);
}
2.初始化 EXTI
首先是打开时钟,exti也是挂载到APB2总线的外设,注意此时的IO是复用IO,使能时应该选AFIO。
然后选择EXTI的输入线,按键是IO口是PA0,相关函数在固件库gpio.h文件中。
再利用结构体初始化exti,结构体在固件库exti.h中,中断线选择0,模式选择中断,触发选上升沿。相关代码配置如下:
void exti_config(void)
{
//初始化exti
EXTI_InitTypeDef EXTI_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
}
3.配置 NVIC
配置中断优先级,相关函数存放在misc.h文件中,相关代码如下:
static void NVIC_Config(void) //只能被此函数所在的文件里被调用
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//优先级分组
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn ;//选择中断源
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级选择为1
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;//子优先级为1
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
注意:
1.优先级分组,组0代表抢占优先级位数为0,子优先级为4,依次类推
2.对于GPIO中断源的选择,0-4都是独立的,5-9是EXTI9-5_IRQn,10-15是
EXTI15_10_IRQn 。
4.编写中断服务函数
为了方便管理,中断服务函数写在stm32f10x_it.c文件中,注意此时函数名要去启动文件里的中断向量表里面找,如下
此时可以看到0-4有单独的函数名,5-9、10-15均共用一个函数名,中断服务函数代码如下:
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)//检测按键是否按下
{
LED_B_TOGGLE;//灯状态翻转一次
}
EXTI_ClearITPendingBit(EXTI_Line0);//清除中断标志位
}
最后主函数代码如下:
int main(void)
{
GPIO_LED_Config();
KEY_Config();
exti_config();
}
按键按下,产生外部中断,灯状态改变一次。