这次实验要实现的效果是通过中断方式按键控制LED闪烁翻转。
配置中断步骤是:
1:按键GPIO初始化;
2:使能AIFO时钟;
3:中断映射线配置;
4:EXTI配置;
5:NVIC配置;(主函数进行分组)
6:编写中断服务函数;
先贴出exti.c中的代码:
#include "exti.h"
#include "button.h"
#include "delay.h"
#include "led.h"
void MY_EXTI_Init(void)
{
EXTI_InitTypeDefEXTI_InitStructure;
NVIC_InitTypeDefNVIC_InitStructure;
Button_Init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line=EXTI_Line5;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_Init(&NVIC_InitStructure);
EXTI_InitStructure.EXTI_Line=EXTI_Line15;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
EXTI_InitStructure.EXTI_Line=EXTI_Line0;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI9_5_IRQHandler(void)
{
delay_ms(10);
if(KEY0==0) GPIO_WriteBit(GPIOA,GPIO_Pin_8,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_8)));
EXTI_ClearITPendingBit(EXTI_Line5);
}
void EXTI15_10_IRQHandler(void)
{
delay_ms(10);
if(KEY1==0) GPIO_WriteBit(GPIOD,GPIO_Pin_2,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_2)));
EXTI_ClearITPendingBit(EXTI_Line15);
}
void EXTI0_IRQHandler(void)
{
delay_ms(10);
if(WK_UP==1)
{
GPIO_WriteBit(GPIOA,GPIO_Pin_8,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_8)));
GPIO_WriteBit(GPIOD,GPIO_Pin_2,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_2)));
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
这里还有一点要说明的是GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_8)));可以轻松实现GPIO口状态翻转。
还有以下注意点:
1:NVIC函数在misc.h中,各通道在stm32f10x.h中,各中断函数名称在启动文件中
2:error: #268: declaration may not appear afterexecutable statement in block
在语句后不能再定义变量,比如 EXTI_InitTypeDefEXTI_InitStructure;这种语句应该放在最开头。
3:warning: #188-D: enumerated type mixed with anothertype 定义了枚举类型,却用其他类型向它赋值。
4:有多个中断时,NVIC_IRQChannelSubPriority响应优先级要有大小区分。这里所谓2位是指0到3。
5:注意触发方式是上升沿还是下降沿或者是双边沿。