开发环境是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
来源:oschina
链接:https://my.oschina.net/u/1000353/blog/126476