OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2164|回复: 3

关于消息队列的代码问题

[复制链接]

1

主题

2

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-10-14
在线时间
3 小时
发表于 2018-10-14 11:56:45 | 显示全部楼层 |阅读模式
1金钱
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "includes.h"
#include"key.h"
#include"beep.h"
/************************************************
ALIENTEK战舰STM32开发板UCOS实验
例4-1 UCOSIII UCOSIII移植
技术支持:www.openedv.com
淘宝店铺:http://eboard.taobao.com
关注微信公众平台微信号:"正点原子",免费获取STM32资料。
广州市星翼电子科技有限公司  
作者:正点原子 @ALIENTEK
************************************************/

//UCOSIII中以下优先级用户程序不能使用,ALIENTEK
//将这些优先级分配给了UCOSIII的5个系统内部任务
//优先级0:中断服务服务管理任务 OS_IntQTask()
//优先级1:时钟节拍任务 OS_TickTask()
//优先级2:定时任务 OS_TmrTask()
//优先级OS_CFG_PRIO_MAX-2:统计任务 OS_StatTask()
//优先级OS_CFG_PRIO_MAX-1:空闲任务 OS_IdleTask()
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com  
//广州市星翼电子科技有限公司  
//作者:正点原子 @ALIENTEK

//任务优先级
#define START_TASK_PRIO                3
//任务堆栈大小       
#define START_STK_SIZE                 512
//任务控制块
OS_TCB StartTaskTCB;
//任务堆栈       
CPU_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *p_arg);

//任务优先级
#define MAIN_TASK_PRIO                4
//任务堆栈大小       
#define MAIN_STK_SIZE                 128
//任务控制块
OS_TCB MAINTaskTCB;
//任务堆栈       
CPU_STK MAIN_TASK_STK[MAIN_STK_SIZE];
void main_task(void *p_arg);

//任务优先级
#define KEY_TASK_PRIO                5
//任务堆栈大小       
#define KEY_STK_SIZE                 128
//任务控制块
OS_TCB KEYTaskTCB;
//任务堆栈       
CPU_STK KEY_TASK_STK[KEY_STK_SIZE];
//任务函数
void key_task(void *p_arg);

#define KEYMSG_Q_NUM        1        //按键消息队列的数量


OS_Q KEY_Msg;                                //定义一个消息队列,用于按键消息传递,模拟消息邮箱

