IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler
硬件:
LED——GPIOB,GPIO_Pin_5
KEY——GPIOE,GPIO_Pin_1
代码:
void LED_Init(void) //led初始化配置
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高 此时状态为灭 低电平亮
}
void KEY_Init(void) //key初始化配置
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能PORTA,PORTE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化GPIOE.1
}
void EXTIX_Init(void) //中断线初始化配置 下降沿触发
{
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource1); //设置IO口与中断线的映射关系
EXTI_InitStructure.EXTI_Line=EXTI_Line1; //KEY——GPIOE,GPIO_Pin_1 映射线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //上升沿中断
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
}
void NVIC_Init(void) //中断初始化配置
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //使能按键key1所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
}
void EXTI1_IRQHandler(void) //中断服务函数配置
{
delay_ms(10); //键盘消抖
if(EXTI_GetITStatus(EXTI_Line1)==1) //判断中断线中断状态是否发生
{
GPIO_PinReverse(GPIOB,GPIO_Pin_5); //反转
}
EXTI_ClearITPendingBit(EXTI_Line1); //清除LINE1上的中断标志位
}
int main(void)
{
LED_Init();
KEY_Init();
NVIC_Init();
EXTIX_Init();
while(1);
}
1.使用 #define 宏定义来声明GPIO口
2.使用 库函数 或者 寄存器 来操作GPIO口
硬件:
LED——GPIOB,GPIO_Pin_5
KEY——GPIOE,GPIO_Pin_1
#define digitalHi(p,i) {p->BSRR = i;}
#define digitalLow(p,i) {p->BSRR = (uint32_t)i;}
#define digitalToggle(p,i) {p->ODR ^= i;}
#define LED_GPIO_PORT GPIOB
#define LED_GPIO_PIN GPIO_pin_5
#define LED_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_TOGGLE digitalToggle(LED_GPIO_PORT,LED_GPIO_PIN)
#define LED_OFF digitalHi(LED_GPIO_PORT,LED_GPIO_PIN)
#define LED_ON digitalLow(LED_GPIO_PORT,LED_GPIO_PIN)
①设置IO口与中断线的映射关系:
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource,uint8_t GPIO_PinSource);
eg: GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource1);
② 初始化中断线:触发方式等:
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
③判断中断线中断状态,是否发生:
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
④清除中断线上的中断标志位:
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
EXTI_Init函数:
typedef struct
{
uint32_t EXTI_Line; //指定要配置的中断线
EXTIMode_TypeDef EXTI_Mode; //模式:事件 OR中断
EXTITrigger_TypeDef EXTI_Trigger; //触发方式:上升沿/下降沿/双沿触发
FunctionalState EXTI_LineCmd; //使能 OR失能
}EXTI_InitTypeDef;
EXTI_InitStructure.EXTI_Line=EXTI_Line2;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);