文章目录

  • 1- 轮询模式和中断模式
  • 2- 配置管脚为中断模式
  • 3- 添加代码
  • 4- 具体实现原理
  • 5- main()——第一个执行程序?

在一般情况下,我们希望实现按键控制灯的亮和灭,这次学习的是中断开发按键实现LED量灭。

1- 轮询模式和中断模式

轮询(Polling)模式:
每个外围设备提供一个或多个状态信息,CPU逐次读入并测试各个外围设备的状态信息,若该外围设备请求服务(请求交换信息),则为之服务,然后清除该状态信息。否则,跳过,查询下一个外围设备的状态。各外围设备查询完一遍后,再返回从头查询起,直到发出停止命令为止。但是在查询式I/O方式下,CPU要不断地读取状态字和检测状态字,不管那个外围设备是否有服务请求,都必须一一查询,许多次的重复查询,可能都是无用的,而又占去了CPU的时间,效率较低。

中断(Interrupt)模式:
为了提高CPU的效率和使系统具有良好的实时性,可以采用中断控制I/O方式。采用中断方式CPU就不必花费大量时间去查询各外围设备的状态了。而是当外围设备需要请求服务时,向CPU发出中断请求(ARQ),CPU响应外围设备中断,停止执行当前程序,转去执行一个外围设备服务的程序,此服务程序称为中断服务处理程序,或称中断服务子程序。中断处理完毕,CPU又返回来执行原来的程序。

2- 配置管脚为中断模式

这是扩展的按键的电路,在单片机上也可以看见key1和key2两个按键。我们希望通过这两个按键分别控制LED其中两个灯的量灭。

看到原理图的话,按下按钮PC15变为低电平,所以我们需要给PA15一个高电平,即内部上拉。对应图中的GPIO Pull_up-Pull_down。
一般我们采用的都是下降沿触发,所以对应的就是GPIO mode。
最后一个User Label 相当于重命名。
当然,PC13也是一样的,LED灯的管脚配置就不过多说啦,然后Ctrl+s保存生成代码。

至于内不上拉和下拉以及沿触发、水平触发不懂的可以去了解一下,这里不过多阐述了。


并且要将中断管脚【10-15】的优先级设置为稍低一点。越大说明优先级越低。

3- 添加代码

我们需要在生成的代码中添加代码才能实现功能,就等于是按键的中断的配置配好了,我们需要利用起来。
在gpio.c中的/* USER BEGIN END 2 / 和/ USER CODE END 2 */之间添加如下代码:

/* USER CODE BEGIN 2 */
typedef struct gpio_s
{GPIO_TypeDef   *group;uint16_t       pin;
} gpio_t;/*这里定义了一个结构体数组,group指向第一个,pin指向第二个*/
gpio_t      leds[LedMax] =
{{RedLed_GPIO_Port,  SysLed_Pin},{RedLed_GPIO_Port,  BlueLed_Pin},{RedLed_GPIO_Port,  RedLed_Pin},{RedLed_GPIO_Port,  GreenLed_Pin},
};
/*which代表选择哪一个灯,int类型的,每个灯都有一个数字代替,去enum去看;ststus控制灯的亮灭,对应参数是OFF 和 ON*/
void turn_led(int which, int status)
{GPIO_PinState       level;if( which<0 || which>=LedMax){return ;}level = status == OFF ? GPIO_PIN_SET : GPIO_PIN_RESET;HAL_GPIO_WritePin(leds[which].group, leds[which].pin, level);
}/*int whitch对应的是控制哪一个灯,interval传时间,单位毫秒*/
void blink_led(int which, uint32_t interval)
{if(which>=LedMax || interval<=0){return ;}turn_led(which, ON);HAL_Delay(interval);turn_led(which, OFF);HAL_Delay(interval);
}/*每次复位都会闪三下,表示启动*/
void sysled_hearbeat(void){blink_led(SysLed, 100);blink_led(SysLed, 100);blink_led(SysLed, 800);}void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if (Key1_Pin == GPIO_Pin){blink_led(BlueLed, 500);}else if(Key2_Pin == GPIO_Pin){blink_led(RedLed, 500);}
}
/* USER CODE END 2 */

