你好,我在调试你贴上的程序,发现单个按键都正常,为什么组合键就不正常呢?代码如下:

#include

#define K_STOP                (1<

#define K_START               (1<

#define K_SEL                 (1<

#define K_ADD                 (1<

#define K_DEC                 (1<

#define OneKeyTime        300                                                                         // 单键长按时长 = OneKeyTime * 10ms

#define MuxKeyTime        500                                                                         // 组合键长按时长 = MuxKeyTime * 10ms

#define RepeatTime        5                                                                           // 单键连发功能重复间隔时间 = RepeatTime * 10ms

#define Key_Mask        (K_STOP|K_START|K_SEL|K_ADD|K_DEC)                        // 按键掩码值

#define KEY_PORT              PORTA                                                                    // 独立按键所占用端口.

#define KEY_DDR                                  DDRA

#define KEY_PIN                                  PINA

//-------------------------------------------------------------------------------------------------------

#define GetKey()        (KEY_PIN & Key_Mask)                                                // 读取按键端口值

#define key_state_0        0                                                                                // 初始态.

#define key_state_1        1                                                                                // 确认态.

#define key_state_2        2                                                                                // 组合键,长按键确认态.

#define key_state_3        3                                                                                // 长按连发功能确认态.

#define key_state_4        4                                                                                // 等待释放态.

//-------------------------------------------------------------------------------------------------------

/****************************************数据类型定义**************************************/

typedef enum {NO_KEY,STOP,START,SEL,ADD,DEC,SETUP} eKEY;        // 按键返回值类型定义.

//-------------------------------------------------------------------------------------------------------

/*****************************************函数声明****************************************/

eKEY ReadKey(void);                                                                                        //读取按键.

//-------------------------------------------------------------------------------------------------------

unsigned char time_counter,key_stime_counter;                // 时间计数单元

unsigned char point_on, time_1s_ok,key_stime_ok;

/********************************************************************************************

* eKEY ReadKey(void);

* 功能: 独立按键扫描,10ms扫描一次.

* 返回值:枚举类型,{NO_KEY,STOP,START,SEL,ADD,DEC,SETUP}.

* 参数:

********************************************************************************************/

eKEY ReadKey(void)

{

static unsigned int key_time = 0;                                                        // 长按键计时

static unsigned char key_state = 0;                                                // 记录按键扫当前描状态

static unsigned char key_press_old = 0;                                        // 记录上一次按键状态

static eKEY key_value_old = NO_KEY;                                                // 保存上一次按键返回值

eKEY key_return = NO_KEY;                                                                // 按键功能返回值

unsigned char key_press;

key_press = GetKey() ^ Key_Mask;                                                // 读按键I/O电平,只保留被按下的键(被按下的键位为1)

switch (key_state)

{

case key_state_0:                                                                // 1.按键初始态

if (key_press)

{

key_state = key_state_1;                                        // 键被按下,状态转换到按键确认态

key_press_old = key_press;                                      // 保存当前按键状态

}

break;

case key_state_1:                                                                                                                                // 2.按键确认态

if (key_press == key_press_old)                                         // 与初始态的按键状态相同?

{

key_time = 0;                                                        // 清另按键时间计数器

switch(key_press)

{

case K_STOP:

key_state  = key_state_4;                         // 转按键释放态

key_return = STOP;

// "停止"键

break;

case K_START:

key_state  = key_state_4;                         // 转按键释放态

key_return = START;                                // "起动"键

break;

case K_SEL:

key_state  = key_state_2;                         // 转长按键态

key_return = SEL;                                // "选择"键

break;

case K_ADD:

key_state  = key_state_2;                         // 转长按键态

key_return = ADD;                                // "+"键

break;

case K_DEC:

key_state  = key_state_2;                         // 转长按键态

key_return = DEC;                                // "-"键

break;

case K_STOP|K_SEL:                                        // "组合"键,长按键

key_state  = key_state_2;                         // 组合键按键仍按下,状态转换到计时1

break;

default:

key_state  = key_state_4;                         // 转按键释放态

break;

}

}

else if (!key_press)

key_state = key_state_0;                                        // 按键已抬起(是干扰),转换到按键初始态

else

key_state = key_state_4;                                        // 按键已发生变化,转到按键释放态

key_value_old = key_return;                                        // 保存按键返回值

break;

case key_state_2:                                                                // 3.长按键确认态

if (key_press == key_press_old)

{

++key_time;                                                        // 按键计时

if (key_press == (K_STOP|K_SEL))                        // "配置"键?

{

if(key_time >= MuxKeyTime)                        // 组合键长按计时

{

key_state = key_state_4;                        // 按下时间>=MuxKeyTime,转到按键释放状态

key_return = SETUP;                                // 组合键功能,"配置"键

}

}

else

{

if(key_time >= OneKeyTime)                        // 单键长按计时

{

key_state = key_state_3;                        // 按下时间>=OneKeyTime,转到连发功能态,用于触发连发功能

key_time = 0;                                        // 清按键计数器

key_return = key_value_old;                // 返回上一次按键值

}

}

}

else

key_state = key_state_4;                                        // 按键已发生变化,转到按键释放态

break;

case key_state_3:                                                                // 4.按键连发功能

if (key_press == key_press_old)

{

if (++key_time >= RepeatTime)                                // 按键时间计数

{

key_time = 0;                                                // 按下时间>=0.05s,清0按键计数器

key_return = key_value_old;                        // 返回上一次按键值

}

}

else

key_state = key_state_4;                                         // 按键已发生变化,转到按键释放态

break;

case key_state_4:                                                                // 5.等待所有按键释放开

//if (!key_press)                                                                // 等待所有按键释放,才进入一次新的按键确认过程

if (key_press != key_press_old)                                        // 按键发生变化,就进入一次新的确认过程

key_state = key_state_0;                                         // 按键已释放,转换到初始态.

break;

}

return key_return;

}

