OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子全套STM32开发资料,上千讲STM32视频教程,RT1052教程免费下载啦...
查看: 420|回复: 4

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

[复制链接]

  离线 

1

主题

3

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2017-10-20
在线时间
3 小时
发表于 2018-1-12 11:21:45 | 显示全部楼层 |阅读模式
5金钱
上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);呢?  
下面贴下代码:(红色是相关代码
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));                                //普通方式延时
}

        

最佳答案

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

UCOSII没运行之前delay_ms()为什么一定要小5ms?看delay_ms()函数源码,UCOSII没有运行起来之前调用的是delay_us()来实现延时的!delay_us()通过统计SYSTICK的计数值来实现延时的,这里面会处理SYSTICK溢出这个情况的,仔细分析delay_us()里面的told,tcnt,tnow,reload是用来干嘛的
回复

使用道具 举报

  离线 

74

主题

6656

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
13325
金钱
13325
注册时间
2013-11-13
在线时间
1583 小时
发表于 2018-1-12 11:21:46 | 显示全部楼层
UCOSII没运行之前delay_ms()为什么一定要小5ms?看delay_ms()函数源码,UCOSII没有运行起来之前调用的是delay_us()来实现延时的!delay_us()通过统计SYSTICK的计数值来实现延时的,这里面会处理SYSTICK溢出这个情况的,仔细分析delay_us()里面的told,tcnt,tnow,reload是用来干嘛的
开往春天的手扶拖拉机
回复

使用道具 举报

  离线 

61

主题

5013

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
6324
金钱
6324
注册时间
2012-11-26
在线时间
1369 小时
发表于 2018-1-12 11:23:58 | 显示全部楼层
那你觉得应该是多少????
回复

使用道具 举报

  离线 

1

主题

3

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2017-10-20
在线时间
3 小时
 楼主| 发表于 2018-1-12 11:28:52 | 显示全部楼层
本帖最后由 xiyangzzz 于 2018-1-12 11:43 编辑
jermy_z 发表于 2018-1-12 11:23
那你觉得应该是多少????

未进入UCOSII系统前,delay_ms(u16 nms)的nms值应该小于5,我那里搞错了么?
回复

使用道具 举报

  离线 

1

主题

3

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2017-10-20
在线时间
3 小时
 楼主| 发表于 2018-1-12 15:19:50 | 显示全部楼层
zuozhongkai 发表于 2018-1-12 14:58
UCOSII没运行之前delay_ms()为什么一定要小5ms?看delay_ms()函数源码,UCOSII没有运行起来之前调用的是del ...

看清楚了,tcnt+=told-tnow;这里是累加,看漏了,闹了个笑话
回复

使用道具 举报

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

本版积分规则




关闭

报名原子哥新品发布会&粉丝见面会上一条 /1 下一条

正点原子公众号

QQ|联系我们|手机版|官方淘宝店|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-10-19 16:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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