引言

这是这篇博文的升级版本

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 用中断实现按键点灯和蜂鸣器鸣叫(固件库版)相关推荐

  1. OK6410开发板学习之外部中断(按键点亮led和蜂鸣器)

    中断在嵌入式里面是很常见的一个功能了.通过这个功能,可以让CPU减轻很多负担,不用不断的查询设备的状态.提高了CPU的效率. 中断的大体过程如下: 中断源检测中断信号产生,然后将中断信号发送给中断控制 ...

  2. 龙芯2k按键中断驱动_外部中断按键驱动

    我的开发板上一共有四个按键,分别影射到GPF0.GPF2.GPG3.GPG11,当按下按键时分别产生0.2.11.19号外部中断.由于没有安装驱动,当按下按键时,没有任何反应.所以需要编写一个驱动,将 ...

  3. linux 按键驱动中断 rockchip_7.自己写中断方式按键驱动程序(详解)

    request_irq()和free_irq()分析完毕后,接下来开始编写上升沿中断的按键驱动 如下图,需要设置4个按键的EINT0, EINT2, EINT11, EINT19的模式为双边沿,且设置 ...

  4. 【10天基于STM32F401RET6智能锁项目实战第4天】外部中断的按键实现语音控制

    外部中断的按键实现语音控制 一.实现语音功能 1.语音模块的资料 2.代码实现 二.外部中断的按键实现语音控制 一.实现语音功能 1.语音模块的资料 首先我们要做的就是了解语音模块是怎么使用的,那么就 ...

  5. cc2530 按键中断实验——按键控制LED灯的亮灭

    在本次学习中,主要通过外部中断来控制LED的亮灭. 首先,先查看相关电路图.由图可知,当CC2530端口1的1号引脚输出低电平时,LED3将被点亮,当按键31按下时,端口1的1号引脚将为低电平,抬起时 ...

  6. 1.8.ARM裸机第八部分-按键和CPU的中断系统

    1.8.1.什么是按键 1.8.1.1.按键的物理特性 (1).平时没人按的时候,弹簧把按键按钮弹开.此时内部断开的. (2).有人按下的时候,手的力量克服弹簧的弹力,将按钮按下,此时内部保持接通(闭 ...

  7. 51单片机:利用外部中断实现按键按一下数码管数字加1直到加到99,另一个按键实现清零

    51单片机:利用外部中断实现按键按一下数码管数字加1直到加到99,另一个按键实现清零 题目要求: 利用外部中断实现按键按一下数码管数字加1,实现00-99的循环,另一个按键实现清零,不管数码管数字是多 ...

  8. stm32l4 外部中断按键会卡死_【stm32f407】外部中断实现按键中断方式

    一.外部中断 STM32F4的每个IO都可以作为外部中断的中断输入口,这点也是STM32F4的强大之处.STM32F407的中断控制器支持22个外部中断/事件请求.每个中断设有状态位,每个中断/事件都 ...

  9. 51单片机:中断实现按键按一下数码管从00加到99循环(C语言)

    51单片机:中断实现按键按一下数码管从00加到99循环(C语言) 题目要求: 在51单片机上通过C语言编写代码,使用中断,按键按一下数码管上面的数字从00开始加1,实现00--99的循环 准备工作: ...

最新文章

  1. PARAMETERS 指令
  2. java word表格_Java 添加Word表格行或列
  3. OpenCV在Python上的调用( import cv2的解决办法)
  4. 扎心!互联网行业的神回复
  5. python paramiko并发_使用Python paramiko模块利用多线程实现ssh并发执行操作
  6. I/O复用之 EPOLLONESHOT 事件
  7. 《从零开始走进FPGA》导读
  8. lisp用entmake生产圆柱体_投石科技圆柱体全息幻象装置
  9. 功率 dbm 和 mw 的换算
  10. zedgraph显示最小刻度_ZedGraph教程
  11. [工具]勒索病毒解密工具汇总
  12. Linux查看目录busy,Linux中遇到device is busy的处理方法
  13. 高等数学强化3:一元函数积分学 P积分
  14. 解决移动硬盘可以识别,但不显示盘符的问题
  15. A Game of Thrones(84)
  16. OSChina 周四乱弹 —— 曾经有只老鹰冲着我提需求
  17. 物联网平台TZ-IOT发布透传云内测服务:V1.0
  18. LinuxC进程编程
  19. Kanzi学习之路(2):Hello world!
  20. jenkins fastlane淌坑记录

热门文章

  1. 密码的复杂化#个人隐私保护系列#
  2. 计算机网络与应用测试题,计算机网络技术与应用测试题
  3. unity 200.8m yoy_没错,Unity双十一来了
  4. python和sass区别_CSS 的预处理程序(Sass、LESS、Stylus 等)分别都有哪些优缺点?...
  5. eeglab中文教程系列(6)-数据叠加平均{1}(Data averaging)
  6. MetaHuman效果炸了!但如果只想到元宇宙,那格局有点小了
  7. 美国版“非升即走”瞄准终身教授,2年评审不通过就减薪撤职,其他高校开始抢人...
  8. 明尼苏达大学研究团队道歉,Linux内核维护人员:拒绝
  9. 疫情凶险,开学延期:在家中陪孩子,需要注意这3点
  10. 27年前被Nature拒稿,如今斩获诺贝尔奖!学术投稿模式再引热议:都有神奇的评审2...