STM32L431RCT6的按键开发

在进行按键开发时首先来了解轮询和中断两种工作模式。

轮询模式

   很多I/O设备都有一个状态寄存器,用于描述设备当前的工作状态,每当设备状态发生改变时,设备将修改相应状态寄存器位。通过不断查询设备的状态寄存器,CPU就可以了解设备的状态,从而进行必要的I/O操作。为了节约CPU资源,查询工作往往不是连续的,而是定时进行,即轮询即间隔一段时间去判断寄存器的状态。
   轮询方式具有简单、易实现、易控制等优势,在对实时面感性不高,且有大量CPU资源中大量应用。比如说功能较为单一的单片机中就大量使用轮询模式。

轮询方式主要存在以下不足: 

        增加系统开销。无论是任务轮询还是定时器轮询都需要消耗对应的系统资源。 
        无法及时感知设备状态变化。在轮询间隔内的设备状态变化只有在下次轮询时才能被发现,这将无法满足对实时性敏感的应用场合。 
        浪费CPU资源。无论设备是否发生状态改变,轮询总在进行。在实际情况中,大多数设备的状态改变通常不会那么频繁,轮询空转将白白浪费CPU时间片。

中断模式 

  中断就是由硬件或者软件发出的一种IRQ(中断请求)信号,一旦CPU接收到中断信号,CPU就会暂停当前执行的任务,并且保留现场,去响应外设的中断请求。

  中断的工作流程:CPU安装中断处理程序,发生中断,保存现场,识别中断,判断中断号,执行中断服务处理程序,返回现场。

了解了这两种工作模式后我们使用这两种对进行开发。

根据电路图可知按键通过PB12\13\14IO端口进行控制,这些端口通过一个上拉电阻将按键的电压钳制于高电平,当按键按下时端口则为低电平。

因此对端口进行如下设置:

1、将端口设置为输出模式(以PB12为例)

                    

2、设置内部上拉,并对管脚进行命名

                                 

   4、后续其他设置同跑马灯设置,后生成代码。

 3、在main.c中while()循环中添加如下代码:

        if(HAL_GPIO_ReadPin(Key1_GPIO_Port,Key1_Pin) == GPIO_PIN_RESET)
		{
			Blink_led(RedLed, 500);//当按键Key1按下红色LED亮500ms
		}
		if(HAL_GPIO_ReadPin(Key2_GPIO_Port,Key2_Pin) == GPIO_PIN_RESET)
		{
			Blink_led(BlueLed, 500);//当按键Key2按下蓝色LED亮500ms
		}
		if(HAL_GPIO_ReadPin(Key3_GPIO_Port,Key3_Pin) == GPIO_PIN_RESET)
		{
			Blink_led(GreenLed, 500);//当按键Key3按下绿色LED亮500ms
		}

  然后对代码进行编译烧录,并验证实验现象:当按键Key1按下红色LED亮,当按键Key2按下蓝色LED亮,当按键Key3按下绿色LED亮。后将LED亮灯时间延长,例如延迟至2s,重新编译烧录,再次观察实验现象,会发现当按下Key1后,马上按Key2,蓝色LED并不会亮。而这便是轮询模式的特点:轮询模式下,如果CPU正在执行其他的代码,来不及查询按键状态的代码,而导致错过事件的错过。因此类似这样事件的处理,我们一般选用中断的工作模式。进行如下设置:

1、修改管脚的输入模式为中断输入,并对管脚进行命名

             

                   

2、使能中断,并设置中断优先级

               

3、后续其他设置同跑马灯设置,后生成代码。

打开工程,发现HAL_GPIO_EXTI_IRQHandler(中断服务函数) 在stm32f1xx_it.c文件下,接着右键HAL_GPIO_EXTI_IRQHandler(中断服务函数),点击Go To Definition Of " "进入此函数

HAL_GPIO_EXTI_IRQHandler此函数的作用是清除中断标志位,之后进入HAL_GPIO_EXTI_Callback(中断回调函数)中断运行结束后不会立马退出,而是进入HAL_GPIO_EXTI_Callback(中断回调函数),处理完中断回调函数的事件后,再退出中断,所以可以将需要响应的事件代码写入中断回调函数中。

继续进入HAL_GPIO_EXTI_Callback(中断回调函数)

 这是中断回调函数的原型,我们发现该函数定义前有两个下划线,提示我们该函数为虚函数,意味着需自行编写。因此我们通常不将需要响应的事件代码在这写入,而是重新定义一个中断回调函数。

 因此我们在gpio.c中添加一个中断回调函数。

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	switch(GPIO_Pin)
	{
		case Key1_Pin:
			Blink_led(RedLed, 500);
      break;
		
		case Key2_Pin:
			Blink_led(RedLed, 500);
      break;
		
		case Key3_Pin:
			Blink_led(RedLed, 500);
      break;
		
		default:
			break;
   }
}

 最后编译,烧录,观察实验现象。

补充说明

上拉电阻和下拉电阻

上拉电阻:将一个单片机的IO口通过一个电阻与电源VCC相连,固定在高电平。

下拉电阻:将一个单片机的IO口通过一个电阻与地GND相连,固定在低电平。

上拉电阻和下拉电阻2者共同的作用是:避免电压的“悬浮”,造成电路的不稳定。对于上拉电阻和下拉电阻的选择,应结合开关管特性和下级电路的输入特性进行设定;考虑的因素包括:驱动能力与功耗的平衡,下级电路的驱动需求,高低电平的设定,频率特性等等。

其他详情可以参考此博科:http://t.csdn.cn/CVTx0

HAL_GPIO_ReadPin()函数

该函数的作用时读取我们想要知道的引脚的电平状态、函数返回值为0或1。

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

函数参数GPIOx: 是GPIO_TypeDef * 类型,是GPIO寄存器类型。
函数参数: GPIO_Pin:是unit16_t类型,是GPIO寄存器的位端口。

返回值:输入端口引脚值,0或1。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值