开发环境是keil4.70a 数组
实验板为神舟三号 STM32F103ZET6 post
软件上使用到了固件库了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中
接下来贴上的按键扫描的任务 .net
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也会闪烁