5. Stm32f407 key查询方式示例
硬件平台: stm32f407ve
软件平台: win10 (OS Name: Microsoft Windows 10 Enterprise
OS Version: 10.0.18363 N/A Build 18363)
Keil5 5.26.2
HAL库版本: 2.14.0(目前下载的最新的)
时间: 2020-02-10
实验介绍:
本次是使用hal库进行按键循环查询实验。(根据之前建立的模板操作,这里不再建立工程模板)
- 首先看原理图,按键的原理比较简单,按下去,电路短路,松开,电路开路。在下图中,我们看到与cpu的连接时PE10,11,12 3个引脚,松开按钮的时候,对于的引脚是高电平(上拉电阻)。按键按下去之后,对应得引脚为低电平。
- 这个时候,我们可以看到芯片引出的3个引脚的电平由按键控制,而不是由cpu控制(对比led的引脚的方式,led的引脚的状态是由cpu控制的)。这个时候,cpu是要获取这个引脚的状态,才能知道按键是否按下。这就是常说的输入模式(led的引脚应该配置为输出模式)。
- 按键的状态(按下或松开)是不确定的,是由外部的人为控制的,人可能随时想按一下就按一下,可能很长时间也不按。对cpu而言,cpu无法得知人什么时候会按下按键。所以cpu想知道按键是否被按下,就需要时时查询按键对应的引脚的状态(在程序中变现为循环查询)。这也就是我们这次使用的查询方法。在生活中类似于我有一个手机,这个手机没有铃声,没有震动,只能在来电的时候亮屏,为了不错过任何一个电话,我就要不断的盯着这个手机屏幕,这个过程就是一直在查询。(除了查询方式之外,还可以使用中断方式。)
4.那么我们对于按键的操作就比较简单了,首先初始化按键对应得引脚为输入模式,然后在循环中不断查询引脚的状态就可以了,如果获得的状态为低电平就是按键被按下了,如果是高电平,那么就是按键时松开的。
5.程序如下
#include <stm32f4xx.h>
void led_init(void)
{
GPIO_InitTypeDef GPIO_Init;
//1.时钟使能
__HAL_RCC_GPIOE_CLK_ENABLE();
//2.端口设置
GPIO_Init.Mode = GPIO_MODE_OUTPUT_OD; //输出开漏模式
GPIO_Init.Pin = GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_Init.Pull = GPIO_PULLUP;
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
// GPIO_Init.Alternate = ; //GPIO的mode设置位复用功能的时候,才会配置复用功能
HAL_GPIO_Init(GPIOE, &GPIO_Init);
//3.点亮或熄灭灯
}
/*按键初始化*/
void key_init(void)
{
GPIO_InitTypeDef GPIO_Init;
//1.时钟使能,按键使用的时GPIOE
__HAL_RCC_GPIOE_CLK_ENABLE();
//2.端口设置
GPIO_Init.Mode = GPIO_MODE_INPUT; //输入模式
GPIO_Init.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; //设置的引脚
GPIO_Init.Pull = GPIO_NOPULL; //上拉电阻可以有也可以没有,电路本身有上拉
// GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW; //这个是设置输出速度,输入模式可以不管
// GPIO_Init.Alternate = ; //GPIO的mode设置位复用功能的时候,才会配置复用功能
HAL_GPIO_Init(GPIOE, &GPIO_Init);
}
/*
按键测试程序,我的例子实现为,(这是最简单的方法)
第一个按键按下的时候,第一个灯点亮
第二个按键按下的时候,第二个灯点亮
第三个按键按下的时候,第三个灯点亮
*/
int main(void)
{
int i;
GPIO_PinState pins;
HAL_Init(); //必须在第一个语句执行
led_init();
key_init();
while(1)
{
//1.读取第一个按键的状态,根据按键的状态控制灯的状态
pins = HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_10);
if(pins == GPIO_PIN_RESET) //按键被按下了
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13, GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13, GPIO_PIN_SET);
}
//2.读取第二个按键的状态,根据按键的状态控制灯的状态
pins = HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_11);
if(pins == GPIO_PIN_RESET) //按键被按下了
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_14, GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_14, GPIO_PIN_SET);
}
//3.读取第三个按键的状态,根据按键的状态控制灯的状态
pins = HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_12);
if(pins == GPIO_PIN_RESET) //按键被按下了
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_15, GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_15, GPIO_PIN_SET);
}
}
}
void SysTick_Handler(void)
{
HAL_IncTick();
}
6.当然加上一些软件方法,可以实现按下一次点亮,再按下一次松开等操作。这个就作为练习了。