『 Jack_a_Lent_Notes』---按键状态机[ATmega128]
来源:互联网 发布:windows me u盘安装 编辑:程序博客网 时间:2024/05/21 07:42
修改于:《安富莱_STM32-V5开发板_用户手册(V2.1) 》第20章 按键 FIFO 教程
按键状态机(单按键或者组合按键)支持:短按,弹起,长按,连发。
/** ****************************************************************************** * 文 件: main.c * 版 本: v1 * 编 译 环 境: Atmel Studio 6.0 * 目 标 芯 片: ATmega128 * 晶 振: 4MHz * 创 建 时 间: 2017-2-2 * 描 述:按键1 短按、连发 :DISbuf++ ;按键1 长按 :DISbuf+=10;按键2 弹起 :DISbuf++;组合按键 连发 :DISbuf--; ****************************************************************************** */#define F_CPU 4000000UL#include <avr/io.h>#include<util/delay.h>#include <avr/interrupt.h>#include "LCD1602.h"#include "bsp_key.h"unsigned char DISbuf=0; void Test_Key(void);/******************************************************************************** * 函 数 名: main * 功 能: * 形 参: * 返 回 值: * 说 明: *******************************************************************************/int main(void){ PORTB=0B00000000;DDRB=0XFF; PORTC=0B00000000;DDRC=0XFF;PORTF=0B11111111;DDRF=0X00;TCCR0=0b00000111;//1024分频TCNT0=61;//初值=256-晶振/预分频*定时长度(s) 256-4000000/1024*0.05s=256-195=61//OCR0=0x00;TIMSK|=(1<<TOIE0);//溢出中断使能TIFR |=(1<<TOV0);//写 1 来清零溢出标志位sei(); //全局中断使能使能 LCD1602_init(); LCD1602_prints(0,0,"Jack_a_Lent"); while(1) {LCD1602_Display(7,1,(DISbuf%1000)/100+0x30);//百位LCD1602_Display(8,1,(DISbuf%100)/10+0x30);//十位LCD1602_Display(9,1,(DISbuf%10)+'0');//个位Test_Key(); }}/******************************************************************************** * 函 数 名: T0中断函数 50ms * 功 能: * 形 参: * 返 回 值: * 说 明: *******************************************************************************/ISR(TIMER0_OVF_vect){TCNT0=61;// 256-4000000/1024*0.05s=256-195=61bsp_KeyScan();}/******************************************************************************** * 函 数 名: Test_Key * 功 能: 按键测试 * 形 参: None * 返 回 值: None * 说 明: *******************************************************************************/void Test_Key(void){switch ( bsp_GetKey())/* 读取键值, 无键按下时返回 KEY_NONE = 0 */{/**********************************************************/case 0xA1://按键1按下case 0xD1://按键1连发DISbuf++;break;/**********************************************************/case 0xC1://按键1长按DISbuf+=10;break;/**********************************************************/case 0xB2://按键2弹起DISbuf++;break;/**********************************************************/case 0xD3://(组合键) 连发DISbuf--;break;/**********************************************************/default:break;/**********************************************************/}}
/************************************************************************************************************模块名称 : 按键驱动模块*文件名称 : bsp_key.h*版 本 : V1.0*说 明 : 头文件************************************************************************************************************/#ifndef __BSP_KEY_H#define __BSP_KEY_H#include <avr/io.h>#include <stdint.h>#defineKEY_DOWN0xA0 /* 按键按下 */ #defineKEY_UP 0xB0 /* 按键弹起 */#defineKEY_LONG0xC0 /* 按键长按 */#defineKEY_LIAN0xD0 /* 按键连发 */#define KEY_LONG_FLAG 20 /* 长按时间 */#define KEY_SERIES_DELAY 5 /* 连发速度 *//* 按键FIFO用到变量 */#define KEY_FIFO_SIZE10typedef struct{uint8_t Buf[KEY_FIFO_SIZE];/* 键值缓冲区 */uint8_t Read;/* 缓冲区读指针1 */uint8_t Write;/* 缓冲区写指针 */}KEY_FIFO_T;/* 供外部调用的函数声明 */void bsp_InitKey(void);void bsp_KeyScan(void);uint8_t bsp_GetKey(void);#endif/*********************************************************************************************************/
/************************************************************************************************************模块名称 : 独立按键驱动模块*文件名称 : bsp_key.c*版 本 : V1.0*说 明 : 扫描独立按键,具有软件滤波机制,具有按键FIFO。可以检测如下事件:*(1) 按键按下*(2) 按键弹起*(3) 长按键*(4) 长按时自动连发************************************************************************************************************/#include "bsp_key.h"#defineKEY_PORTPINF#define NO_KEY_DOWN0b11111111static KEY_FIFO_T s_tKey;/* 按键FIFO变量,结构体 *//***********************************************************************************************************函 数 名: bsp_InitKeyHard*功能说明: 配置按键对应的GPIO*形 参: 无*返 回 值: 无**********************************************************************************************************/static void bsp_InitKeyHard(void){PORTF=0b11111111;DDRF=0X00;//上拉输入}/***********************************************************************************************************函 数 名: bsp_InitKey*功能说明: 初始化按键. 该函数被 bsp_Init() 调用。*形 参: 无*返 回 值: 无**********************************************************************************************************/void bsp_InitKey(void){/* 对按键FIFO读写指针清零 */s_tKey.Read = 0;s_tKey.Write = 0;bsp_InitKeyHard();/* 初始化按键硬件 */}/***********************************************************************************************************函 数 名: bsp_PutKey*功能说明: 将1个键值压入按键FIFO缓冲区。可用于模拟一个按键。*形 参: _KeyCode : 按键代码*返 回 值: 无**********************************************************************************************************/void bsp_PutKey(uint8_t _KeyCode){s_tKey.Buf[s_tKey.Write] = _KeyCode;if (++s_tKey.Write >= KEY_FIFO_SIZE){s_tKey.Write = 0;}}/***********************************************************************************************************函 数 名: bsp_GetKey*功能说明: 从按键FIFO缓冲区读取一个键值。*形 参: 无*返 回 值: 按键代码**********************************************************************************************************/uint8_t bsp_GetKey(void){uint8_t ret;if (s_tKey.Read == s_tKey.Write){return 0;}else{ret = s_tKey.Buf[s_tKey.Read];if (++s_tKey.Read >= KEY_FIFO_SIZE){s_tKey.Read = 0;}return ret;}}/***********************************************************************************************************函 数 名: GetKeyValue*功能说明: 读取按键值,判断按键是否按下*形 参: *返 回 值: 返回值 按键编码 **********************************************************************************************************/static uint8_t GetKeyValue(void){switch(KEY_PORT & NO_KEY_DOWN)//保证只是读取与按键相关的IO口{case 0b11111111: return 0x00;//无按键按下case 0b11111110: return 0x01;//按键1case 0b11111101: return 0x02;//按键2case 0b11111100: return 0x03;//按键1和按键2default : return 0x00;} }/***********************************************************************************************************函 数 名: bsp_KeyScan*功能说明: 扫描所有按键。非阻塞,被systick中断周期性的调用*形 参: 无*返 回 值: 无**********************************************************************************************************/void bsp_KeyScan(void){static uint8_t KeyState = 0; //按键状态static uint8_t KeyPrev = 0; //上一次按键状态static uint16_t KeyDelay = 0; //按键连发计时static uint16_t KeyLong = 0; //按键长按计时uint8_t KeyPressValue = 0x00; //按键值KeyPressValue = GetKeyValue(); //得到按键值switch(KeyState){case 0: /* 按键初始状态 */if(KeyPressValue!=0x00) /* 有键按下 */{KeyState = 1; /* 转到下一个状态,确认按键 */KeyPrev = KeyPressValue; /* 保存按键状态 */} break; /*消抖 */case 1: /* 按键确认状态 */if(KeyPressValue==KeyPrev) /* 确认和上次按键相同,否则重新Scan */{KeyState = 2; /* 转到下一个状态,判断弹起、长按、连发 */bsp_PutKey((uint8_t)(KEY_DOWN|KeyPrev));/* 发送按钮 按下 的消息 */} else /* 本次按键和上次按键不相同,返回到状态0,重新Scan */KeyState = 0; break;case 2:/* 判断弹起、长按、连发 */if(KeyPressValue == 0x00) /* 按键释放 */{KeyState = 0;KeyDelay = 0;KeyLong = 0;bsp_PutKey((uint8_t)(KEY_UP|KeyPrev));/* 发送按钮 弹起 的消息 */break;}if(KeyPressValue==KeyPrev)/* 判断长按、连发 */{KeyDelay++;if((KeyLong==1)&&(KeyDelay>KEY_SERIES_DELAY)) /* 连发 */{KeyDelay = 0;bsp_PutKey((uint8_t)(KEY_LIAN|KeyPrev));/* 发送按钮 连发 的消息 */KeyPrev = KeyPressValue; /* 记住上次的按键 */break;}if(KeyDelay>KEY_LONG_FLAG) /* 长按 */{KeyLong = 1;KeyDelay = 0;bsp_PutKey((uint8_t)(KEY_LONG|KeyPrev));/* 发送按钮 长按 的消息 */break;}}else /* 本次按键和上次按键不相同,返回到状态0,重新Scan */{KeyState = 0;KeyDelay = 0;KeyLong = 0;}default:break;}}/*********************************************************************************************************/
本人在此发布的博文(包括但不限于汉字、拼音、阿拉伯字母、图片、影像,以及前述之各种任意组合等等)均为互联网整理而来,仅供学习参考,如果侵犯了你的权益请发送电子邮件联系我,我会尽快处理你的问题。
0 0
- 『 Jack_a_Lent_Notes』---按键状态机[ATmega128]
- 『 Jack_a_Lent_Notes』---SPI[ATmega128] ①
- 『 Jack_a_Lent_Notes』---SPI[ATmega128] ②
- 『 Jack_a_Lent_Notes』---MCU的库函数的尝试[ATmega128
- 『 Jack_a_Lent_Notes』---基于时间触发的合作式调度器[ATmega128]
- 『 Jack_a_Lent_Notes』---IIC[ATmega128_24C02]
- 『 Jack_a_Lent_Notes』---Buck基本工作原理
- 『 Jack_a_Lent_Notes』---Boost基本工作原理
- 『 Jack_a_Lent_Notes』---FlyBack基本工作原理
- 『 Jack_a_Lent_Notes』---功率因数校正(PPFC)
- 『 Jack_a_Lent_Notes』---功率因数校正(APFC)
- 『 Jack_a_Lent_Notes』---三极管的三种工作状态
- 『 Jack_a_Lent_Notes』---Buck-Boost基本工作原理
- 『 Jack_a_Lent_Notes』---嵌入式实时操作系统概念①
- 按键状态机程序
- 状态机按键消抖
- 状态机按键扫描
- 『 Jack_a_Lent_Notes』---半桥LLC谐振变换器的基本工作原理
- 【笔试练习】腾讯2016笔试题
- 推荐系统 Crab 初探(一)
- Android 创建与解析xml文件
- 微信小程序笔记
- 算法训练 Anagrams问题
- 『 Jack_a_Lent_Notes』---按键状态机[ATmega128]
- 读《透过结构看世界》
- iWebShop二次开发之商城之后台系统菜单管理【转载】
- BZOJ 4240 有趣的家庭菜园
- C++11之经典书籍和网文推荐(持续更新资源下载链接)
- 初识Nginx(一):nginx的安装
- 进程间通信--命名管道(fifo)
- Ubuntu常见问题及解决汇总
- HDU 2097 Sky数