srm32f4按键蜂鸣器_stm32 用中断实现按键点灯和蜂鸣器鸣叫(固件库版)
引言
这是这篇博文的升级版本
https://blog.csdn.net/qq_44885018/article/details/103050388
上面轮询的方法,今天主要讲中断的方法。为了方便不要开两个网页,我尽量把主要不一样的代码弄一下,原先的代码,电路图和任务说明就不写了,需要的跳转看一下上一篇。
按键中断代码
与原先的代码多了两个中断初始化函数(也就是有interrupt的),中断函数我没有写在这个子文件,因为中断函数随时可以变,所有写在main函数前面。
#include"key.h"
#include
#include"stm32f4xx.h"
#include"stm32f4xx_gpio.h"
//GEC_key_init:初始化key所使用的端口
void GEC_key_init(void)
{
//使能GPIOA、GPIOC端口时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
//设置模式
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;//设置为输入模式
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;//设置相应端口
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;//输入模式为悬空
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//速率为50MHz
GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化端口
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13;//切换引脚
GPIO_Init(GPIOC,&GPIO_InitStruct);//切换组号,并且初始化
}
/*
GEC_key_ctl:实现对按键的状态的监控
@key_n:用于保存键返回状态的主源
例如:
GEC_F429_K2_K3:表示主源为两个键
GEC_F429_K2:表示主源是键K2
GEC_F429_K3:表示主源是键k3
返回值:返回主源键的状态
例如:
GEC_KEY_DOWN:表示主源键按下
GEC_KEY_UP:表示主源键松开
(注意当主源键为GEC_F429_K2_K3表示两个键按下或者松开,当主源键为一个时表示另一个为松开状态)
*/
int GEC_key_ctl(int *key_n)
{
//读取键的电平状态
uint8_t status_a=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);//获取键k2的电平
uint8_t status_c=GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13);//获取键k3的电平
//将键k2的电平左移1位和键k3的电平组合去满足宏的范围
/*
KEY_ALL_DOWN:表示键k2、k3按下
KEY_K2_DOWN:表示键k2按下,k3松开
KEY_K3_DOWN:表示键k3按下,k2松开
KEY_ALL_UP:表示键k2、k3松开
*/
status_c+=status_a<<1;
switch (status_c)
{
case KEY_ALL_DOWN:
{
*key_n=GEC_F429_K2_K3;
return GEC_KEY_DOWN;
}
case KEY_K2_DOWN:
{
*key_n=GEC_F429_K2;
return GEC_KEY_DOWN;
}
case KEY_K3_DOWN:
{
*key_n=GEC_F429_K3;
return GEC_KEY_DOWN;
}
case KEY_ALL_UP:
{
*key_n=GEC_F429_K2_K3;
return GEC_KEY_UP;
}
default:;
}
return GEC_KEY_UP;
}
/*
在启动汇编的.s文件进行替换,并且声明
IMPORT GEC_key2_interrupt;
IMPORT GEC_key3_interrupt
*/
//GEC_key2_interrupt_init:主要实现键k2的初始化
void GEC_key2_interrupt_init(void)
{
//GPIO口的基本初始化配置,这里就不多说了,看上面链接的博客
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;//需要注意的就是中断的串口必须是输入模式,因为要获取而不是修改
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//SYSCFG:系统配置管理的设置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//其也是一个外设,需要使能时钟
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);//确定需要中断的是哪个引脚
//外部中断控制器的配置
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line=EXTI_Line0;//中断的组号
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;//模式的选择,还有一种可以是一种事件
EXTI_InitStruct.EXTI_LineCmd=ENABLE;//允许中断
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising_Falling;//中断触发方式为:双边沿触发
EXTI_Init(&EXTI_InitStruct);
//NVIC的配置,NVIC:嵌套中断控制器(简单来说就是优先级问题)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;//中断组号
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级的设置
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//子优先级设置(也就是在抢占优先级相同且同时情况下使用)
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//允许中断
NVIC_Init(&NVIC_InitStruct);
}
void GEC_key3_interrupt_init(void)//和上面类似
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStruct);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,EXTI_PinSource13);
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line=EXTI_Line13;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising_Falling;
EXTI_Init(&EXTI_InitStruct);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=EXTI15_10_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
main函数
#include
#include"led.h"
#include"key.h"
#include"stm32f4xx.h"
#include"stm32f4xx_gpio.h"
#include"beep.h"
/*
在启动汇编的.s文件进行替换,并且声明
IMPORT GEC_key2_interrupt;
IMPORT GEC_key3_interrupt
*/
void GEC_key2_interrupt(void)//k2中断函数
{
if(SET==EXTI_GetFlagStatus(EXTI_Line0))//检测是否0组是否发生中断
{
if(GEC_KEY_DOWN==GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))//判断键2是否按下还是弹起
{
GEC_led_ctl(GEC_F429_D3,GEC_LED_ON);//控制灯D3亮
if(GEC_KEY_DOWN==GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13))//判断键k3是否按下
{
GEC_beep_ctl(GEC_BEEP_ON);//k2,k3同时按下,蜂鸣器鸣叫
}
}
else
{
GEC_led_ctl(GEC_F429_D3,GEC_LED_OFF);//k2松开时,灯熄灭
GEC_beep_ctl(GEC_BEEP_OFF);//将蜂鸣器关闭
}
EXTI_ClearITPendingBit(EXTI_Line0);//清除中断标志
}
}
void GEC_key3_interrupt(void)//k3中断函数
{
if(SET==EXTI_GetFlagStatus(EXTI_Line13))//检测是否13组是否发生中断
{
if(GEC_KEY_DOWN==GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13))//判断键3是否按下还是弹起
{
GEC_led_ctl(GEC_F429_D4,GEC_LED_ON);//控制灯D4亮
if(GEC_KEY_DOWN==GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))//判断键k2是否按下
{
GEC_beep_ctl(GEC_BEEP_ON);//k2,k3同时按下,蜂鸣器鸣叫
}
}
else
{
GEC_led_ctl(GEC_F429_D4,GEC_LED_OFF);//k3松开时,灯熄灭
GEC_beep_ctl(GEC_BEEP_OFF);//将蜂鸣器关闭
}
EXTI_ClearITPendingBit(EXTI_Line13);//清除中断标志
}
}
int main()
{
GEC_led_init();//初始化LED灯
GEC_key_init();//初始化按键灯
GEC_beep_init();//初始化蜂鸣器
GEC_key2_interrupt_init();//初始化按键中断键k2
GEC_key3_interrupt_init();//初始化按键中断键k3
while(1);//等待中断
}
注意点
因为使用固件库,使用你需要在固件库的startup_stm32f429_439xx.s进行修改,以及声明。
将
DCD EXTI0_IRQHandler
修改成
DCD GEC_key2_interrupt;
将
DCD EXTI15_10_IRQHandler
修改成
DCD GEC_key3_interrupt;
由于这两个程序均是用c写的所以,需要在这个汇编启动代码加入声明
IMPORT GEC_key2_interrupt;
IMPORT GEC_key3_interrupt
注意中断函数为没有返回值和参数列表,因为,中断具有不可控,你不知道什么时候发生。
其次也有人会问,为什么没有延时去抖动?
实际上也没什么特别必要(当然你要加也很简单),为什么没什么必要呢?因为这不是测电平,实现函数发生器,产生方波之类的,仅仅只是按下就发光,就是有抖动,人的眼睛也看不出来,反应不过来,而且这里中断中使用的也不是将端口电平取反之类的,使用也是可控状态的。我也亲测实现和想的一至,完成任务需求。
其他的我基本上都写了备注,由于两个按键中断差不多,所以第二个,基本上没有写备注,不过流程差不多。
结语
如果有什么疑问,或者观点不一致的欢迎一起讨论。
如果有什么函数不懂的可以自己稍微查一下,也可以比较两个的不同,了解。
srm32f4按键蜂鸣器_stm32 用中断实现按键点灯和蜂鸣器鸣叫(固件库版)相关推荐
- OK6410开发板学习之外部中断(按键点亮led和蜂鸣器)
中断在嵌入式里面是很常见的一个功能了.通过这个功能,可以让CPU减轻很多负担,不用不断的查询设备的状态.提高了CPU的效率. 中断的大体过程如下: 中断源检测中断信号产生,然后将中断信号发送给中断控制 ...
- 龙芯2k按键中断驱动_外部中断按键驱动
我的开发板上一共有四个按键,分别影射到GPF0.GPF2.GPG3.GPG11,当按下按键时分别产生0.2.11.19号外部中断.由于没有安装驱动,当按下按键时,没有任何反应.所以需要编写一个驱动,将 ...
- linux 按键驱动中断 rockchip_7.自己写中断方式按键驱动程序(详解)
request_irq()和free_irq()分析完毕后,接下来开始编写上升沿中断的按键驱动 如下图,需要设置4个按键的EINT0, EINT2, EINT11, EINT19的模式为双边沿,且设置 ...
- 【10天基于STM32F401RET6智能锁项目实战第4天】外部中断的按键实现语音控制
外部中断的按键实现语音控制 一.实现语音功能 1.语音模块的资料 2.代码实现 二.外部中断的按键实现语音控制 一.实现语音功能 1.语音模块的资料 首先我们要做的就是了解语音模块是怎么使用的,那么就 ...
- cc2530 按键中断实验——按键控制LED灯的亮灭
在本次学习中,主要通过外部中断来控制LED的亮灭. 首先,先查看相关电路图.由图可知,当CC2530端口1的1号引脚输出低电平时,LED3将被点亮,当按键31按下时,端口1的1号引脚将为低电平,抬起时 ...
- 1.8.ARM裸机第八部分-按键和CPU的中断系统
1.8.1.什么是按键 1.8.1.1.按键的物理特性 (1).平时没人按的时候,弹簧把按键按钮弹开.此时内部断开的. (2).有人按下的时候,手的力量克服弹簧的弹力,将按钮按下,此时内部保持接通(闭 ...
- 51单片机:利用外部中断实现按键按一下数码管数字加1直到加到99,另一个按键实现清零
51单片机:利用外部中断实现按键按一下数码管数字加1直到加到99,另一个按键实现清零 题目要求: 利用外部中断实现按键按一下数码管数字加1,实现00-99的循环,另一个按键实现清零,不管数码管数字是多 ...
- stm32l4 外部中断按键会卡死_【stm32f407】外部中断实现按键中断方式
一.外部中断 STM32F4的每个IO都可以作为外部中断的中断输入口,这点也是STM32F4的强大之处.STM32F407的中断控制器支持22个外部中断/事件请求.每个中断设有状态位,每个中断/事件都 ...
- 51单片机:中断实现按键按一下数码管从00加到99循环(C语言)
51单片机:中断实现按键按一下数码管从00加到99循环(C语言) 题目要求: 在51单片机上通过C语言编写代码,使用中断,按键按一下数码管上面的数字从00开始加1,实现00--99的循环 准备工作: ...
最新文章
- PARAMETERS 指令
- java word表格_Java 添加Word表格行或列
- OpenCV在Python上的调用( import cv2的解决办法)
- 扎心!互联网行业的神回复
- python paramiko并发_使用Python paramiko模块利用多线程实现ssh并发执行操作
- I/O复用之 EPOLLONESHOT 事件
- 《从零开始走进FPGA》导读
- lisp用entmake生产圆柱体_投石科技圆柱体全息幻象装置
- 功率 dbm 和 mw 的换算
- zedgraph显示最小刻度_ZedGraph教程
- [工具]勒索病毒解密工具汇总
- Linux查看目录busy,Linux中遇到device is busy的处理方法
- 高等数学强化3:一元函数积分学 P积分
- 解决移动硬盘可以识别,但不显示盘符的问题
- A Game of Thrones(84)
- OSChina 周四乱弹 —— 曾经有只老鹰冲着我提需求
- 物联网平台TZ-IOT发布透传云内测服务:V1.0
- LinuxC进程编程
- Kanzi学习之路(2):Hello world!
- jenkins fastlane淌坑记录
热门文章
- 密码的复杂化#个人隐私保护系列#
- 计算机网络与应用测试题,计算机网络技术与应用测试题
- unity 200.8m yoy_没错,Unity双十一来了
- python和sass区别_CSS 的预处理程序(Sass、LESS、Stylus 等)分别都有哪些优缺点?...
- eeglab中文教程系列(6)-数据叠加平均{1}(Data averaging)
- MetaHuman效果炸了!但如果只想到元宇宙,那格局有点小了
- 美国版“非升即走”瞄准终身教授,2年评审不通过就减薪撤职,其他高校开始抢人...
- 明尼苏达大学研究团队道歉,Linux内核维护人员:拒绝
- 疫情凶险,开学延期:在家中陪孩子,需要注意这3点
- 27年前被Nature拒稿,如今斩获诺贝尔奖!学术投稿模式再引热议:都有神奇的评审2...