<交流一下> 偷师傻孩子,自己用的简单测试模板-测试按键
本帖最后由 slzm40 于 2014-11-28 10:21 编辑在傻孩子这个专栏偷师了许久,觉得有必要发出来交流下,顺便听听大家的批评声,以促进自己更大的进步。
因为是测试小模板,用于测试一些小功能的,所有有些要求并不高,比如串口调试 用的不是循环队列的中断方式,而是用等待方式。
/********测试小模板说明 - 2014-11-27*********/
模板功能: 有串口回显功能, 时间触发式小系统,延时模块调用,对象方法的使用,宏方法使用
模板来源:至少80%偷师于傻孩子,因为是自己重编过,所以没有在注释里留下来源,但变量用名等大部份保留原来的格式,有一些修改也只是适用在自己的风格。
/********测试小模板说明*********/
*另外由于PIC不支持掩码结构体,所以在对对象方法的简单使用中,做了修改,本次没有使用,但宏有放在H文件中,简单的其实是结构体。*/
/*本次主要测试功能,按键功能。*/
上次对通用按键模块做了分析和学习, 在通用模块中开了两个队列, 占有了不少的空间,所以我自己修改了下按键模块,去除队列,加入消息传输,以适用于自己的平台。
按键模块大部份变量和思想 基于傻孩子专栏的 通用按键模块。 也是状态机!
简单说下自己这个按键模块的使用,由于本人属于水平有限。有BUG的地方提出来,以便修正和提高。
和通用按键模块基本一样的顺序列:
1、编写按键获取键值函数
需要编写自己的按键键值获取函数。放在keyqueue.c中(我够懒的,里面不是队列方式)
对了,我是高电平获得按键,平时低电平。
/*这个是需要更改的*/
static uint8_t bsp_key_scan_value()
{
if( IO_KEY_K1 )
{
return KEY_PRESS_K1;
}
if( IO_KEY_K2)
{
return KEY_PRESS_K2;
}
return KEY_NULL;
}
在keyqueue.h中可以拓展按键,可以修改滤波,长击,连击时间,可以拓展按键。
然后,我的按键只有三种状态,短按,长按,连击,其它的没有做。
//时基为10ms
//用于定义按键滤波,长击,连击时间
#define KEY_FILTER_TIME 2
#define KEY_LONG_TIME 10
#define KEY_REPEAT_TIME 3
/*用于拓展按键,需要修改*/
typedef enum
{
KEY_NULL = 0, /* 0 表示按键事件 */
KEY_PRESS_K1, /* k1按键 */
KEY_PRESS_K2, /* k2按键*/
//KEY_PRESS_K3, /* k3按键 */
//KEY_PRESS_K4 /* k3按键 */
}key_value_t;
在初始化于配置IO口
void bsp_Key_init(void)
{
/*按键硬件配置*/
KEY_K1_INPUT();//按键输入
KEY_K2_INPUT();//按键输入
/*消息创建*/
KeyMsgCreate(&s_tKeyEventMsg,&s_tKeyDetectorMsg);//创建获得键消息
}
2、接口使用说明
经过以上的修改,keyqueue.h: 三个函数就可以使用了。
void bsp_decetor_Key_Task(void);
void bsp_Key_init(void);
bool bsp_GetKey(key_event_t *ptkey);
bsp_Key_init();初始化调用
bsp_decetor_Key_Task(); 在超级循环里调用,我是设成10ms调用一次,配合触发式小系统
bsp_GetKey()可以获得键值,有键值时返回true,
超级循环:
void main(void)
{
…
init_key_task();
…
while(1) {
…
//需要在超级循环或者定时器中断处理程序中被周期性的调用
if(10ms到)
{
bsp_decetor_Key_Task();
}
Keydeal_loop();
…
}
}
按键使用:
void Keydeal_loop(void)
{
key_event_t keycode = {KEY_NULL,KEY_NONE_PRESSED};
if(bsp_GetKey(&keycode))
{
if(KEY_PRESSED == keycode.tEvent)//短按
{
if(KEY_PRESS_K1 == keycode.chKeyValue)
{
sprint("key1 short press!\n");
}
if(KEY_PRESS_K2 == keycode.chKeyValue)
{
sprint("key2 short press!\n");
}
}
if(KEY_LONG_PRESSED == keycode.tEvent)//长按
{
if(KEY_PRESS_K1 == keycode.chKeyValue)
{
sprint("key1 long press!\n");
}
if(KEY_PRESS_K2 == keycode.chKeyValue)
{
sprint("key2 long press!\n");
}
}
if(KEY_REPEAT_PRESSED == keycode.tEvent)//连击
{
if(KEY_PRESS_K1 == keycode.chKeyValue)
{
sprint("key1 repeat press!\n");
}
if(KEY_PRESS_K2 == keycode.chKeyValue)
{
sprint("key2 repeat press!\n");
}
}
}
}
我用的是proteus仿真,Virtual serial port做串口测试;
结果:
还是传文件吧,欢迎批评。 以求编程水平提高。
/****修改kqueue里 KEY_MSG和key_event_t 多定义的问题****/
/****修改kqueue里有无消息事件 改成枚举,未修正问题。 ****/
本帖最后由 slzm40 于 2014-11-28 10:20 编辑
****************************************
说明一下,大部份源码来源于本专栏。
传不上附件。。。
slzm40 发表于 2014-11-27 16:18
****************************************
说明一下,大部份源码来源于本专栏。
在增加按键使用时,只需修改.h文件中的
/*用于拓展按键,需要修改*/
typedef enum
{
KEY_NULL = 0, /* 0 表示按键事件 */
KEY_PRESS_K1, /* k1按键 */
KEY_PRESS_K2, /* k2按键*/
//KEY_PRESS_K3, /* k3按键 */
//KEY_PRESS_K4 /* k3按键 */
}key_value_t;
和/*这个是需要更改的*/
static uint8_t bsp_key_scan_value()
{
if( IO_KEY_K1 )
{
return KEY_PRESS_K1;
}
if( IO_KEY_K2)
{
return KEY_PRESS_K2;
}
return KEY_NULL;
}
两个地方和配置硬件IO放入初始化,就可以调用了。。bsp_decetor_Key_Task()放入10ms的时基里,bsp_GetKey()就可以使用了。 修改地方为四处。
状态机{:lol:} 赞!还没来得及看你的代码,但希望你学习到信息分级处理的思想,这也是模式识别的基本方法。比如手势识别就是用信息分级 本帖最后由 slzm40 于 2014-11-28 10:19 编辑
static KEY_MSG s_tKeyEventMsg;
static key_event_t s_tKeyDetectorMsg;//定义消息内存
在kqueue.c中多定义的了一次,有看代码的,可以把里面删掉一份。
我重新传一份
/****修改kqueue里 KEY_MSG和key_event_t 多定义的问题****/
/****修改kqueue里有无消息事件 改成枚举,未修正问题。 ****/
本帖最后由 slzm40 于 2014-11-28 10:12 编辑
Gorgon_Meducer 发表于 2014-11-28 09:51
赞!还没来得及看你的代码,但希望你学习到信息分级处理的思想,这也是模式识别的基本方法。比如手势识别就 ...
正在学习中,简单点说,从专栏里学到无阻塞状态机方法,面向对象,分层。
至于信息分级处理思想还有多多思考写代码中慢慢继续领悟。
等你新书啊! bsp_decetor_Key_Task();这个函数怎么没有贴出来
收藏看看,谢谢分享。弱弱的问一句,楼主用的是什么串口调试软件,能放上来共享么 赞一个!
{:lol:} 下载下来学习一下
页:
[1]