100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > TM1638驱动显示板(8数码管+8LED+8按键)单片机C语言程序(按键功能)

TM1638驱动显示板(8数码管+8LED+8按键)单片机C语言程序(按键功能)

时间:2019-02-13 18:42:49

相关推荐

TM1638驱动显示板(8数码管+8LED+8按键)单片机C语言程序(按键功能)

一、概述

上一篇文章记录了TM1638驱动的显示模块的显示功能C语言程序,详见TM1638显示板(8数码管+8LED+8按键)驱动程序(显示功能),本文分享按键的驱动,以及按键的去抖动等操作。

模块如下图:

笔者采用的MCU是STM32F103C8T6,IAR开发环境,使用了HAL库。

二、驱动程序

1. 硬件分析

首先,通过上图,可以看出按键是连接到K3上的;

再看上图手册中对按键功能的描述,可知所有按键连接到同一个K引脚上,不能实现组合按键,按键仅能单个使用。读取按键的4个BYTE时,我们需要把K3引脚对应的值取出,即查看每个BYTE的B0和B4位,有一个为1,则对应的键被按下,又因为无法实现组合按键,所以在取4个BYTE中的K3对应的位时,取到第一个1,即认为对应的按键被按下。

2. 按键读取驱动程序

按键读取程序如下:

/******************************************************************************** 函数名:TM1638_ReadKey* 功 能:TM1638读按键数据* 参 数:无* 返回值:读出的数据* 说 明:实际该显示板只有8个按键,返回值1~8分别为Key1~Key8;所有按键连接K3,无法实现组合按键,只允许一次按一个键;*******************************************************************************/uint8_t TM1638_ReadKey(void){uint8_t u8Data[4], i;uint8_t u8Key = 0;TM1638_STBReset();TM1638_WriteData(0x42);for (i = 0; i < 4; i++){u8Data[i] = TM1638_ReadData();//读BYTE1~BYTE4的数据}TM1638_STBSet();for (i = 0; i < 4; i++)//取出4个BYTE中的键值{if (((u8Data[i] >> 0) & 0x01) == 0x01)//第0位,B0,对应按键为1、3、5、7,计算公式是i*2+1{u8Key = (i * 2 + 1);break;}else{if (((u8Data[i] >> 4) & 0x01) == 0x01)//第4位,B4,对应按键为2、4、6、8,计算公式是i*2+2{u8Key = (i * 2 + 2);break;}}}return u8Key;}

程序注释还算详细,应该不需要再说明了。

3.应用层程序

这里我们实现如下功能:

右侧4位数码管显示实际温度,精确到1位小数;左侧4位数码管显示设定温度,精确到1位小数;

左1按键为设置键,按下时,设定温度闪烁显示,左2键为“+”键,可向上调整设定温度,设置步长为0.1,左3键为“-”键,可向下调整设定温度,设置步长为0.1,再次按设置键,温度设定完成,不再闪烁。

根据人的按键操作反应时间,程序可20ms左右执行一次,扫描时按键被释放,才将按键值返回,完成按键相应的操作,达到去抖动的效果。该方法简单易懂,但缺点是没有长按、双击等操作(可自行扩展)。主要代码如下:

#define KEY_NULL0x00//无#define KEY_SET0x01//设置键#define KEY_UP0x03//向上键#define KEY_DOWN0x05//向下键typedef union{uint8_t byte;struct{uint8_t bSetMode:1;//0正常,1进入设定模式uint8_t b1:1;uint8_t b2:1;uint8_t b3:1;uint8_t b4:1;uint8_t b5:1;uint8_t b6:1;uint8_t b7:1;}bt;}KeyFlag_tu;static uint8_t u8Key_Name;//按键名称static uint8_t u8KeyState;//按键状态,按下或释放static KeyFlag_tu uKey_Flag;static uint32_t u32Key_SettingTemper;//正在设定的温度值#define KEY_RELEASED0x00//键被释放#define KEY_PRESSED0x01//键被按下/******************************************************************************** 函数名:Key_Init* 功 能:初始化* 参 数:无* 返回值:无* 说 明:无*******************************************************************************/void Key_Init(void){u8Key_Name = KEY_NULL;uKey_Flag.byte = 0;u8KeyState = KEY_RELEASED;u32Key_SettingTemper = 0;}/******************************************************************************** 函数名:Key_ScanProcess* 功 能:按键扫描处理* 参 数:无* 返回值:无* 说 明:去抖动,每20ms扫描一次,扫描时按键被释放才会执行案件的操作;仅支持单键、单击*******************************************************************************/void Key_ScanProcess(void){uint8_t u8KeyNum;u8KeyNum = TM1638_ReadKey();//获取键值if (u8KeyNum != 0)//有键按下{u8KeyState = KEY_PRESSED;u8Key_Name = u8KeyNum;//保存按键值}else{u8KeyState = KEY_RELEASED;}if (u8KeyState == KEY_RELEASED)//按键释放{switch (u8Key_Name){case KEY_SET://设置键{if (uKey_Flag.bt.bSetMode){uKey_Flag.bt.bSetMode = 0;//退出设置模式PID_ModifySetTemper(u32Key_SettingTemper);//修改设定温度}else{uKey_Flag.bt.bSetMode = 1;//进入设置模式u32Key_SettingTemper = PID_GetSetTemper();//读取设定温度}}break;case KEY_UP://向上键{if (uKey_Flag.bt.bSetMode)//设置模式{if (u32Key_SettingTemper < (80 * 100)){u32Key_SettingTemper += 10;}}}break;case KEY_DOWN://向下键{if (uKey_Flag.bt.bSetMode)//设置模式{if (u32Key_SettingTemper > (30 * 100)){u32Key_SettingTemper -= 10;}}}break;default:break;}u8Key_Name = KEY_NULL;}}

4.效果

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。