在gpio.h中添加声明:

/* USER CODE BEGIN Prototypes */
/*枚举,SysLed默认为0,后面依次增长*/
enum
{SysLed,BlueLed,RedLed,GreenLed,LedMax,
};#define OFF 0
#define ON 1extern void turn_led(int which, int status);
extern void blink_led(int which, uint32_t interval);
void sysled_hearbeat(void);
/* USER CODE END Prototypes */

我们如果现在烧录测试的话就会发现我们要改变LED灯就必须按复位键,并且灯只会亮一个,而且一直亮着。死在了那里。
全部完成之后,我们需要注意的是,HAL_Delay()是由Systick滴答定时器中断实现的,所以我们需要Systick中断优先级大于我们前面设置的优先级(数字越大优先级越低)。如下设置:在红色的地方将优先设置为最高0即可。

4- 具体实现原理

程序怎么接受中断请求的呢?接收到中断请求又是怎么处理的呢?
本来CPU是在自己的main函数中的while(1)中执行的,突然有按键的中断请求过来了,然后就去找是哪一个中断服务处理程序,并且去执行。

然后找到是EXTI15_10_IRQHandler的中断服务处理程序。EXTI15_10_IRQHandler这个中断服务处理程序是在stm32L4xx_it.h这个文件中声明的。

在stm32L4xx_it.c中找到了这个函数,系统知道我们按的是哪一个管脚,然后调用相关函数。

找到HAL_GPIO_EXTI_Callback(GPIO_Pin)然后执行我们写好的功能。我们想让这个按钮按下之后执行什么事情就是在这个HAL_GPIO_EXTI_Callback(GPIO_Pin)函数中写的。函数大小写等需要完全一样,传过来的参数就是哪一个管脚。

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if (Key1_Pin == GPIO_Pin){blink_led(BlueLed, 500);}else if(Key2_Pin == GPIO_Pin){blink_led(RedLed, 500);}
}

执行完毕之后会返回while(1)中继续执行没执行完毕的环节。

5- main()——第一个执行程序?

在startup_stm32l433cbtx.s中我们也鞥能够看见,其实STM32上电的时候,main函数并不是第一个执行的程序,他的前面还要执行一系列的操作。
还需要做:

  • 调用时钟系统初始化函数
    /* Call the clock system initialization function.*/

  • 将数据段初始化器从flash复制到SRAM
    /* Copy the data segment initializers from flash to SRAM */

  • 零填充bss段
    /* Zero fill the bss segment. */

  • 调用静态构造函数
    /* Call static constructors */

  • 调用应用程序的入口点
    /* Call the application's entry point.*/

笔记,如有错误还请指出~

