第四章:EXTI-使用按键点亮LED灯
在之前的几讲中,我讲过了如果通过编程来点亮LED灯,今天这节课,我要将另一种点亮LED灯的方法:通过独立按键来控制LED灯的亮灭。本质上,还是点亮LED灯,改变的只是触发方式,之前用的是程序触发从而点亮LED灯,咱们这次用的是按键了,当然也不仅仅是按键,你也可以使用其它的外设来控制LED灯亮灭,按键只是我们学习EXTI(外部中断/事件控制器来举的一个例子,仅此而已。
一、 神马是EXTI
STM32 (非互联型)供 IO 口使用的中断线只有 16 个,但是 STM32 的 IO 口却远远不止16 个,那么 STM32 是怎么把 16 个中断线和 IO 口一一对应起来的呢?于是 STM32 就这样设计,GPIO 的管教 GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线 15~0。这样每个中断线对应了最多 7 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。而中断线每次只能连接到 1 个 IO 口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。下面我们看看 GPIO 跟中断线的映射关系图:
二、按键!
指南者上面的按键是叫轻触开关(独立按键\微动按键),当按键按下,电路导通。我们再来看一下指南者这个板子上他的按键电路:
typedef struct { uint8_t NVIC_IRQChannel;//配置中断源,在stm32f10x.h中,如果用的是EXTI0 就是EXTI0_IRQn(186行) uint8_t NVIC_IRQChannelPreemptionPriority;//配置抢占优先级 uint8_t NVIC_IRQChannelSubPriority;//配置子优先级 FunctionalState NVIC_IRQChannelCmd; //中断源使能 } NVIC_InitTypeDef;
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)ST已经给了这个函数详细的注释:
/** * @brief Configures the priority grouping: pre-emption priority and subpriority. * @param NVIC_PriorityGroup: specifies the priority grouping bits length. * This parameter can be one of the following values: * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority * 4 bits for subpriority * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority * 3 bits for subpriority * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority * 2 bits for subpriority * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority * 1 bits for subpriority * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority * 0 bits for subpriority * @retval None */三、 说了这么多,终于要开始编程啦~
1、 初始化LED的GPIO
//选择EXTI的信号源和输入线,函数参数可以直接调到它的定义处,有详细说明。
GPIO_EXTILineConfig(KEY1_EXTI_PORTSOURCE, KEY1_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = KEY1_EXTI_LINE;
//配置为中断模式,还有一种是事件模式是传输一个脉冲信号给其他外设使用
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
//上升沿中断,也就是按键被按下的时候才触发中断(看原理图),执行中断服务程序
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
//使能中断
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
5、 编写中断服务函数
static int i=0;//定义一个静态变量,初始化为0
void KEY1_IRQHandler(void)
{
//确保是否产生了EXTI Line中断
if(EXTI_GetITStatus(KEY1_EXTI_LINE) != RESET)
{
if(i==0)
{
GPIO_ResetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);//点亮
i=1;
}
else
{
GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);//熄灭
i=0;
}
//清除中断标志位
EXTI_ClearITPendingBit(KEY1_EXTI_LINE);
}
}


块
导
航
举报
请选择举报类别
- 广告垃圾
- 违规内容
- 恶意灌水
- 重复发帖