历史上的今天
返回首页

历史上的今天

今天是: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;

}

}

}

}


推荐阅读

史海拾趣

Dongguan City Niuhang Electronics Co.LTD公司的发展小趣事

Dongguan City Niuhang Electronics Co.LTD成立于2012年,当时的中国电子行业正处于快速发展期。创始人李小芹凭借对半导体技术的深刻理解和市场需求的敏锐洞察,决定专注于二极管、桥式整流器等产品的研发与封装。公司成立初期,面临着资金短缺、技术储备不足等挑战,但李小芹凭借坚定的信念和不懈的努力,带领团队攻克了一个又一个技术难关,逐步在市场上树立了良好的口碑。

AOS公司的发展小趣事

随着技术的不断发展和市场的扩大,AOS公司开始积极寻求全球扩张的机会。1998年,AOS在南京独资成立了中国总部,开始了其在中国的深耕之旅。通过多年的努力,AOS在中国建立了完善的产研基地和销售网络,其产品横跨家用和商用两大领域,赢得了广大消费者的信任和喜爱。如今,AOS已成为中国市场上备受推崇的热水设备品牌之一。

Chipcera Technology Co Ltd公司的发展小趣事

人才是企业发展的核心动力。为了保持技术领先地位和市场竞争力,Chipcera高度重视人才引进和团队建设。公司积极招聘具有丰富经验和专业技能的人才,并为员工提供良好的工作环境和发展空间。同时,公司还定期组织各种培训和学习活动,提升员工的专业素养和创新能力。这些措施使得Chipcera的团队更加团结、高效,为公司的持续发展提供了有力保障。

COILCRAFT公司的发展小趣事

在追求产品性能的同时,COILCRAFT公司也非常注重产品质量和环保。公司采用先进的设备和工艺,确保产品的稳定性和可靠性。此外,公司还积极采取措施减少能源和资源的消耗,优化生产流程,降低废物排放。这种对质量和环保的坚持使得COILCRAFT在行业中树立了良好的形象。

ELANTEC (Renesas )公司的发展小趣事

作为一家半导体公司,技术突破和创新是ELANTEC发展的核心动力。在移动通信领域,ELANTEC不断推出具有创新性的产品和技术,如低功耗、高性能的移动通信芯片等。此外,在汽车电子、工业控制等领域,ELANTEC也取得了多项技术突破,为客户提供了更加优质的产品和服务。

ept Connectors公司的发展小趣事

随着国际市场的不断扩大,EPT Connectors公司开始实施全球扩张战略。公司先后在捷克共和国、美国和中国等地设立了生产基地和研发中心,以便更好地服务当地客户。同时,EPT还建立了一个遍布全球的分销网络,以确保产品能够及时、准确地送达客户手中。这些举措不仅提升了EPT的市场竞争力,也为其未来的发展奠定了坚实的基础。

问答坊 | AI 解惑

无线网络 --常见标准有以下三种

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 点对点 实例程序

我在网上下载了一个源代码是基于CC2430的zigbee 点对点的实例通信代码,但是看不懂, 能不能帮我解释一下程序的大致框架和实现原理,诸如 hal层 cul层 是实现什么的,程序如何工作的?十分感谢了 TI(德州仪器公司)的CC2430芯片的库函数以及一些 ...…

查看全部问答>

ARM7 NXP236串口问题,请教高手

串口0为片内自带的,初始化的时候,U0FCR这个寄存器总是写不进去值,请教高手~~~ 附代码:[code] INT8U UART0_Init( INT32U baudrate) {     INT32U Fdiv;                 PINSEL0 &= 0 ...…

查看全部问答>

谁有VGA-DB15的封装资料帮我发一份

现在要画一个DB15的封装不知道参数,知道的大侠帮下!!!!!!!!!!!…

查看全部问答>

【问TI】如何能让大家更好的利用M3的板子?

        对于TI的M3系列的开发板,普及率还不是很高,为什么这么说?我主要参考了淘宝里的开发板的销售情况,发现其他公司,尤其是现在比较热的××公司,你只要到淘宝上一搜,遍地都是。这里面良莠不齐,难免 ...…

查看全部问答>

AM335x NAND Driver's Guide中文手册改1

AM335x NAND Driver\'s Guide中文手册改1…

查看全部问答>

视频编解码芯片电源问题

在视频编解码芯片中既有模拟电源又有数字电源,要完全的物理隔离呢?还是只需简单的串联磁珠、电阻等。谢谢…

查看全部问答>

ADI ADC PCB 硬件设计指南

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点东西 ...…

查看全部问答>