2025年2021-04-14 第四次 按键输入实验

2021-04-14 第四次 按键输入实验按键输入实验 GPIO 做输入 h 目录 一 按键实验硬件连接 二 GPIO 输入操作说明 三 按键实验 一 STM32 mini 板 1 GPIO 引脚图及相关配置 WK UP 与 PA0 相连 KEY0 与 PC5 相连 KEY1 与 PA15 相连 WK UP 一端连接高电平 一端连接 IO 口 KEY0 和 KEY1 一端连接地

大家好,我是讯享网,很高兴认识大家。

按键输入实验—GPIO做输入h

目录:

一. 按键实验硬件连接

二. GPIO输入操作说明

三. 按键实验

STM32 mini板

1. GPIO引脚图及相关配置

在这里插入图片描述
讯享网
WK UP与PA0相连
KEY0与PC5相连
KEY1与PA15相连
WK UP一端连接高电平,一端连接IO口
KEY0和KEY1一端连接地,一端连接IO口
如果按键按下,WK UP会检测到高电平。而KEY0和KEY1会检测到低电平。
还有一点需要注意:
除了KEY1 有上拉电阻(与 JTDI 共用),其他两个都没有上下拉电阻,所以,需要在 STM32 内部设置上下拉。

2. GPIO输入操作说明

2.1 读取IO口输入电平调用库函数

unit8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx,unit16_t GPIO Pin);

2.2 读取IO口输入电平操作寄存器为:

GPIOx_IDR:端口输入寄存器

2.3 使用位带操作读取IO口输入电平:

3. 编写按键输入实验

3.1 使能按键对应IO口时钟。调用函数:
 RCC_APB2PeriphClockCmd(); 

讯享网
3.2 初始化IO模式:上拉/下拉输入。调用函数:
讯享网 GPIO_Init(); 
3.3 扫描IO口电平(库函数/寄存器/位操作)。
3.4 按键扫描

C语言关键字:static

  1. static申明的局部变量,存储在静态存储区。
  2. 它在函数调用结束之后,不会被释放,它的值会一直保留下来
  3. 所以可以说static申明的局部变量,具有记忆功能。
    例如:
    1:
    在这里插入图片描述
    结果:1,1,1…
    2:
    在这里插入图片描述
    static关键字具有存储记忆功能,能存入返回的上一时刻flag的值。
    此时的flag++是在上一时刻的flag的基础上进行加1。
按键扫描的两种模式:

1.支持连续扫描模式
连续按下时,会认为有多个数值,比如我们的遥控板,一直按下则频道会一直增加。
2.不支持连续模式
连续按下时,仅认为只有一个数值,比如我们的电源按键,长时间的按下并不会一直有效,从而频繁的开关机,就算按的时间很长,也只会进行一次。
只有在前一时刻的状态与这个时候的状态不想同时,会记一个数值。比如之前是高电平,现在是低电平就记一次,一直是低电平,则不继续计数进行。

不支持连续按

u8 KEY_Scan(void) { 
    static u8 key_up=1; if(key_up && KEY按下)//若key_up=1时,1&&KEY=KEY;若key_up=0时,0&&KEY=0; { 
    delay_ms(10);//延时,防抖 key_up=0;//标记这次key已经按下 if(KEY确实按下) { 
    return KEY_VALUE; } } else if(KEY没有按下) key_up=1; } 

混合模式:

这里加了个mode。当mode=1,支持连续按。当mode=0,不支持连续按

讯享网u8 KEY_Scan(u8 mode) { 
    static u8 key_up=1;//默认刚开始为高电平 if(mode==1) key_up=1;//mode=1,支持连续按,key-up永远等于1;mode=0,则此行代码无用,不支持连续按; if(key_up && KEY按下) { 
    delay_ms(10);//延时,防抖 key_up=0;//标记这次key已经按下 if(KEY确实按下) { 
    return KEY_VALUE;//识别到按下,返回KEY的真实值 } } else if(KEY没有按下) key_up=1;//表示没有扫描到按下,则返回 key_up=1 return 没有按下 } 
编写

编写key.c

#include "key.h" #include "delay.h" //按键初始化函数  //PA15和PC5 设置成输入 void KEY_Init(void) { 
    GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);//使能PORTA,PORTC时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭jtag,使能SWD,可以用SWD模式调试 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//PA15 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA15 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PC5 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入 GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC5 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PA0 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0 } //按键处理函数 //返回按键值 //mode:0,不支持连续按;1,支持连续按; //返回值: //0,没有任何按键按下 //KEY0_PRES,KEY0按下 //KEY1_PRES,KEY1按下 //WKUP_PRES,WK_UP按下  //注意此函数有响应优先级,KEY0>KEY1>WK_UP!! u8 KEY_Scan(u8 mode) { 
    static u8 key_up=1;//按键按松开标志 if(mode)key_up=1; //支持连按  if(key_up&&(KEY0==0||KEY1==0||WK_UP==1)) { 
    delay_ms(10);//去抖动  key_up=0; if(KEY0==0)return KEY0_PRES; else if(KEY1==0)return KEY1_PRES; else if(WK_UP==1)return WKUP_PRES; }else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1; return 0;// 无按键按下 } 

编写led.c

讯享网#include "led.h" //初始化PB5和PE5为输出口.并使能这两个口的时钟  //LED IO初始化 void LED_Init(void) { 
    GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE); //使能PA,PD端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PA.8 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.8 GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA.8 输出高 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置, 推挽输出 GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽输出 ,IO口速度为50MHz GPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 输出高  } 

编写main.c

#include "led.h" #include "delay.h" #include "sys.h" #include "key.h" int main(void) { 
    u8 t=0; delay_init(); //延时函数初始化  LED_Init(); //初始化与LED连接的硬件接口 KEY_Init(); //初始化与按键连接的硬件接口 LED0=0; //点亮LED while(1) { 
    t=KEY_Scan(0); //得到键值 switch(t) { 
    case KEY0_PRES: LED0=!LED0; break; case KEY1_PRES: LED1=!LED1; break; case WKUP_PRES: LED0=!LED0; LED1=!LED1; break; default: delay_ms(10); } } } 
小讯
上一篇 2025-03-22 10:03
下一篇 2025-03-06 10:29

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/50848.html