本篇博文最后修改时间:2017年01月20日,17:01。
一、简介
本文介绍STM8L系列如何自定义一个长短按键。
二、实验平台
编译软件:IAR for STM8 1.42.2
硬件平台:stm8l101f3p6开发板
仿真器:ST-LINK
库函数版本:STM8L_STMTouch_Lib_V1.1.0
三、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.NET/feilusia
联系方式:[email protected]
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
香瓜BLE之Android群:541462902
五、基础知识
暂无六、硬件原理图
本文使用PB2作为按键引脚,PB2配置为内部上拉输入,当KEY1按键按下时,PB2被拉低。
七、实验步骤
1、工程中添加长短按键的驱动
1)写一个长短按键的驱动GUA_Key.c (存放在工程的USER文件夹中)
//******************************************************************************
//name: GUA_Key.c
//introduce: 按键驱动
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.14
//******************************************************************************
#include "stm8l10x.h"
#include "GUA_Key.h"
/*********************宏定义************************/
#ifndef U8
typedef unsigned char U8;
#endif
#ifndef U32
typedef unsigned long U32;
#endif
//按键引脚宏
#define GUA_KEY_PORT GPIOB
#define GUA_KEY_PIN GPIO_Pin_2
#define GUA_KEY_MODE GPIO_Mode_In_PU_No_IT
//按键触发宏
#define GUA_KEY_TRIGGER RESET //低电平触发
//按键消抖宏
#define GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT 2000 //短按键消抖数,约20ms
#define GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT 300000 //长按键消抖数,约3S
/*********************内部变量************************/
static 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: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.14
//******************************************************************************
U8 GUA_Key_Scan(void)
{
//触发
if(GPIO_ReadInputDataBit(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_ReadInputDataBit(GUA_KEY_PORT, GUA_KEY_PIN) != GUA_KEY_TRIGGER) || (sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT))
{
//长按键时
if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)
{
return GUA_KEY_STATUS_TRIGGER_LONG;
}
//短按键时
else
{
return GUA_KEY_STATUS_TRIGGER_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: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.14
//******************************************************************************
void GUA_Key_Init(void)
{
//按键IO初始化
GPIO_Init(GUA_KEY_PORT, GUA_KEY_PIN, GUA_KEY_MODE);
}
//******************************************************************************
//name: GUA_Key.h
//introduce: 按键驱动的头文件
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.14
//******************************************************************************
#ifndef _GUA_KEY_H_
#define _GUA_KEY_H_
/*********************宏定义************************/
//按键的触发状态
#define GUA_KEY_STATUS_IDLE 0 //按键没触发
#define GUA_KEY_STATUS_TRIGGER_SHORT 1 //短按键触发
#define GUA_KEY_STATUS_TRIGGER_LONG 2 //长按键触发
#define GUA_KEY_STATUS_NO_LOOSEN 3 //长按键触发后未松开
/*********************外部函数声明************************/
unsigned char GUA_Key_Scan(void);
void GUA_Key_Init(void);
#endif
4)添加驱动的路径
$PROJ_DIR$\..\USER
注意USER文件夹是与“Project”等文件夹同级的自定义文件,用于存放香瓜写的代码。
2、应用层中调用
1)添加头文件(main.c中)
#include "GUA_Key.h"
//按键初始化
GUA_Key_Init();
①替换main.c
//******************************************************************************
//name: main.c
//introduce: 主函数
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.14
//******************************************************************************
#include "stm8l10x.h"
#include "main.h"
#include "GUA_Key.h"
/*********************宏定义************************/
#ifndef U8
typedef unsigned char U8;
#endif
#ifndef U16
typedef unsigned short U16;
#endif
#ifndef U32
typedef unsigned long U32;
#endif
#ifndef int32
typedef signed long int32;
#endif
/*********************外部变量************************/
U8 gGUA_Function = 0; //功能码
/*********************内部函数声明************************/
static void CLK_Init(void);
static void GUA_Init(void);
//******************************************************************************
//name: CLK_Init
//introduce: 时钟初始化
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.14
//******************************************************************************
static void CLK_Init(void)
{
CLK_DeInit();
CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv1); //时钟1分频,16MHz
}
//******************************************************************************
//name: GUA_Init
//introduce: 初始化
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.14
//******************************************************************************
static void GUA_Init(void)
{
//关全局中断
asm("sim");
//晶振初始化
CLK_Init();
//按键初始化
GUA_Key_Init();
//开全局中断
asm("rim");
}
//******************************************************************************
//name: main
//introduce: 主函数
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.14
//******************************************************************************
void main(void)
{
U8 nRet = 0;
//初始化
GUA_Init();
while(1)
{
switch(gGUA_Function)
{
//空闲
case FUNC_IDLE_EVENT:
{
//检测按键当前状态
nRet = GUA_Key_Scan();
//短按键触发时
if(nRet == GUA_KEY_STATUS_TRIGGER_SHORT)
{
gGUA_Function = FUNC_GUA_KEY_SHORT_EVENT;
}
//长按键触发时
else if(nRet == GUA_KEY_STATUS_TRIGGER_LONG)
{
gGUA_Function = FUNC_GUA_KEY_LONG_EVENT;
}
break;
}
//短按键处理
case FUNC_GUA_KEY_SHORT_EVENT:
{
//返回空闲状态
gGUA_Function = FUNC_IDLE_EVENT;
break;
}
//长按键处理
case FUNC_GUA_KEY_LONG_EVENT:
{
//返回空闲状态
gGUA_Function = FUNC_IDLE_EVENT;
break;
}
//其他
default:
{
//返回空闲状态
gGUA_Function = FUNC_IDLE_EVENT;
break;
}
}
}
}
//******************************************************************************
//name: main.h
//introduce: 主函数的头文件
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.11.14
//******************************************************************************
#ifndef _MAIN_H_
#define _MAIN_H_
/*********************宏定义************************/
//主轮询的宏
#define FUNC_IDLE_EVENT 0x00 //空闲
#define FUNC_GUA_KEY_SHORT_EVENT 0x10 //短按键处理事件
#define FUNC_GUA_KEY_LONG_EVENT 0x11 //长按键处理事件
/*********************外部变量************************/
extern u8 gGUA_Function; //功能码
#endif
九、实验结果
仿真并设置断点查看长短按键的处理,可发现:
1、3S以内的按键被判定为短按键,并跳转至短按键处理事件中处理。
2、3S以上的按键被判定为长按键,并跳转至长按键处理事件中处理。处理之后的下一次按键判定必须等待按键松开后才开始。
因此,实验成功。