收藏 分享(赏)

AVR定时按键.doc

上传人:scg750829 文档编号:7666750 上传时间:2019-05-23 格式:DOC 页数:14 大小:61.50KB
下载 相关 举报
AVR定时按键.doc_第1页
第1页 / 共14页
AVR定时按键.doc_第2页
第2页 / 共14页
AVR定时按键.doc_第3页
第3页 / 共14页
AVR定时按键.doc_第4页
第4页 / 共14页
AVR定时按键.doc_第5页
第5页 / 共14页
点击查看更多>>
资源描述

1、AVR 定时按键程序共定义了 6 个键的功能: K1、K2、K3、K4 以及 K5、K8 组成的一对复合键,其中 K2,K3 为 *连击键,K5 为上档键。在正常工作模式下按 K1 则切换至状态,在设定模式下按 K1 键循环选 *择 4 个数码管中的某个,被选中的数码管闪烁,此时单按 K2 键显示数值加 1;常按 K2 显示数 *值以一定速度递增,同时数码管停止闪烁,当 K2 松开,数码管恢复闪烁,显示数值停留在 *K2 松开前的值上。K3 完成的功能和 K2 类似。其完成减操作。这 2 个键只有在设定状态才有 *效,可以有效防止误操作。K4 为确认键,按下该键回到正常显示状态,所有指示灯熄灭

2、, *数码管显示刚刚设定的数值。K5+K8 这对复合键执行复位操作,任何情况下同时按下 K5 和 K8 *或先按下 K5 再按下 K8,所有数码管的显示全为 0,指示灯全灭,进入正常显示状态。同时程 *序还对如下几个异常操作进行了处理: * 2 个或多个功能键同时按下 * 一个功能键按下未释放,又按另一个功能键,然后再松开其中一个功能键 * 先按下功能键再按下上档键 * 多个上档键和一个功能键同时按下,此时不做处理。等到松开其他上档键,只剩下一个上 * 档键和一个功能键时才执行这对复合键;或松开所有上档键,处理单一功能键。 */ #include #include #define uchar

3、unsigned char #define uint unsigned int#define RCtrl 0x20 /定义上挡键 第 5 键 #define RConti 0xfe /定义连击键 第 6 键#define N 2 /去抖年龄下限#define MaxRate 50 /重复前的延迟值 600ms #define MinRate 20 /重复速度 240ms#define leddark 83 /闪烁时灭时间 1s #define ledshow 83 /闪烁时亮时间 1s#define decimal 0x80 /小数点的段数#define KEY_DDR DDRC #defin

4、e KEY_PORTO PORTC #define KEY_PORTI PINC #define OUT 0x3f #define IN 0xc0 #define KeyValue 0x3f#define LEDD_DDR DDRB #define LEDD_PORTO PORTB#define LEDS_DDR DDRD #define LEDS_PORTO PORTD #define LEDS_MASK 0xfc #define LEDS_NUM 0x06#define TRUE 1 #define FALSE 0/*定义键盘扫描程序返回数据类型*/ typedef struct ucha

5、r shiftcnt; /上档键的个数值 uchar funcnt; /功能键的个数值 uchar shiftval; /最后扫描到的上档键的值 uchar funval; /最后扫描到的功能键的值 keyret;/*定义显示字符段码*/ uchar const led_stroke19 = /0,1,2,3,4,5,6,7,8,9 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,/a,b,C,d,e,F,P, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x73, /all on all off

6、 0xff, 0x00 ;/*定义位选码*/ uchar const led_csLEDS_NUM = 0xfb, /11111011 0xf7, /11110111 0xef, /11101111 0xdf, /11011111 0xbf, /10111111 0x7f /01111111 ;uchar led_bufLEDS_NUM = 0x73, 0x81, 0x82, 0x83, 0x84,0x85 ; uchar *pb = /定义指向数码管数据缓冲区的指针/*定义全局变量*/uchar task, state; /task:按键状态,0:去抖 1,重复的延迟 2,重复 /state

