stm32基础学习——外部中断的使用
·
stm32基础学习——外部中断的使用
所有可用资源可在我的gitee仓库查找,点击即可前往。
一、前言
本篇文章继续介绍stm32的一些基本使用,文章主要是介绍外部中断的使用,同样以按键控制LED灯为例,之前我用查询方式来实现的,这篇文章尝试用中断的方式实现,废话不多说,咱们开始。
二、准备工作
硬件:
- stm32F103C8T6开发板
- ST-LINK V2下载器一个
- 3~5V的LED灯(发光二极管)一个
- 四引脚按键一个
- 杜邦线若干+面包板
软件:
- Keil 5(没安装可以点击进入我的另一篇博客有详细下载及配置教程)
其他(需要自行下载,点击前往,下载template文件即可):
- stm32工程模板(由于新建模板比较麻烦,初学还是找个工程模板吧,方便点)
电路图:
三、编写代码
为了方便对比,我这里先给出用查询方式实现LED灯开关的代码,对比可以发现,在查询方式中Turn_LED函数是写在while循环里面的,而在中断方式里是写在中断函数里面的。
3.1用查询方式实现LED开关
#include "stm32f10x.h"
#include "delay.h"
uint8_t flag1 = 0; //表示是否按下的标志位
uint8_t is_led_turn = 0; //LED灯状态标志位默认为关
void Trun_LED(void); //开灯关灯
void Trun_LED(void){
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0){
flag1 = 1; //表示按下
Delay(50);
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 1 && flag1 == 1){
// 取反状态:如按下前为关则置为开,反之亦然
is_led_turn = !is_led_turn;
GPIO_WriteBit(GPIOB, GPIO_Pin_10, is_led_turn == 1 ? Bit_SET : Bit_RESET);
flag1 = 0; // 重置
}
}
}
int main(void)
{
//按键引脚初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //设置为输入上拉模式
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
//初始化连接LED的引脚
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //设置为输出推挽模式
GPIO_ResetBits(GPIOB, GPIO_Pin_10);
GPIO_Init(GPIOB, &GPIO_InitStruct);
while(1){
Trun_LED();
}
}
上面就是用查询方式实现的当个按键开关控制LED,也挺丝滑的哈。
3.2用中断方式实现LED开关
在stm32中使用中断我感觉还是有点麻烦,大概就以下的步骤:开启时钟 -> 配置GPIO和AFIO -> 配置EXTI -> 配置NVIC -> 配置中断函数,大概就这些了。
#include "stm32f10x.h"
#include "delay.h"
uint8_t is_led_turn = 0; //LED灯状态标志位默认为关
void Turn_LED(void); //开灯关灯
void Key_Init(void); //初始化中断
void EXTI0_IRQHandler(void); //中断函数
void Key_Init(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//配置AFIO
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
//配置EXTI
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line14;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿出发
EXTI_Init(&EXTI_InitStructure);
//配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级
NVIC_Init(&NVIC_InitStructure);
}
// 这里注意
// GPIO引脚0~4使用的是独立中断线Line0~4,Line5-9是同一中断线,Line10-15同一中断线
// 如果使用的是同一中断线,下面的函数名相应的改动,如EXTI0_IRQHandler()
void EXTI15_10_IRQHandler(void){ //配置中断函数函数
if(EXTI_GetITStatus(EXTI_Line14) == SET){ //中断标志判断
Delay(10);
Turn_LED();
}
EXTI_ClearITPendingBit(EXTI_Line14); // 清除标志位
}
void Turn_LED(void){
//按键按下
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0){
// 取反状态:如按下前为关则置为开,反之亦然
is_led_turn = !is_led_turn;
GPIO_WriteBit(GPIOB, GPIO_Pin_10, is_led_turn == 1 ? Bit_SET : Bit_RESET);
//等待松开,防止重复进入中断(学习使用,工作中应避免这种用法)
while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0);
Delay(10);
}
}
int main(void)
{
//按键引脚初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //设置为输入上拉模式
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
//初始化连接LED的引脚
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //设置为输出推挽模式
GPIO_ResetBits(GPIOB, GPIO_Pin_10);
GPIO_Init(GPIOB, &GPIO_InitStruct);
Key_Init(); //初始化中断
while(1){
//Turn_LED();
}
}
四、结束语
好了,stm32的基本使用——外部中断的使用先介绍到这,后续有时间我继续更新这方面的文章,敬请期待,我是“风行男孩”,咱有缘再见!(码字不易,转载请标明出处!若是文章有帮助,点个赞留个痕迹即可。)
更多推荐

所有评论(0)