您的位置:首页 > 其它

STM32 按键扫描的方式实现,用队列传递参数

2013-04-29 00:00 295 查看
开发环境是keil4.70a

实验板为神舟三号 STM32F103ZET6

软件上使用到了固件库了ucosii

纯粹为了学习,分享一下学习心得

首先上队列初始化的代码

OS_EVENT* KEY_Q;		//按键记录的OS队列
void *key_list[80];		//队列定义时要求定义指针数组
/* 推荐在main中或者main.c类似的文件和位置创建这两个变量 */

KEY_Q = OSQCreate(key_list,80);
/* 推荐在OSInit之后立马创建这个队列 */

//对了别忘了配置
//这些OS的功能使能
#define OS_Q_EN                   1    /* Enable (1) or Disable (0) code generation for QUEUES         */
#define OS_Q_ACCEPT_EN            1    /*     Include code for OSQAccept()                             */
#define OS_Q_DEL_EN               1    /*     Include code for OSQDel()                                */
#define OS_Q_FLUSH_EN             1    /*     Include code for OSQFlush()                              */
#define OS_Q_PEND_ABORT_EN        1    /*     Include code for OSQPendAbort()                          */
#define OS_Q_POST_EN              1    /*     Include code for OSQPost()                               */
#define OS_Q_POST_FRONT_EN        1    /*     Include code for OSQPostFront()                          */
#define OS_Q_POST_OPT_EN          1    /*     Include code for OSQPostOpt()                            */
#define OS_Q_QUERY_EN             1    /*     Include code for OSQQuery()                              */

//以上的文件默认在os_cfg.h中

接下来贴上的按键扫描的任务

void key_task(void *p_arg) //该任务只实现按键的跟踪功能	//高四位是上一个状态,低四位是当前状态
{
u32 bsp_key_scaned;  	//每四位记录一个状态,一共可以记录8个状态
//在后续优化中可以考虑改成结构体 分出8位或者16位记录按键时长
u8 key_rem1 = 0x00;		//第一次缓冲	//用于消抖
u8 key_rem2 = 0x00;		//第二次缓冲	//用于判断按键状态是否改变
u8 key_t = 0x00;		//第一次记录

bsp_key_scaned = 0x00000000;	//清空按键状态 32位的数字
while(1)
{
OSTimeDlyHMSM(0,0,0,10);	//短暂的消抖
if(!(GPIO_ReadInputDataBit(GPIO_KEY1_PORT, GPIO_KEY1))){
key_t = key_t | 0x01;}
if(!(GPIO_ReadInputDataBit(GPIO_KEY2_PORT, GPIO_KEY2))){
key_t = key_t | 0x02;}
//		if(!(GPIO_ReadInputDataBit(GPIO_KEY3_PORT, GPIO_KEY3))){
//			key_t = key_t | 0x04;} 		//这个按键在神舟三号开发板上不怎么好用
if(!(GPIO_ReadInputDataBit(GPIO_KEY4_PORT, GPIO_KEY4))){
key_t = key_t | 0x08;}		//这里看起来挺繁琐的,所以 挤挤←_←
//以上实现扫描后一个简单的编码

if((key_rem1 == key_t)&&(key_rem1 != key_rem2))	//没有抖动,并且按键状态发生了改变,则Qpost
{
key_rem2 = key_rem1;	//记录即将post的变量,用于下一次判断
bsp_key_scaned = ((bsp_key_scaned<<4)&0xfffffff0)|(key_t&0x0f);	//传递参数	//注意是位操作
OSQPost(KEY_Q,(void*)bsp_key_scaned);	//发送队列内容
}

key_rem1 = key_t;   	//记录一个状态
key_t = 0x00;			//下一次记录,判断是否抖动
}
}
最后一个是队列中内容的提取 也做成了一个任务
void key_solve_task(void *p_arg)
{
u32 key_value;	//获取实际数据
void* pKEY_Q;	//获取队列中的指针
while(1)
{
OSTimeDlyHMSM(0,0,1,0);	//延时 1m处理一次
pKEY_Q = OSQPend(KEY_Q,0,&err);	//不过期,一直请求Q
if(pKEY_Q == (void*)0)		//如果返回数据为空
{
switch(err)		//目前没有加入错误处理
{
case OS_ERR_NONE: break;
default:continue;//break;	//如果不是OS_NO_ERR则继续等待1秒
}
} else
{
key_value = (int)pKEY_Q;
key_value = key_value &0x000000ff;

if(GPIO_ReadOutputDataBit(GPIOF,GPIO_Pin_7) == 1){ //翻转LED2	//表示得到数据
GPIO_ResetBits(GPIOF,GPIO_Pin_7);
} else {
GPIO_SetBits(GPIOF,GPIO_Pin_7);
}

if(key_value == 0x00000013)	 //说明是先按下第一个键,再按下第二个键
{
if(GPIO_ReadOutputDataBit(GPIOF,GPIO_Pin_9) == 1) { //翻转LED4
GPIO_ResetBits(GPIOF,GPIO_Pin_9);
} else {
GPIO_SetBits(GPIOF,GPIO_Pin_9);
}
} /*else if(key_value == 0x00000057)	//按键有问题,第三个按键不加入扫描
{
if(GPIO_ReadOutputDataBit(GPIOF,GPIO_Pin_9)==1) {//LED按键有问题ADC1 第三个按键默认经常是按下的状态
GPIO_ResetBits(GPIOF,GPIO_Pin_9);
} else {
GPIO_SetBits(GPIOF,GPIO_Pin_9);
}
}		*/
}
}
}
我应用的时候 优先级按键扫描任务给得比按键处理要高,亲测连续按下很多次之后LED2会每过1秒闪烁一下,如果满足要求LED4也会闪烁
原文地址http://my.oschina.net/mummy108/blog/126476
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  STM32 ucosii 按键 队列