STM32按键控制LED灯(中断实现)相关推荐

  1. STM32按键控制LED灯亮灭(四)

    编程要点: 1)使能GPIO端口时钟: 2)初始化GPIO目标引脚为输入模式(浮空输入): 3)编写简单测试程序,检测按键的状态,实现按键控制LED灯: bsp_led.h文件 #ifndef T_L ...

  2. 记录1——stm32f411CEU6之点亮一盏LED灯+按键控制LED灯

    文章目录 前言 一.准备工作 二.点亮一盏LED灯 1.配置工程 2.代码实现 3.程序烧录注意 三.按键控制LED灯 1.配置工程 2.代码实现 按键控制 按键进阶1: 按键进阶2 3.基于自己理解 ...

  3. STM32定时器控制LED灯闪烁及PWM练习

    一.STM32定时器控制LED灯闪烁 1.相关配置 1)配置RCC和SYS 2)配置IO 配置PC15,并命名为D1. 3)配置定时器 选定时器2,配置Clock Source为Internal Cl ...

  4. 嵌入式系统开发设计——按键控制LED灯实现

    一.实验目的 掌握STM32固件库的使用方法: 掌握基于库函数模板的开发方法: 掌握基于固件库进行GPIO端口编程的方法: 4.规范编程格式. 二.实验内容 1.查阅STM32-V5开发板按键.LED ...

  5. FPGA(1)基础入门 -- 按键控制led灯

    目录 效果说明 1.配置输入输出变量 2.变量赋值 3.配置引脚(输入输出变量) 代码 效果说明 key1按键按下,led1被点亮. key2按键按下,led2被点亮. 1.配置输入输出变量 inpu ...

  6. led计数电路实验报告_「正点原子FPGA连载」第八章 按键控制LED灯实验

    1)实验平台:正点原子开拓者FPGA开发板 2)本实例源码下载:请移步正点原子官网 第八章 按键控制LED灯实验 按键是常用的一种控制器件.生活中我们可以见到各种形式的按键,由于其结构简单,成本低廉等 ...

  7. 基于Verilog的按键控制LED灯

    按键控制LED灯 原理图 程序设计 `timescale 1ns / 1psmodule key_led( input sys_clk, input sys_rst_n, input [3:0] ke ...

  8. 51单片机实现独立按键控制LED灯

    本节博客主要实现以下效果: 3-1独立按键控制LED亮灭 本段代码主要使用了if...else...语句实现按下按下灯亮,松开按键时灯灭 #include <REGX51.H>void m ...

  9. 【tiny4412】按键控制led灯亮灭

    前言:使用友善之臂tiny4412进行嵌入式学习,对于初学者而言并不是一件轻松事情,即使该平台已经存在很多年,网上也有很多分享,但由于官方文档相对还是不够全面,导致很多初学者遇到问题不知如何下手,如果 ...

最新文章

  1. win10系统 计算机配置要求高吗,win10配置要求_win10配置要求高吗-太平洋电脑网
  2. AI基础:论文写作工具
  3. ZooKeeper安装配置
  4. itil 容量管理流程_探索ITIL和DevOps的边界
  5. ACM算法 -- 数论 -- 开灯关灯问题(数论,整数分解,因子个数,公式推导)
  6. Nodejs系列课程,从入门到进阶帮你打通全栈
  7. pbdom 不能解析gbk_备受家长追捧的公立学校,摇中率不到3%,还要抢着报名?速看大摇号学校全面解析!...
  8. layui移动开发_LayUI后台管理与综合示例
  9. Android 动态改变布局属性RelativeLayout.LayoutParams.addRule()
  10. linux内核分析及应用 -- 文件系统
  11. 将xml文件由格式化变为压缩字符串
  12. 12864液晶显示原理(C程序)
  13. VS Qt 项目 “fatal error C1083: ”无法打开包括文件
  14. tortoise git revert的坑
  15. html怎么画虚线空心圆,教你用ps怎么画一个虚线的空心圆
  16. bigworld源码分析(3)——dbMgr分析
  17. java对接钉钉发送消息通知
  18. 最新 PhpStorm 2018 安装及破解方法
  19. CSS---padding详解
  20. 计算机主板外频,笨鸟先飞 主板超频BIOS选项接触(图解)

热门文章

  1. 育种值 表型值 回归系数 相关系数 遗传力之间的关系
  2. ASP.NET MVC网站使用新浪微博账号登录
  3. i.MX8m mini核心板及开发板介绍(MYC-C8MMX)
  4. 别再问我做一个网站多少钱了!
  5. QUARTUS联合modelsim仿真(quartus13.0)
  6. 中国移动BOSS系统的建设和完善
  7. Flink Cep 扩展 - 动态规则更新及Pattern间within()
  8. 常用统计数学公式学习(1)方差与期望值
  9. Servlet的本质以及与Web服务器的关系
  10. html flex 的高度,Flex布局高度撑开不足问题