7、:显示位置变量uchar keydone, keyprocess; /keydone: 按键任务完成标志,为 1 表示已完成 /keyprocess: 按键有效标志,为 1 时表示对按键执行uchar keypre2 = 0x00, 0x00 ; /存放上次功能键和上档键的键值 /keypre0 存放功能键uchar blink, ledtime; /blink:闪烁控制寄存器,某位为 1 时闪烁 /d7d6d5d4d3d2d1d0 /xxxx1111 /ledtime:累计闪烁时已点亮和已熄灭的时间 uchar ledtask; /ledtask: 当前的闪烁状态,0 代表亮uchar ke

8、ymark; /keymark:只是当前工作状态,为 1 时处于设定状态,为 0 时正常工作 uchar enflash; /enflash:闪烁使能标志,1 闪烁#define shut_dis() LEDS_PORTO|=LEDS_MASK; /shut display/* *函数原型 : uchar _crol_(uchar data,uchar shiftbit); *功能 :字节左移 shiftbit *参数 : *说明 : */ uchar _crol_(uchar data,uchar shiftbit) data if(shiftbit8)return 0; return (d

9、ata)8)return 0; return (data)shiftbit); /* *函数原型 : void send_shift(uchar d); *功能 : 将显示数据由 B 口送出 */ void send_shift(uchar data) LEDD_PORTO = data; /* *函数原型 : void lflash(); *功能 :闪烁处理。ledtask 指示当前的显示状态:亮或灭,ledtask 为 0 时亮 *参数 : *说明 : */ void lflash() if (enflash else ledtime = ledshow; ledtask = ledtas

10、k; /显示状态翻转 else ledtask = 0; /* *函数原型 : void display(uchar pos); *功能 :将 pos 对应的显示缓冲区的内容显示在第 pos 位数码管上 *参数 : *说明 : */ void display(uchar pos) uchar sflag; shut_dis(); /关显示 sflag = (blink (6-pos) /取出 pos 对应的数码管的闪烁控制位 if (pos = 0) send_shift(led_buf0); /指示灯显示时直接将显示内容送显示端口 else if (!sflag | (sflag /显示小数

11、点,把查表得到段码与小数点的段码与的结果送显示端口 else send_shift(led_strokeled_bufpos else send_shift(0xff); /pos 位数码管不显示 LEDS_PORTO /送出位选码 /* *函数原型 : void scankey(keyret *kpd); *功能 :键盘扫描,返回上档键个数,上档键值,功能键个数,功能键值 *参数 : *说明 : */ void scankey(keyret *kpd) uchar i,j; shut_dis(); /关显示 KEY_DDR = OUT; /定义数据端口为输出 KEY_PORTO |= Key

12、Value; /输出数据(输出检测码) KEY_DDR = IN; /定义数据端口为输入 i = (KEY_PORTI /取出键盘位 if (i != KeyValue) /检测是否有键按下 i |= KeyValue; /组成完整的字节 if (i /上档键个数加 1 ? /这里不对 for(j=0;jshiftval = j+1; /上档键值存入上档键值缓冲 ? else for(j=0;jfuncnt+; /功能键个数加 1 ? kpd-funval =j+1; /上档键值存入上档键值缓冲 ? KEY_DDR = OUT; /数据端口还原为输出 /* *函数原型 : void key()

13、; *功能 :键盘扫描,返回上档键个数,上档键值,功能键个数,功能键值 *参数 : *说明 : */ void key() uchar krpt = RConti; static uchar keycnt; static uchar keyesc; keyret keytemp = 0x00, 0x00, 0x00, 0x00 ; if (keydone) /上次按键任务已完成 scankey( /扫描键盘 if (!keytemp.funcnt | keytemp.shiftcnt 1) /功能键计数器为 0 或上档键个数多于 1 enflash = 1; /允许闪烁 / USART0_Tr

14、ansmitString(“shiftcnt!rn“); keypre0 = 0x00; /清零上次功能键和上档键缓冲 keypre1 = 0x00; /清零 keyesc = 0x00; /键释放标志 清零 task = 0x00; /按键状态 标志为去抖阶段 keycnt = 0x00; /年龄计数器 清零 else if (!keyesc) /键已释放 按下上挡键后按键释放标志请零 / USART0_TransmitString(“keyesc!rn“); if (keytemp.funcnt 1) /有多于一个的功能键按下 keyesc = 1; /置位按键释放标志 /本次功能键值和上

15、次不同或本次上档键值和上次不同且上次有上档键 else if (keytemp.funval != keypre0 | keytemp.shiftval != keypre1 /用本次键值更新上次键值 keypre1 = keytemp.shiftval;keycnt = 0x00; /年龄计数器复位 else if (!keypre1 /置位 keyesc,屏蔽先按下功能键,再按下上档键这种按键组合 else keycnt+; /2 次功能键和上档键都相同 switch (task) case 0: if (keycnt = N) enflash = 1; keyprocess = 1; /

16、键值处理 if (keytemp.shiftcnt = 1) | !(krpt (keytemp.funval - 1) /是一对复合键或该键不允许连击 else task+; /按键状态转入重复的延缓阶段 keycnt = 0; /按键年龄清 0 break; case 1:/重复的延缓阶段 if (keycnt = MaxRate)/按键年龄等于重复的延缓阶段 enflash = 0; /不允许闪烁keyprocess = 1; /进行键值处理 keycnt = 0; /按键年龄清 0 task+; /按键转入重复状态 break; case 2:/重复阶段 if (keycnt = Mi

17、nRate)/重复时间到 enflash = 0; /不允许闪烁keyprocess = 1; /进行键值处理 keycnt = 0; /按键年龄清 0 break; /* *函数原型 : void key1_handler(); *功能 :按键 1 处理 *参数 : *说明 :正常工作模式下,按下按键 1 即进入设定状态,此时第一个数码管闪烁,同时对应 led1 * 的指示灯亮。设定模式下,按下按键 1,在 led1 和 led4 之间循环切换选择被选中的数码 * 管闪烁,相应的指示灯亮 */ void key1_handler() if (!keymark) /进入设定状态 led_buf

18、0 = 0xfe; /点亮第一个 led pb = /pb 指向第一个数码管 /blink = 0x80; /第一个数码管闪烁 blink = 0x20; /第一个数码管闪烁 keymark = 1; enflash = 1; /允许闪烁 else pb+; /pb 指向下一个数码管 blink = 1; /该数码管闪烁 / led_buf0 = _crol_(led_buf0, 2); /调整指示灯 if (pb = (uchar*)(led_buf + 6) /pb 指针越限,重新初始化 pb = /blink = 0x80; /第一个数码管闪烁 blink = 0x20; /第一个数码管

19、闪烁 /* *函数原型 : void key2_handler(); *功能 :按键 2 处理 *参数 : *说明 :正常工作模式下,按下按键 2 无效。设定模式下,按下按键 2,每执行一次选中的数码 * 管值加一,常按,数值以一定速度连续递增,但数值大于 9 时又回到 0, */ void key2_handler() if (keymark) *pb += 1; if (*pb = 10) *pb = 0; /* *函数原型 : void key3_handler(); *功能 :按键 3 处理 *参数 : *说明 :正常工作模式下,按下按键 3 无效。设定模式下,按下按键 2,每执行一次

20、选中的数码 * 管值减一,常按,数值以一定速度连续递减,但数值大于 0 时又回到 9, */ void key3_handler() if (keymark) if (*pb = 0) *pb = 9; else *pb -= 1; /* *函数原型 : void key4_handler(); *功能 :按键 4 处理 *参数 : *说明 :此键为确认键,按下后熄灭指示灯,不闪烁,进入工作状态 */ void key4_handler() blink = 0x00; led_buf0 = 0x73; keymark = 0; /* *函数原型 : void keymix_handler();

21、 *功能 :复合按键(上档键 5 和功能键 8)处理 *参数 : *说明 :执行复位功能,4 个数码管全显示 0,不闪烁。8 个指示灯全灭,进入正常工作状态 */ void keymix_handler() led_buf0 = 0x73; led_buf1 = 0; led_buf2 = 0; led_buf3 = 0; led_buf4 = 0; led_buf5 = 0; keymark = 0; blink = 0; /* *函数原型 : void key_processing(); *功能 :键值处理 *参数 :keyprocess,keypre1,keypre0, *说明 :根据键

22、值执行相应的按键功能 */ void key_processing() if (keyprocess) keydone = 0; keyprocess = 0; switch (keypre1) case 0x00: switch (keypre0) case 0x01: key1_handler(); break; case 0x02: key2_handler(); break; case 0x03: key3_handler(); break; case 0x04: key4_handler(); break; break; case 0x05: if (keypre0 = 8) key

23、mix_handler(); break; keydone = 1; /TIMER0 initialize - prescale:256 / desired value: 2mSec / actual value: 1.991mSec (0.5%) void timer0_init(void) TCCR0 = 0x00; /stop TCNT0 = 0xAA; /set count TCCR0 = 0x04; /start timer /* *函数原型 : void timer0_ovf_isr(void); *功能 :定时器 0 中断服务程序 *参数 : *说明 :键盘和 led 一起构成

24、1/6 扫描,每 6 次中断进行一次键盘处理 */ #pragma interrupt_handler timer0_ovf_isr:10 void timer0_ovf_isr(void) TCNT0 = 0xAA; /set count if (state = 5) lflash(); display(state); state+; else key(); state = 0; void USART0_Init(void) UCSRB = 0x00; /disable while setting baud rate UCSRA = 0x00; UCSRC = BIT(URSEL) | 0x

25、06; UBRRL = 0x47; /set baud rate lo UBRRH = 0x00; /set baud rate hi UCSRB = 0x18; /-void USART0_Transmit(unsigned char data) while (!(UCSRA UDR = data; /-void USART0_TransmitString(char *data) while (*data) USART0_Transmit(*data+); /-unsigned char USART0_Receive(void) while (!(UCSRA return UDR; /* *

26、函数原型 : void port_init(void); *功能 :端口初始化 *参数 : *说明 : */ void port_init(void) /端口初始化 DDRB = 0xff; /led 数据口 11111111 DDRC = 0xff; /键盘 00111111 DDRD = 0xfc; /段码选择 11111100PORTD = 0xff; PORTB = 0xff; PORTC = 0xff; /* *函数原型 : void init_devices(void); *功能 :m8 初始化 *参数 : *说明 : */ /call this routine to initia

27、lize all peripherals void init_devices(void) /stop errant interrupts until set up CLI(); /disable all interrupts port_init(); timer0_init(); USART0_Init(); MCUCR = 0x00; GICR = 0x00; TIMSK = 0x01; /timer interrupt sources SEI(); /re-enable interrupts /all peripherals are now initialized /* *函数原型 : v

28、oid main() ; *功能 :主程序,执行初始化操作,循环等待案件事件 *参数 : *说明 : */ void main() init_devices(); /标志和常量初始化 task = 0x00; /按键状态 state = 0x00; /显示位置变量 keyprocess = 0; /按键有效标志 keydone = 1; /按键任务完成标志 ledtime = ledshow; /累计闪烁时已点亮或已熄灭时间 ledtask = 0; /当前的闪烁状态 0 代表亮 keymark = 0; /指示当前工作状态为正常工作状态 USART0_TransmitString(“OK!rn“); while (1) key_processing();

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报