代码未进ucos系统时,delay_ms()的最大延时为什么能超过5ms?

2019-07-20 10:04发布

上UCOSII系统,代码未进ucos系统时,delay_ms()的最大延时为什么能超过5ms(原子哥的例程中用的delay_ms(100);都可以)?
上UCOS系统后,未进入系统时,delay_ms(u16 nms)中只执行delay_us((u32)(nms*1000));,但是SysTick->LOAD=105000=(1000000/200)*168/8;这个重载值为5ms,delay_us()是按照数节拍数来进行的延时,这样应该是做不到大于5ms的延时的,那为什么能用delay_ms(100);呢?  
下面贴下代码:(红 {MOD}是相关代码
void delay_init(u8 SYSCLK)
{
#if SYSTEM_SUPPORT_OS                                                 //如果需要支持OS.
        u32 reload;
#endif
         SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
        fac_us=SYSCLK/8;                                                //不论是否使用OS,fac_us都需要使用
#if SYSTEM_SUPPORT_OS                                                 //如果需要支持OS.
        reload=SYSCLK/8;                                                //每秒钟的计数次数 单位为M           
        reload*=1000000/delay_ostickspersec;        //根据delay_ostickspersec设定溢出时间
                                                                                        //reload为24位寄存器,最大值:16777216,在168M下,约合0.7989s左右        
        fac_ms=1000/delay_ostickspersec;                //代表OS可以延时的最少单位           
        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;           //开启SYSTICK中断
        SysTick->LOAD=reload;                                         //每1/delay_ostickspersec秒中断一次        
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;         //开启SYSTICK   
#else
        fac_ms=(u16)fac_us*1000;                                //非OS下,代表每个ms需要的systick时钟数   
#endif
}        


void delay_us(u32 nus)
{               
        u32 ticks;
        u32 told,tnow,tcnt=0;
        u32 reload=SysTick->LOAD;                                //LOAD的值                     
        ticks=nus*fac_us;                                                 //需要的节拍数
        delay_osschedlock();                                        //阻止OS调度,防止打断us延时
        told=SysTick->VAL;                                        //刚进入时的计数器值
        while(1)
        {
                tnow=SysTick->VAL;        
                if(tnow!=told)
                {            
                        if(tnow<told)tcnt+=told-tnow;        //这里注意一下SYSTICK是一个递减的计数器就可以了.
                        else tcnt+=reload-tnow+told;            
                        told=tnow;
                        if(tcnt>=ticks)break;                        //时间超过/等于要延迟的时间,则退出.
                }  
        };
        delay_osschedunlock();                                        //恢复OS调度                                                                                            
}  


void delay_ms(u16 nms)
{        
        if(delay_osrunning&&delay_osintnesting==0)//如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度)            
        {                 
                if(nms>=fac_ms)                                                //延时的时间大于OS的最少时间周期
                {
                           delay_ostimedly(nms/fac_ms);        //OS延时
                }
                nms%=fac_ms;                                                //OS已经无法提供这么小的延时了,采用普通方式延时   
        }
        delay_us((u32)(nms*1000));                                //普通方式延时
}

        

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
taizonglai
1楼-- · 2019-07-20 10:19
UCOSII没运行之前delay_ms()为什么一定要小5ms?看delay_ms()函数源码,UCOSII没有运行起来之前调用的是delay_us()来实现延时的!delay_us()通过统计SYSTICK的计数值来实现延时的,这里面会处理SYSTICK溢出这个情况的,仔细分析delay_us()里面的told,tcnt,tnow,reload是用来干嘛的
jermy_z
2楼-- · 2019-07-20 10:28
那你觉得应该是多少????
xiyangzzz
3楼-- · 2019-07-20 12:54
 精彩回答 2  元偷偷看……
xiyangzzz
4楼-- · 2019-07-20 18:10
 精彩回答 2  元偷偷看……

一周热门 更多>