void Key_init(void)

{

KEY_DDR  &=~ (K_STOP)|(K_START)|(K_SEL)|(K_ADD)|(K_DEC);

KEY_PORT |=  (K_STOP)|(K_START)|(K_SEL)|(K_ADD)|(K_DEC);

}

void Timer0_Init(void)

{

// T/C0 初始化

TCCR0 = 0x0C;                        // 内部时钟,64分频(4M/64=62.5KHz),CTC模式

TCNT0 = 0x00;

OCR0 = 0x08;                        // OCR0 = 0x7C(124),(124+1)/62.5=2ms

//TIMSK = 0x02;                        // 允许T/C0比较匹配中断

TIMSK |=(1<

}

#pragma interrupt_handler Timer0_comp_isr:20

void Timer0_comp_isr(void)

{

//display();                                                // LED扫描显示

if (++key_stime_counter >=5)

{

key_stime_counter = 0;

key_stime_ok = 1;                                // 10ms到

if (++time_counter >= 100)

{

time_counter = 0;

time_1s_ok = 1;             // 1s到

}

}

}

void main(void)

{

Buzz_init();

Key_init();

Timer0_Init();

SREG|=0x80;

while(1)

{

if (key_stime_ok)

{

key_stime_ok = 0;                                // 10ms到

//typedef enum {NO_KEY,STOP,START,SEL,ADD,DEC,SETUP} eKEY;

switch (ReadKey())

{

case STOP:

Beep(1,1);

break;

case START:

Beep(5,5);

break;

case SEL:

Beep(10,10);

break;

case ADD:

Beep(15,15);

break;

case DEC:

Beep(20,20);

break;

case SETUP:

Beep(130,130);

break;

}

}

}

}

php 按键连击,写了一个独立按键 支持组合键、单键长按,连发功能的例子相关推荐

  1. 单片机学习笔记————51单片机实现按住一个独立按键不松手的加速匀速触发

    一.使用proteus绘制简单的电路图,用于后续仿真 二.编写程序 /***************************************************************** ...

  2. 第十二节:按住一个独立按键不松手的连续步进触发

    第十二节:按住一个独立按键不松手的连续步进触发. 开场白: 上一节讲了同一个按键短按与长按的区别触发功能,这节要教会大家两个知识点: 第一个知识点:如何在上一节的基础上,略作修改,就可以实现按住一个独 ...

  3. 51单片机按键扫描程序汇编程序(独立按键与矩阵按键)(使用定时器)(可移植的汇编程序)矩阵键盘控制两个led数码管(汇编语言)与UART通信总结(上)

    一,按键控制数码管 1四按键控制程序(汇编) (您的关注点赞是作者创作的最大动力哦) //******************************************************* ...

  4. 独立按键和矩阵按键c语言,第八章 独立按键和矩阵按键

    我们和单片机之间进行信息交互,主要包含两大类,输入设备和输出设备.前边讲的LED小灯.数码管.点阵都是输出设备,这节课我们学习一下最常用的输入设备--按键.在本节课的学习过程中我们还会穿插介绍一点硬件 ...

  5. 单片机按键防抖程序_单片机独立按键使用程序

    独立按键是单片机中很重要的一个器件,在这篇文章里,通过这个用独立按键控制LED灯的小程序来介绍独立按键开关的使用. 1.按键分类与输入原理         按键按照结构原理科分为两类,一类是触点式开关 ...

  6. c语言按键控制的步进电机程序,独立按键控制步进电机运转c语言程序

    独立按键控制步进电机运转c语言程序 /* * 名称:步进电机 * * 晶振:12MHZ * * 修改:无 * * 内容: 主程序中用 3 个按键,加速.减速.启动和停止.定时器做数码* * 管动态扫描 ...

  7. 一个接口同时支持 form 表单、form-data、json 的优雅写法

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:https://juejin.cn/post/7054441239839506446 最近重写个项目遇到个比较棘手的问题,老项 ...

  8. java按键发出声音代码_用Java写的一个根据按键发声的程序,为什么只有前16次按键响...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 public void sound(int tone){ try { sequencer = MidiSystem.getSequencer(); seq ...

  9. 矩阵键盘 多键组合 c语言,矩阵键盘的检测和独立按键有很大的区别

    描述 先说矩阵键盘,因为我写的组合键代码是在矩阵键盘的基础上写的,当然在独立按键上写组合键更简单一些.所以当你矩阵键盘的组合键会写的时候,你在独立按键上的组合键也就会写了. 矩阵键盘的检测和独立按键有 ...

最新文章

  1. .net c# 序列化和反序列
  2. POJ 2387 Til the Cows Come Home
  3. 转-Apache kafka 工作原理介绍
  4. ajax环境配置tomcat,jcreator+tomcat环境配置
  5. 常见的布局实现,以及响应式布局技巧。
  6. 诗与远方:无题(四)
  7. python中split函数源代码_Pandas.split()函数用法及源码
  8. editplus 格式java_用Editplus开发Java
  9. FastReport.Net使用:[17]线(Line)控件使用
  10. 电话本写完了,发个1.0吧
  11. 报表工具对比选型系列——打印与导出
  12. 360安全桌面 v2.7.0.1060 官方版
  13. 性能测试工具------并发模式
  14. m4s格式转换mp3_简单的amr转换mp3音频格式转换方法
  15. 述职答辩提问环节一般可以问些什么_2.50 述职报告与评审提问注意事项
  16. android国际化(文字、布局、语音、多渠道打包)
  17. 美国计算机研究生最好的大学排名,美国大学计算机信息系统专业研究生排名
  18. 华为手机助手 android,华为手机助手(安卓版)
  19. python方差膨胀因子_讲讲共线性问题
  20. STM32F103-TIM3 4路PWM波输出

热门文章

  1. 玉蝴蝶 柳永 望处雨收
  2. 【总结】一些网络流量统计的网站及工具
  3. [历年IT笔试题]2014迅雷校园招聘笔试题
  4. 项目管理的前景如何?
  5. 西门子plc如何用c语言编程软件下载,s7一200编程软件下载安装
  6. 麻将游戏(mahjong)题解
  7. vba ado的一些封装
  8. Jquery隐藏div 根据id
  9. 酒旅板块复苏,亚朵继续上市梦,距离“新住宿经济第一股“还有多远?
  10. 用python解小学奥数题