版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
按键KEY中断方式控制LED
中断固件库 stm32f10x_exti.h 和 stm32f10x_exti.c
STM32 的每个 IO 都可以作为外部中断的中断输入口,这点也是 STM32 的强大之处。STM32F103 的中断控制器支持 19 个外部中断事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103 的19 个外部中断为:
- 线 0~15:对应外部 IO 口的输入中断。
- 线 16:连接到 PVD 输出。
- 线 17:连接到 RTC 闹钟事件。
- 线 18:连接到 USB 唤醒事件。
GPIO 的管教 GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线 0-15(GPIO 和中断线的映射关系图)
使用 IO 口外部中断的一般步骤:
1)初始化 IO 口为输入。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);
//这里PGIO不只是作为普通输入输出、还要作为中断,需挂载RCC_APB2Periph_AFIO
//配置key
GPIO_InitTypeDef GPIO_InitTypeDef_PE4 ;
GPIO_InitTypeDef_PE4 .GPIO_Pin = GPIO_Pin_4;//PE4
GPIO_InitTypeDef_PE4 .GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_Init(GPIOE,&GPIO_InitTypeDef_PE4 )
2)开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
/*
GPIO_PortSource 为GPIO_PortSourceGPIO(A-G)
GPIO_PinSource 为GPIO_PinSource(0-15)
具体那个端口怎么配置得看上图(GPIO 和中断线的映射关系图):
比如是PA5 1. GPIO_PortSource为GPIO_PortSourceGPIOA
2. GPIO_PinSource为GPIO_PinSource5
*/
3)初始化线上中断,设置触发条件等。
//外部i/o中断配置
EXTI_InitTypeDef EXTI_ITDef;
//该函数将 GPIO 端口与中断线映射起来
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
EXTI_ITDef.EXTI_Line = EXTI_Line4;
EXTI_ITDef.EXTI_Mode = EXTI_Mode_Interrupt;//设置 EXTI 线路为中断请求
EXTI_ITDef.EXTI_Trigger=EXTI_Trigger_Falling;//设置输入线路下降沿为中断请求
EXTI_ITDef.EXTI_LineCmd = ENABLE;//定义选中线路的新状态
EXTI_Init(&EXTI_ITDef);
4)配置中断分组(NVIC),并使能中断。
//中断管理NVIC
NVIC_InitTypeDef NVIC_ITDef;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
NVIC_ITDef.NVIC_IRQChannel = EXTI4_IRQn;//使能按键外部中断通道
NVIC_ITDef.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2
NVIC_ITDef.NVIC_IRQChannelSubPriority = 0x00;//子优先级 2
NVIC_ITDef.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
NVIC_Init(&NVIC_ITDef);
5)编写中断服务函数。
//常用的中断服务函数格式为:
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生
{
//中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位
}
}
KEY(PE4)中断方式控制LED(PB5)代码
#include "stm32f10x.h"
void LED_Ioinit(void)
{
//挂载PE5到时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitTypeDef GPIO_ITYPD;
GPIO_ITYPD.GPIO_Pin=GPIO_Pin_5;//端口
GPIO_ITYPD.GPIO_Mode=GPIO_Mode_Out_PP;//模式
GPIO_ITYPD.GPIO_Speed=GPIO_Speed_2MHz;//速度
GPIO_Init(GPIOE,&GPIO_ITYPD);//设置PB5
GPIO_SetBits(GPIOE,GPIO_Pin_5); //BSRR 1
//GPIO_ResetBits(GPIOE,GPIO_Pin_5); //BRR 0
}
void EXTI_Init_k0(void)
{
//外部i/o中断配置
EXTI_InitTypeDef EXTI_ITDef;
//该函数将 GPIO 端口与中断线映射起来
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
EXTI_ITDef.EXTI_Line = EXTI_Line4;
EXTI_ITDef.EXTI_Mode = EXTI_Mode_Interrupt;//设置 EXTI 线路为中断请求
EXTI_ITDef.EXTI_Trigger=EXTI_Trigger_Falling;//设置输入线路下降沿为中断请求
EXTI_ITDef.EXTI_LineCmd = ENABLE;//定义选中线路的新状态
EXTI_Init(&EXTI_ITDef);
//中断管理NVIC
NVIC_InitTypeDef NVIC_ITDef;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
NVIC_ITDef.NVIC_IRQChannel = EXTI4_IRQn;//使能按键外部中断通道
NVIC_ITDef.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2
NVIC_ITDef.NVIC_IRQChannelSubPriority = 0x00;//子优先级 2
NVIC_ITDef.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
NVIC_Init(&NVIC_ITDef);
}
void delay_ms(u16 time)
{
u16 i = 0;
while(time--)
{
i = 12000;
while(i--);
}
}
void delay_us(u16 time)
{
u16 i = 0;
while(time--)
{
i=10;
while(i--);
}
}
void KEY_Init(void)
{
//配置PE时钟 //配置复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);
//配置key
GPIO_InitTypeDef GPIO_ITYPD1;
GPIO_ITYPD1.GPIO_Pin = GPIO_Pin_4;
GPIO_ITYPD1.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_Init(GPIOE,&GPIO_ITYPD1);
}
//外部中断 4 的服务函数,负责 KEY 按键的中断检测;
void EXTI4_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line4)!=RESET)//判断某个线上的中断是否发生
{
delay_ms(15);
if(!(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)))//0X00
{
if(GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_5))//0X01
{
GPIO_ResetBits(GPIOE,GPIO_Pin_5); //BRR 0
}else
{
GPIO_SetBits(GPIOE,GPIO_Pin_5); //BSRR 1
}
}
EXTI_ClearITPendingBit(EXTI_Line4);
}
}
int main(void)
{
while(1);
}
相关文档
STM32F10x_StdPeriph_Lib_V3.5.0(官方固件库)
链接:STM32固件库使用手册的中文翻译版 提取码:4lkx