按键状态机—实现连发
2010-07-02 17:18
169 查看
状态机的编程,最好的地方就是在于,一旦框架出现了,如果需要实现新的功能,只是需要增加新的状态。在c语言中,只需要增加几个简单的变量即可。而在labview中,只需要增加一个分支框图即可。就跟累积积木一样,为后期的更改提高了很大的可塑性。
在上次的程序中,更改一下,实现连发功能。关键是设置变量,检测按键按下的时间。同时增加一个状态,就是所谓的“连发状态”。
proteus图和上次的一样,gcc,mega48实现。
在上次的程序中,更改一下,实现连发功能。关键是设置变量,检测按键按下的时间。同时增加一个状态,就是所谓的“连发状态”。
//这个的案件带有连按的功能,如果按下的时间超过一秒的话,进行连按的计算,也就是相应的加上一个状态key_state_3,一次通过 #include <avr/io.h> #include <avr/interrupt.h> #define uchar unsigned char #define key_state_0 0 //空闲状态 #define key_state_1 1 //确认状态,消斗 #define key_state_2 2 //按键按下状态,等待释放 #define key_state_3 3 //连按状态在3状态之后 #define key_input PIND&_BV(PD7) const uchar sec[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; void IO_initial(){ PORTD = 0xff; DDRD = 0x00; //输入,上拉电阻有效 DDRB = 0xff; PORTB = 0x00; //输出,初始值为0 } uchar key_state = 0; //记录此刻按键的状态 volatile uchar key_stime_ok = 0x00; // 这里面的volatile一定要加,否则就被优化掉了,attention volatile uchar key_time_state2 = 0x00; //在状态2中的时间计数器 volatile uchar key_time_state3 = 0x00; //在状态3中的时间计数器 uchar getKey(){ uchar key_press,key_return = 0; key_press = key_input; switch(key_state){ case key_state_0: if(!key_press){ key_state = key_state_1; //按键被按下,装换到状态1 } else key_state = key_state_0; //否则保持0状态,可以去掉,但是这样结构清晰,表示出了所有的情况 break; case key_state_1: if(!key_press) { //按键依然被按下,确定按键被按下 key_state = key_state_2; key_time_state2 = 0x00; //进入状态2,状态2的counter开始计数 key_return = 1; } else { key_state = key_state_0; } break; case key_state_2: if(key_press) key_state = key_state_0; else if((!key_press)&(key_time_state2<50)) key_state = key_state_2; else if((!key_press)&&(key_time_state2>=50)){ key_state = key_state_3 ; key_time_state3 = 0; } break; case key_state_3: if((!key_press)&&(key_time_state3 >= 100)){ key_time_state3 = 0; key_return = 1; } if(key_press){ key_state = key_state_0; } } return key_return; } void Timer0_initial(){ TCCR0B = _BV(CS02)|_BV(CS00); //1024分频,8/1024 TCNT0 = 0xb2; //设置定时器初始值,使得每次定时值为10ms TIMSK0 = _BV(TOIE0); sei(); } ISR(TIMER0_OVF_vect){ TCNT0 = 0xb2; key_stime_ok = 0xff; key_time_state2++; key_time_state3++; } int main(){ IO_initial(); Timer0_initial(); uchar dispos = 0x00; while(1){ if(key_stime_ok){ key_stime_ok = 0x00; if(getKey()==1){ PORTB = sec[dispos]; if((++dispos) == 0x0e) dispos = 0; } } } }
proteus图和上次的一样,gcc,mega48实现。
相关文章推荐
- 发一个用状态机实现的按键检测是VERILOG代码
- 基于状态机的按键扫描的实现
- 黑金开发板状态机实现的可用按键控制的流水灯
- 基于状态机的按键扫描的实现
- 基于状态机的单个按键长按,短按实现复用
- STM32F103按键操作的另一种实现——状态机
- 基于状态机的按键扫描的实现
- pygame中使用事件扫描实现对按键的检测以及小游戏的编写
- s5pv210GPIO口按键(k1)多功能实现( 已测试)
- 按键定时扫描--有限状态机的软件实现方法(下)
- msp430单片机实现常按键和短按键加去抖功能
- STM32F401利用CubeMX实现按键中断翻转LED
- MSP430利用IO中断方式来实现按键检测
- android monitor tool (8.0 模拟发送按键及触摸屏事件实现)
- Android App实现监听软键盘按键的三种方式
- 探讨Android实现后台(Service)按键监听的功能
- 实现一个鼠标自动按键程序
- iphone5实现按键自动点击
- MTK6735(Android6.0)-按键灯的实现
- GridView的几个事件(如实现: 行的双击/单击/捕捉键盘按键/鼠标悬浮/移出效果)