历史上的今天
今天是:2025年02月15日(星期六)
2019年02月15日 | 【单片机笔记】单个按键实现单击、双击、长按的实现
2019-02-15 来源:eefocus
直接贴上源码和测试例程,附带的都有中文注释不多做解释。
底层驱动:
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
#define key_no 0
#define key_click 1
#define key_double 2
#define key_long 3
#define key_input P30
/***************************************************************************
程序功能:一个按键的单击、双击、长按。三种按键方式,然后做不同的处理。
***************************************************************************/
static unsigned char key_driver(void)
{
static unsigned char key_state_buffer1 = key_state_0;
static unsigned char key_timer_cnt1 = 0;
unsigned char key_return = key_no;
unsigned char key;
key = key_input; //read the I/O states
switch(key_state_buffer1)
{
case key_state_0:
if(key == 0)
key_state_buffer1 = key_state_1;
//按键被按下,状态转换到按键消抖和确认状态//
break;
case key_state_1:
if(key == 0)
{
key_timer_cnt1 = 0;
key_state_buffer1 = key_state_2;
//按键仍然处于按下状态
//消抖完成,key_timer开始准备计时
//状态切换到按下时间计时状态
}
else
key_state_buffer1 = key_state_0;
//按键已经抬起,回到按键初始状态
break; //完成软件消抖
case key_state_2:
if(key == 1)
{
key_return = key_click; //按键抬起,产生一次click操作
key_state_buffer1 = key_state_0; //转换到按键初始状态
}
else if(++key_timer_cnt1 >= 100) //按键继续按下,计时超过1000ms
{
key_return = key_long; //送回长按事件
key_state_buffer1 = key_state_3; //转换到等待按键释放状态
}
break;
case key_state_3: //等待按键释放
if(key == 1) //按键释放
key_state_buffer1 = key_state_0; //切回按键初始状态
break;
}
return key_return;
}
/***************************************************************************
函数功能:中层按键处理函数,调用底层函数一次,处理双击事件的判断,
返回上层正确的无键、单击、双击、长按四种状态
本函数由上层循环调用,间隔10ms
***************************************************************************/
unsigned char key_read(void)
{
static unsigned char key_state_buffer2 = key_state_0;
static unsigned char key_timer_cnt2 = 0;
unsigned char key_return = key_no;
unsigned char key;
key = key_driver();
switch(key_state_buffer2)
{
case key_state_0:
if(key == key_click)
{
key_timer_cnt2 = 0; //第一次单击,不返回,到下个状态判断是否会出现双击
key_state_buffer2 = key_state_1;
}
else
key_return = key; //对于无键、长按,返回原事件
break;
case key_state_1:
if(key == key_click) //又一次单击,时间间隔小于500ms
{
key_return = key_double; //返回双击事件,回到初始状态
key_state_buffer2 = key_state_0;
}
else if(++key_timer_cnt2 >= 50)
{
//这里500ms内肯定读到的都是无键事件,因为长按大于1000ms
//在1s前底层返回的都是无键
key_return = key_click; //500ms内没有再次出现单击事件,返回单击事件
key_state_buffer2 = key_state_0; //返回初始状态
}
break;
}
return key_return;
}
测试例程(基于51内核)
void main(void)
{
u8 cnt_1ms=0,cnt_100ms=0;
u8 key_value = 0;
u8 led_flash=0;
GPIO_Configuration();
P3M1 &= ~(1<<0);P3M2 &= ~(1<<0); //P30准双向
P1M1 &= ~(1<<2);P1M2 |= (1<<2); //P12推挽
P12=0;Delay_ms(500);P12=1;Delay_ms(500);IWDG_Feed();
P12=0;Delay_ms(500);P12=1;Delay_ms(500);IWDG_Feed();
P12=0;Delay_ms(500);P12=1;Delay_ms(500);IWDG_Feed();
P12=0;Delay_ms(500);P12=1;Delay_ms(500);IWDG_Feed();
enableInterrupts();
IWDG_Configuration();
while(1)
{
if(++cnt_1ms>=10)
{
cnt_1ms=0;
key_value = key_read();
if(key_value != key_no) led_flash = key_value*2;
}
if(++cnt_100ms>=100)
{
cnt_100ms=0;
if(led_flash)
{
led_flash--;
P12 = ~P12;
}
}
}
}
史海拾趣
|
IEEE 802.11a :使用5GHz频段,传输速度54Mbps,与802.11b不兼容 IEEE 802.11b :使用2.4GHz频段,传输速度11Mbps IEEE 802.11g :使用2.4GHz频段,传输速度54Mbps,可向下兼容802.11b 目前IEEE 802.11b最常用,但IEEE 802.11g更具下一代标准 ...… 查看全部问答> |
|
我在网上下载了一个源代码是基于CC2430的zigbee 点对点的实例通信代码,但是看不懂, 能不能帮我解释一下程序的大致框架和实现原理,诸如 hal层 cul层 是实现什么的,程序如何工作的?十分感谢了 TI(德州仪器公司)的CC2430芯片的库函数以及一些 ...… 查看全部问答> |
|
串口0为片内自带的,初始化的时候,U0FCR这个寄存器总是写不进去值,请教高手~~~ 附代码:[code] INT8U UART0_Init( INT32U baudrate) { INT32U Fdiv; PINSEL0 &= 0 ...… 查看全部问答> |
|
对于TI的M3系列的开发板,普及率还不是很高,为什么这么说?我主要参考了淘宝里的开发板的销售情况,发现其他公司,尤其是现在比较热的××公司,你只要到淘宝上一搜,遍地都是。这里面良莠不齐,难免 ...… 查看全部问答> |
|
HARDWARE DESIGN TECHNIQUES Prototyping Analog Circuits Evaluation Boards Noise Reduction and Filtering for Switching Power Supplies Low Dropout References and Regulators EMI/RFI Considerations Sensors and Cable Shielding … 查看全部问答> |
|
MSP430: Trouble Writing Memory Block at 0x0 on Page 0 of Length 0x4: Could not perform access, BSL memory segments are protected. MSP430: GEL: File: D:\\workspace_v5_2\\12864\\Debug\\12864.out: Load failed.… 查看全部问答> |
|
经网友两次指点,我终于找到了这里:求温度和流量传感器得到的信息怎么显示在液晶屏上 我在传感器板块发了这么一个帖子(开始我连发什么板块都不知道,觉得用到了传感器,所以应该发传感器吧) ------------------------------------------------------------------------------------------ 我从来没搞过开发,不过想自己DIY点东西 ...… 查看全部问答> |