int main(void)
{
        OS_ERR err;
        CPU_SR_ALLOC();
       
        delay_init();       //延时初始化
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置
        uart_init(115200);    //串口波特率设置
        LED_Init();         //LED初始化
        KEY_Init();        //按键扫描初始化
        BEEP_Init();      //蜂鸣器初始化
       
       
        OSInit(&err);                //初始化UCOSIII
        OS_CRITICAL_ENTER();//进入临界区
        //创建开始任务
        OSTaskCreate((OS_TCB         * )&StartTaskTCB,                //任务控制块
                                 (CPU_CHAR        * )"start task",                 //任务名字
                 (OS_TASK_PTR )start_task,                         //任务函数
                 (void                * )0,                                        //传递给任务函数的参数
                 (OS_PRIO          )START_TASK_PRIO,     //任务优先级
                 (CPU_STK   * )&START_TASK_STK[0],        //任务堆栈基地址
                 (CPU_STK_SIZE)START_STK_SIZE/10,        //任务堆栈深度限位
                 (CPU_STK_SIZE)START_STK_SIZE,                //任务堆栈大小
                 (OS_MSG_QTY  )0,                                        //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK          )0,                                        //当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void           * )0,                                        //用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR         * )&err);                                //存放该函数错误时的返回值
        OS_CRITICAL_EXIT();        //退出临界区         
        OSStart(&err);  //开启UCOSIII
        while(1);
}

//开始任务函数
void start_task(void *p_arg)
{
        OS_ERR err;
        CPU_SR_ALLOC();
        p_arg = p_arg;

        CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
   OSStatTaskCPUUsageInit(&err);          //统计任务               
#endif
       
#ifdef CPU_CFG_INT_DIS_MEAS_EN                //如果使能了测量中断关闭时间
    CPU_IntDisMeasMaxCurReset();       
#endif
       
#if        OS_CFG_SCHED_ROUND_ROBIN_EN  //当使用时间片轮转的时候
         //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms
        OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
#endif               
       
        OS_CRITICAL_ENTER();        //进入临界区
       
        //创建消息队列KEY_Msg
        OSQCreate ((OS_Q*                )&KEY_Msg,        //消息队列
                (CPU_CHAR*        )"KEY Msg",        //消息队列名称
                (OS_MSG_QTY        )KEYMSG_Q_NUM,        //消息队列长度,这里设置为1
                (OS_ERR*        )&err);                //错误码                                       
       
        //创建MAIN任务
        OSTaskCreate((OS_TCB         * )&MAINTaskTCB,               
                                 (CPU_CHAR        * )"main task",                
                 (OS_TASK_PTR )main_task,                        
                 (void                * )0,                                       
                 (OS_PRIO          )MAIN_TASK_PRIO,     
                 (CPU_STK   * )&MAIN_TASK_STK[0],       
                 (CPU_STK_SIZE)MAIN_STK_SIZE/10,       
                 (CPU_STK_SIZE)MAIN_STK_SIZE,               
                 (OS_MSG_QTY  )0,                                       
                 (OS_TICK          )0,                                       
                 (void           * )0,                                       
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
                 (OS_ERR         * )&err);                               
                                 
        //创建KEY
        OSTaskCreate((OS_TCB         * )&KEYTaskTCB,               
                                 (CPU_CHAR        * )"key task",                
                 (OS_TASK_PTR )key_task,                        
                 (void                * )0,                                       
                 (OS_PRIO          )KEY_TASK_PRIO,            
                 (CPU_STK   * )&KEY_TASK_STK[0],       
                 (CPU_STK_SIZE)KEY_STK_SIZE/10,       
                 (CPU_STK_SIZE)KEY_STK_SIZE,               
                 (OS_MSG_QTY  )0,                                       
                 (OS_TICK          )0,                                       
                 (void           * )0,                               
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
                 (OS_ERR         * )&err);       
                         
       
}

//主任务函数
void main_task(void *p_arg)
{
        u8 key;
        OS_ERR err;
       
        while(1)
        {
                key = KEY_Scan(0);  //扫描按键
                if(key)
                {
                        //发送消息
                        OSQPost((OS_Q*                )&KEY_Msg,               
                                        (void*                )&key,
                                        (OS_MSG_SIZE)1,
                                        (OS_OPT                )OS_OPT_POST_FIFO,
                                        (OS_ERR*        )&err);
                }
/*                num++;
                if(num%10==0) check_msg_queue(p);//检查DATA_Msg消息队列的容量
                if(num==50)
                {
                        num=0;
                        LED0 = ~LED0;
                }*/
                OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err);   //延时10ms
        }
}

//按键任务函数
void key_task(void *p_arg)
{
        u8 *key;
        OS_MSG_SIZE size;
        OS_ERR err;
        while(1)
        {
                //请求消息KEY_Msg
                key=OSQPend((OS_Q*                        )&KEY_Msg,   
                                        (OS_TICK                )0,
                    (OS_OPT                        )OS_OPT_PEND_BLOCKING,
                    (OS_MSG_SIZE*        )&size,               
                    (CPU_TS*                )0,
                    (OS_ERR*                )&err);
                switch(*key)
                {
                        case WKUP_PRES:                //KEY_UP控制LED1
                                LED1 = ~LED1;
                                break;
                        case KEY2_PRES:                //KEY2控制蜂鸣器
                                BEEP = ~BEEP;
                                break;
/*                        case KEY0_PRES:                //KEY0刷新LCD背景
                                num++;
                                LCD_Fill(126,111,233,313,lcd_discolor[num%14]);
                                break;
                        case KEY1_PRES:                //KEY1控制定时器1
                                tmr1sta = !tmr1sta;
                                if(tmr1sta)
                                {
                                        OSTmrStart(&tmr1,&err);
                                        LCD_ShowString(10,150,100,16,16,"TMR1 START!");
                                }
                                else
                                {
                                        OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
                                        LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
                                }
                                break;
*/
                }
        }
}
这个代码编译没有问题但是烧到板子里,没有对应的实验现象,我的代码希望实现的是通过按键实现蜂鸣器和一个LED 的控制

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-10-14
在线时间
3 小时
 楼主| 发表于 2018-10-14 11:59:10 | 显示全部楼层
对了,我是移植UCOS3到战舰F1上,然后使用消息队列,没有出现象
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-10-15 02:33:50 | 显示全部楼层
帮顶
回复

使用道具 举报

23

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2315
金钱
2315
注册时间
2017-7-6
在线时间
281 小时
发表于 2018-10-15 08:56:52 | 显示全部楼层
工程附上,大家有空的帮你看看
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 21:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表