OpenEdv-开源电子网

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

ucosII的任务切换问题,程序如下,出现的问题在后面,求大神帮忙

[复制链接]

24

主题

51

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
248
金钱
248
注册时间
2015-7-24
在线时间
32 小时
发表于 2016-8-4 14:42:06 | 显示全部楼层 |阅读模式
1金钱
#include "includes.h"

#define START_TASK_PRIO 10
#define START_STK_SIZE  128
OS_STK START_TAST_STK[START_STK_SIZE];
void start_task(void *pdata);

#define LED0_TASK_PRIO 7
#define LED0_STK_SIZE  64
OS_STK LED0_TASK_STK[LED0_STK_SIZE];
void led0_task(void *pdata);

#define LED1_TASK_PRIO 6
#define LED1_STK_SIZE  128
OS_STK LED1_TASK_STK[LED1_STK_SIZE];
void led1_task(void *pdata);

#define FLOAT_TASK_PRIO 5
#define FLOAT_STK_SIZE 128
__align(8) OS_STK FLOAT_TASK_STK[FLOAT_STK_SIZE];
void float_task(void *pdata);

int main(void)
{
        OS_CPU_SysTickInit();
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        
        uart_init(115200);
        LED_Init();
        TIM3_Int_Init();
        
        OSInit();
        OSTaskCreate(start_task,(void *)0,(OS_STK *)
                                &START_TAST_STK[START_STK_SIZE-1],START_TASK_PRIO);
        OSStart();
}

void start_task(void *pdata)
{
        OS_CPU_SR cpu_sr=0;
        pdata=pdata;
        OSStatInit();
        
        OS_ENTER_CRITICAL();
        OSTaskCreate(led0_task,(void *)0,(OS_STK *)
                  &LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);
        OSTaskCreate(led1_task,(void *)0,(OS_STK *)
                  &LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);
        OSTaskCreate(float_task,(void *)0,(OS_STK *)
                  &FLOAT_TASK_STK[FLOAT_STK_SIZE-1],FLOAT_TASK_PRIO);
        OSTaskSuspend(START_TASK_PRIO);
        OS_EXIT_CRITICAL();
}

void led0_task(void *pdata)
{
        while(1)
        {
                OS_CPU_SR cpu_sr=0;
                OS_ENTER_CRITICAL();
                LED0=0;
                delay_ms(50);//TIM3做的延时
                LED0=1;
                delay_ms(50);
                OS_EXIT_CRITICAL();
                OSTimeDly(10);
               
        }
}

void led1_task(void *pdata)
{
        while(1)
        {
                OS_CPU_SR cpu_sr=0;
                OS_ENTER_CRITICAL();
                LED1=0;
                delay_ms(1000);
                LED1=1;
                delay_ms(1000);
                OS_EXIT_CRITICAL();
                OSTimeDly(10);
               
        }
}

void float_task(void *pdata)
{
        OS_CPU_SR cpu_sr=0;
        static float float_num=0.01;
        while(1)
        {
                float_num+=0.01f;
                OS_ENTER_CRITICAL();
                printf("êä3öfloat_num:%.4f\r\n",float_num);
               
                delay_ms(500);
                OS_EXIT_CRITICAL();
                OSTimeDly(30);
        }
}
LED1灯闪烁正常,LED0亮的时间正常,但灭的时间过长,一直要等到LED1亮时才亮,串口打印也不是500ms,感觉是5s

最佳答案

查看完整内容[请看2#楼]

你这个不能用你自己做的delay_ms来延时,因为你这个延时没有任务切换;你的LED1正常显示是因为你的LED1的优先级高于LED0,这样在它得到CPU的资源的时候,只要不调用ucos系统自己的延时函数,它会一直执行;你的LED0执行的时候,只要你的LED1的系统延时时间到了就会被抢占,这样你的LED0的闪烁就不准了。 你可以把LED0的优先级设置成比LED1高,这样你的LED0就正常了,而LED1就不正常了,你可以测试一下
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
235
金钱
235
注册时间
2014-11-26
在线时间
25 小时
发表于 2016-8-4 14:42:07 | 显示全部楼层
你这个不能用你自己做的delay_ms来延时,因为你这个延时没有任务切换;你的LED1正常显示是因为你的LED1的优先级高于LED0,这样在它得到CPU的资源的时候,只要不调用ucos系统自己的延时函数,它会一直执行;你的LED0执行的时候,只要你的LED1的系统延时时间到了就会被抢占,这样你的LED0的闪烁就不准了。   你可以把LED0的优先级设置成比LED1高,这样你的LED0就正常了,而LED1就不正常了,你可以测试一下
回复

使用道具 举报

24

主题

51

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
248
金钱
248
注册时间
2015-7-24
在线时间
32 小时
 楼主| 发表于 2016-8-5 08:13:56 | 显示全部楼层
1376115749 发表于 2016-8-4 15:00
你这个不能用你自己做的delay_ms来延时,因为你这个延时没有任务切换;你的LED1正常显示是因为你的LED1的优 ...

要是用delay_ms();该怎么用怎么改?大神
void TIM3_Int_Init(void)
{
        RCC->APB1ENR|=1<<1;        //TIM6ê±&#214;óê1&#196;ü                     
}
//0<ms<=65535/2
void delay_ms(int ms)
{

        TIM3->PSC=36000-1;
        TIM3->CNT=0x00;
        TIM3->ARR=ms*2;          //éè&#182;¨&#188;&#198;êy&#198;÷×&#212;&#182;ˉ&#214;&#216;×°&#214;μ
//        TIM6->EGR = 0x0001;  //UG=1 á¢&#191;ì&#184;üD&#194;&#212;¤·&#214;&#198;μ&#198;÷£&#172;á¢&#191;ì&#199;&#229;&#191;&#213;&#188;&#198;êy&#198;÷£&#172;μ&#171;&#187;á2úéú&#184;üD&#194;&#214;D&#182;&#207;£&#172;ê1UIF&#214;&#195;1
//        TIM6->CR1|=(1<<3);
        TIM6->SR&=0x00;
//        TIM3->DIER=0x01;
        TIM3->CR1|=0x05;    //ARPE:&#206;T&#187;o3&#229;£&#172;UDIS£oé&#207;ò&#231;2úéú&#184;üD&#194;ê&#194;&#188;t£&#172;USR£o&#184;üD&#194;&#212;′&#214;&#187;óDé&#207;&#207;&#194;ò&#231;
        while((TIM3->SR&0x01)==0);        //μè′yê±&#188;&#228;μ&#189;′&#239;  &#184;üD&#194;&#214;D&#182;&#207;±ê&#214;&#190;&#206;&#187;£¨&#184;üD&#194;ê&#194;&#188;t£oò2ê&#199;&#182;&#212;ARRoíPSC&#184;üD&#194;£&#169;  
        TIM3->SR=0x00;
        TIM3->CR1&=~(1<<0);

}
回复

使用道具 举报

170

主题

917

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1824
金钱
1824
注册时间
2013-4-13
在线时间
63 小时
发表于 2016-8-6 00:47:19 来自手机 | 显示全部楼层
任务不能切换的原因很多,节拍,栈大小,甚至你的系统是否移植好
回复

使用道具 举报

5

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
235
金钱
235
注册时间
2014-11-26
在线时间
25 小时
发表于 2016-8-7 22:36:26 | 显示全部楼层
a1154870074 发表于 2016-8-5 08:13
要是用delay_ms();该怎么用怎么改?大神
void TIM3_Int_Init(void)
{

在delay_ms()里面调用系统的延时函数,只能这样,因为你的delay函数是死循环实现的
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-1 20:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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