本文最后修改时间:2018年10月22日 01:57
一、本节简介
本文介绍STM8S系列如何实现按键的短按、长按、连击。
二、实验平台
编译软件:IAR for STM8 1.42.2
硬件平台:stm8s003f3p6开发板
仿真器:ST-LINK
库函数版本:V2.0.0
三、版权声明
1)作者:甜甜的大香瓜
2)声明:喝水不忘挖井人,转载请注明出处。
3)纠错/业务合作:897503845@qq.com
4)香瓜嵌入式之STM8/STM32群:164311667
5)本文出处:原创连载资料《简单粗暴学STM8和STM32》
6)完整开源资料下载地址(电脑端打开):opengua.taobao.com
四、实验前提
1、在进行本文步骤前,请先阅读以下章节:
1)《简单粗暴学STM8和STM32》的“第一章和第三章”章节。
2、在进行本文步骤前,请先实现以下章节:
1)《简单粗暴学STM8和STM32》的《STM8S之内外部16M晶振》。
五、基础知识
暂无
六、硬件原理
由上图可知当K1松开时PD3为高电平,K1按下后PD3为低电平。
七、实验步骤
1、工程中添加自己写的按键驱动
1)写一个按键驱动GUA_Key.c(存放在工程的USER文件夹中)
//********************************************************************** //name: GUA_Key.c //introduce: 按键驱动 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group: 香瓜单片机之STM8/STM32(164311667) //shop: opengua.taobao.com //changetime: 2018.10.16 //********************************************************************** #include "stm8s.h" #include "GUA_Key.h" /*********************宏定义************************/ //按键触发宏 #define GUA_KEY_TRIGGER RESET //低电平触发
//目测的时钟基准 //#define GUA_KEY_STANDARD_1MS 100 //按键消抖宏 #define GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT 1000 //短按键消抖数 #define GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT 150000 //长按2.5消抖数 /*********************内部变量************************/ static GUA_U32 sGUA_Key_DisappearsShakes_TriggerCount = 0; //消抖时的触发状态计数值
//********************************************************************** //name: GUA_Key_Scan //introduce: 按键检测触发状态 //parameter: none //return: GUA_KEY_STATUS_IDLE or GUA_KEY_STATUS_TRIGGER_SHORT or GUA_KEY_STATUS_TRIGGER_LONG or GUA_KEY_STATUS_NO_LOOSEN //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group: 香瓜单片机之STM8/STM32(164311667) //shop: opengua.taobao.com //changetime: 2018.10.16 //********************************************************************** GUA_U8 GUA_Key_Scan(void) { GUA_U32 nGUA_TimeOut = 0;
//触发 if(GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) == GUA_KEY_TRIGGER) { //如果上一次按键是长按键结束的,需要检测到松开方可开始下一次计数 if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT) { return GUA_KEY_STATUS_NO_LOOSEN; } //计数 sGUA_Key_DisappearsShakes_TriggerCount++;
//判断计数是否足够 while(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT) { //检测到松开、超时的时候,则处理 if((GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) != GUA_KEY_TRIGGER) || (sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)) { //长按2.5S时 if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT) { //返回 return GUA_KEY_STATUS_TRIGGER_LONG; } //短按键时 else { //超时计数值清零 nGUA_TimeOut = 0;
//检测是否有连按 while((GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) != GUA_KEY_TRIGGER)) { //没有被按下,超时,则表示只有1次按键 if(nGUA_TimeOut++ > 100000) { //计数值清零 sGUA_Key_DisappearsShakes_TriggerCount = 0;
return GUA_KEY_STATUS_TRIGGER_SHORT; } }
//判断计数是否足够 while(GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) == GUA_KEY_TRIGGER) { //开始计数 sGUA_Key_DisappearsShakes_TriggerCount++; //检测到松开、超时的时候,则处理 if((GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) != GUA_KEY_TRIGGER) || (sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)) { //长按2.5S时 if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT) { //清除计数器 sGUA_Key_DisappearsShakes_TriggerCount = 0;
//返回 return GUA_KEY_STATUS_TRIGGER_LONG; } //短按键时 else { //清除计数器 sGUA_Key_DisappearsShakes_TriggerCount = 0;
//返回 return GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT; } } }
//清除计数器 sGUA_Key_DisappearsShakes_TriggerCount = 0;
//返回 return GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT; } }
//继续计数用来判断长短按键 sGUA_Key_DisappearsShakes_TriggerCount++; } } //未触发 else { sGUA_Key_DisappearsShakes_TriggerCount = 0; }
return GUA_KEY_STATUS_IDLE; } //********************************************************************** //name: GUA_Key_Init //introduce: 按键初始化 //parameter: none //return: none //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group: 香瓜单片机之STM8/STM32(164311667) //shop: opengua.taobao.com //changetime: 2018.10.16 //********************************************************************** void GUA_Key_Init(void) { //按键IO初始化 GPIO_Init(GUA_KEY_PORT, GUA_KEY_PIN, GUA_KEY_MODE); } |
2)写一个驱动头文件GUA_Key.h(存放在工程的USER文件夹中)
//********************************************************************** //name: GUA_Key.h //introduce: 按键驱动的头文件 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group: 香瓜单片机之STM8/STM32(164311667) //shop: opengua.taobao.com //changetime: 2018.10.16 //********************************************************************** #ifndef _GUA_KEY_H_ #define _GUA_KEY_H_ /*********************宏定义************************/ //类型宏 #ifndef GUA_C typedef char GUA_C; #endif #ifndef GUA_U8 typedef unsigned char GUA_U8; #endif #ifndef GUA_8 typedef signed char GUA_8; #endif #ifndef GUA_U16 typedef unsigned short GUA_U16; #endif #ifndef GUA_16 typedef signed short GUA_16; #endif #ifndef GUA_U32 typedef unsigned long GUA_U32; #endif #ifndef GUA_32 typedef signed long GUA_32; #endif #ifndef GUA_U64 typedef unsigned long long GUA_U64; #endif #ifndef GUA_64 typedef signed long long GUA_64; #endif //按键引脚宏 #define GUA_KEY_PORT GPIOD #define GUA_KEY_PIN GPIO_PIN_3 #define GUA_KEY_MODE GPIO_MODE_IN_PU_NO_IT //按键的触发状态 #define GUA_KEY_STATUS_IDLE 0 //按键没触发 #define GUA_KEY_STATUS_TRIGGER_SHORT 1 //短按键触发 #define GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT 2 //双击触发 #define GUA_KEY_STATUS_TRIGGER_LONG 3 //长按键2.5S触发 #define GUA_KEY_STATUS_NO_LOOSEN 4 //按键没松开 /*********************外部函数声明************************/ GUA_U8 GUA_Key_Scan(void); void GUA_Key_Init(void); #endif |
3)工程中添加GUA_Key.c
4)添加驱动的路径
$PROJ_DIR$\..\USER |
注意USER文件夹是与“Project”、“FWlib”文件夹同级的自定义文件,用于存放香瓜写的代码。
2、添加库的驱动
1)添加库的驱动文件
2)添加库的驱动头文件(stm8s_conf.h中)
#include "stm8s_gpio.h" |
3、应用层中调用
1)添加头文件(main.c中)
#include "GUA_Key.h" |
2)初始化(main.c的main函数中)
//按键初始化 GUA_Key_Init(); |
3)添加按键判断的逻辑代码(main.c的main函数中)
GUA_U8 nGUA_Ret; //检测按键当前状态 nGUA_Ret = GUA_Key_Scan(); //短按键触发时 if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_SHORT) { } //连击触发时 else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT) { } //长按键触发时 else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_LONG) { |
} |
八、注意事项
暂无
九、实验结果
暂无