历史上的今天
今天是:2025年02月20日(星期四)
2021年02月20日 | 按键实验(GPIO的输入模式)
2021-02-20 来源:eefocus
@按键实验(GPIO的输入模式)
#引言
在之前的实验中,小罗同学使用的都只是GPIO的输出模式,这次的按键实验虽然比较简单,但也是我第一次接触GPIO的输入,所以还是想写点东西记录一下。
#按键模块电路图
我手中的开发板除去复位按键后还有其余四个按键,电路结构图如下:

以上四个按键所对应的管脚编号分别为:PA0、PE4、PE3、PE2。由图可知,KEY_UP为高电平有效,其他三个均为低电平有效。
#按键配置
大家都知道,在使用引脚之前首先要进行相应的配置来初始化,相关代码如下:
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct; //先对挂接在PA0的KEY_UP进行配置
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN; //由于改端口高电平视为有效,所以默认为低电平
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; //由于改端口低电平视为有效,所以默认为高电平
GPIO_Init(GPIOE,&GPIO_InitStruct);
}
这里要注意的是要根据电路图的连接来判断究竟是选择GPIO_PuPd_UP还是GPIO_PuPd_DOWN(我就是因为这里的配置错误而调了半天╮(╯▽╰)╭)
#扫描函数
初始化配置完成之后,接下来要进行的就是利用判断语句来判断究竟是哪个引脚接收到了有效电平,由于这里我们需要一个返回值,所以定义为u8类型,而形参mode则用于选择是连续扫描还是单次扫描。
u8 KEY_scan(u8 mode) //自定义扫描函数即模式。mode为1时,连续扫描;为0时为单次扫描
{
u8 flag=1; //flag作为一个标志数,若为1则表示需要进行判断
if(flag&&(KEY_UP==1||KEY_LEFT==0||KEY_DOWN==0||KEY_RIGHT==0)) //判断是否有按键按下
{
flag=0;
delay_nms(10); //通过延时消除按键抖动,再次进行按键的判断
if(KEY_UP==1) //由于KEY_UP为高电平有效,所以若为1,则证明该按键按下,返回相应的key_up,以下同理。
{
return key_up;
}
else if(KEY_LEFT==0)
{
return key_left;
}
else if(KEY_DOWN==0)
{
return key_down;
}
else if(KEY_RIGHT==0)
{
return key_right;
}
}
else if(KEY_UP==0&&KEY_LEFT==1&&KEY_DOWN==1&&KEY_RIGHT==1)
{
flag=1;
}
if(mode==1)
{
flag=1;
}
return 0;
}
在上面的代码中,运用到了头文件中的两部分宏定义,分别为:
#define KEY_UP PAin(0) //PAin(0)等函数的封装详见我的另一篇博文(https://blog.csdn.net/qq_45683640/article/details/105476554)
#define KEY_LEFT PEin(2)
#define KEY_DOWN PEin(3)
#define KEY_RIGHT PEin(4)
#define key_up 1 //在这里,1 2 3 4并没有重要的实际含义,只是进行区别的返回值,不为0即可
#define key_left 4
#define key_down 3
#define key_right 2
相关的解释我基本上在注释里写的比较清楚了,有问题的小伙伴阔以留言评论哈~
#实验主程序
#include "stm32f4xx.h"
#include "led.h"
#include "bit_operation.h"
#include "Systick.h"
#include "beep.h"
#include "key.h"
int main()
{
BEEP_Init();
KEY_Init();
SysTick_Init(168); //系统时钟为168M
RCC_HSE_Config(8,336,2,7);
LED_Init();
int key;
while(1)
{
key=KEY_scan(0);
switch(key)
{
case key_up: led2=0; break; //灯亮
case key_left: beep=0; break; //蜂鸣器不响
case key_down: led2=1; break; //灯灭
case key_right: beep=1; break; //蜂鸣器响
}
}
}
史海拾趣
|
很久没上论坛了啊,最近一段时间太忙,今天上了下,发现人气还是很火,真的不错,现在很多的论坛,qq群虽然都很多人,但是讨论的太少,交流也有限。(不知道是不是人人都不爱说话的原因) 我支持我们这个论坛,希望能一直这么热闹下去,和大家一起 ...… 查看全部问答> |
|
请问下UCOS+ARM9模式下如何编写串口通信 最近将UCOS移植到了ARM9下,但是编写串口通信时出了问题,主要是目前串口无法接受到PC机上的数据,请问各位朋友有谁碰到过类似的问题?… 查看全部问答> |
|
程序中在计算数值的时候将AD中断关闭,计算完成后再将AD中断打开,但是现在发现在AD采样率低的时候AD转换结果没问题,但是提高了采样率,AD结果就不对了,寄存器显示OVERRUN,貌似是数据丢失或者覆盖,这是咋回事呢? 开关AD中断不该影响AD转换啊? ...… 查看全部问答> |
|
本帖最后由 lyzhangxiang 于 2015-7-2 23:07 编辑 搭建了一下开发环境,已经能够运行contiki了,基本和我预料的一样,分分钟可以跑contiki,就是这么easy。 最简单的hello-world 复杂一点的cc26xx-web-demo 效果 mqtt+coap+sensor ...… 查看全部问答> |




