找回密码
 注册

QQ登录

只需一步,快速开始

搜索

STM32固件库使用–按键输入程序

[复制链接]
路漫漫 发表于 2020-6-4 16:56:21 | 显示全部楼层 |阅读模式
简介
1.硬件
STM32F103C8T6 独立按键
2.软件
keil软件

硬件部分
1.按键分类与输入原理

按键按照结构原理科分为两类,一类是触点式开关按键,如机械式开关、导电橡胶式开关灯;另一类是无触点式开关按键,如电气式按键,磁感应按键等。前者造价低,后者寿命长。目前,微机系统中最常见的是触点式开关按键。

在单片机应用系统中,除了复位按键有专门的复位电路及专一的复位功能外,其他按键都是以开关状态来设置控制功能或输入数据的。当所设置的功能键或数字键按下时,计算机应用系统应完成该按键所设定的功能,键信息输入时与软件结构密切相关的过程。

对于一组键或一个键盘,总有一个接口电路与CPU相连。CPU可以采用查询或中断方式了解有无将按键输入,并检查是哪一个按键按下,将该键号送人累加器,然后通过跳转指令转入执行该键的功能程序,执行完成后再返回主程序。

2.按键结构与特点

微机键盘通常使用机械触点式按键开关,其主要功能式把机械上的通断转换为电气上的逻辑关系。也就是说,它能提供标准的TTL逻辑电平,以便于通用数字系统的逻辑电平相容。机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定的时间触点机械抖动,然后其触点才稳定下来。其抖动过程如下图1所示,抖动时间的长短与开关的机械特性有关,一般为5-10ms。在触点抖动期间检测按键的通与断,可能导致判断出错,即按键一次按下或释放错误的被认为是多次操作,这种情况是不允许出现的。为了克服你、按键触点机械抖动所致的检测误判,必须采取消抖措施。按键较少时,可采用硬件消抖;按键较多式,采用软件消抖。


按键编码

一组按键或键盘都要通过I/O口线查询按键的开关状态。根据键盘结构的不同,采用不同的编码。无论有无编码,以及采用什么编码,最后都要转换成为与累加器中数值相对应的键值,以实现按键功能程序的跳转。

(2)键盘程序

一个完整的键盘控制程序应具备以下功能:

a.检测有无按键按下,并采取硬件或软件措施消抖。

b.有可靠的逻辑处理办法。每次只处理一个按键,期间对任何按键的操作对系统不产生影响,且无论一次按键 时间有多长,系统仅执行一次按键功能程序。

c.准确输出按键值(或键号),以满足跳转指令要求。

3.独立按键

(1)独立按键

单片机控制系统中,如果只需要几个功能键,此时,可采用独立式按键结构。

独立按键式直接用I/O口线构成的单个按键电路,其特点式每个按键单独占用一根I/O口线,每个按键的工作不会影响其他I/O口线的状态。独立按键的典型应用如图所示。独立式按键电路配置灵活,软件结构简单,但每个按键必须占用一个I/O口线,因此,在按键较多时,I/O口线浪费较大,不宜采用。
1.png 2.png

独立按键的软件常采用查询式结构。先逐位查询没跟I/O口线的输入状态,如某一根I/O口线输入为低电平,则可确认该I/O口线所对应的按键已按下,然后,再转向该键的功能处理程序。
软件部分

key.c

  1. #include"key.h"
  2. void KEY_GPIO_Config(void)
  3. {
  4.         GPIO_InitTypeDef GPIO_InitStructure;         //定义结构体指针变量
  5.         RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);  
  6. //开启按键端口的时钟
  7.         /*按键输入控制GPIO端口的步骤*/
  8.         /*
  9.           {
  10.    1.选择按键的引脚
  11.    2.设置按键的引脚为浮空输入
  12.    3.使用结构体初始化按键
  13.    }
  14.         */
  15.   //key1
  16.         GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  18.         GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);
  19.         //key2
  20.         GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN;
  21.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  22.         GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);        
  23.         
  24. }
  25. /*
  26. * 函数名:Key_Scan
  27. * 描述  :检测是否有按键按下
  28. * 输入  :GPIOx:x 可以是 A,B,C,D或者 E
  29. *                     GPIO_Pin:待读取的端口位         
  30. * 输出  :KEY_OFF(没按下按键)、KEY_ON(按下按键)
  31. */
  32. uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
  33. {        /*检测是否有按键按下 */
  34.         if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON )  
  35.         {         /*等待按键释放 *///松手检测
  36.                 while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON);           
  37.                 return         KEY_ON;         
  38.         }
  39.         else
  40.                 return KEY_OFF;
  41. }

复制代码
key.h

  1. #ifndef __KEY_H
  2. #define __KEY_H

  3. #include "stm32f10x.h"
  4. /*
  5. 注意:该引脚定义是根据野火STM32F103霸道开发板的原理图定义的,如果需要自行的设计需要重新更改宏定义选择不同的GPIO端口
  6. STM32F103ZET6芯片共有144个引脚
  7. 其中:GPIOA,GPIOB,GPIOC,GPIOD,GPIOE
  8. */

  9. //  引脚定义
  10. #define    KEY1_GPIO_CLK     RCC_APB2Periph_GPIOA
  11. #define    KEY1_GPIO_PORT    GPIOA                           
  12. #define    KEY1_GPIO_PIN         GPIO_Pin_0

  13. #define    KEY2_GPIO_CLK     RCC_APB2Periph_GPIOC
  14. #define    KEY2_GPIO_PORT    GPIOC                  
  15. #define    KEY2_GPIO_PIN         GPIO_Pin_13


  16. /** 按键按下标置宏
  17.         *  按键按下为高电平,设置 KEY_ON=1, KEY_OFF=0
  18.         *  若按键按下为低电平,把宏设置成KEY_ON=0 ,KEY_OFF=1 即可
  19.         */
  20. #define KEY_ON        1
  21. #define KEY_OFF        0

  22. void KEY_GPIO_Config(void);
  23. uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);

  24. #endif
复制代码
main.c
  1. #include "stm32f10x.h"   
  2. #include "key.h"

  3. int main(void)
  4. {
  5.         
  6.           LED_GPIO_Config();
  7.           KEY_GPIO_Config();
  8.                 while(1)                           
  9.         {           
  10.                 if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON  )
  11.                 {
  12.                         GPIO_ResetBits(LED1_GPIO_PORT , LED1_GPIO_PIN);//开
  13.                         GPIO_SetBits(LED2_GPIO_PORT   , LED2_GPIO_PIN);//关
  14.                         GPIO_SetBits(LED3_GPIO_PORT   , LED3_GPIO_PIN);//关
  15.                 }  

  16.                 if( Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON  )
  17.                 {
  18.                     GPIO_SetBits(LED1_GPIO_PORT , LED1_GPIO_PIN);//关
  19.                         GPIO_SetBits(LED2_GPIO_PORT , LED2_GPIO_PIN);//关
  20.                         GPIO_SetBits(LED3_GPIO_PORT , LED3_GPIO_PIN);//关
  21.                         
  22.                 }               
  23.         }
  24. }
复制代码

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-4-26 05:58

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表