OpenEdv-开源电子网

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

关于STM32F207移植uCOS-III后,延时函数延时不准确,求高手解答!

[复制链接]

6

主题

45

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2016-12-3
在线时间
47 小时
发表于 2017-1-12 15:33:27 | 显示全部楼层 |阅读模式
5金钱
最近用STM32F207做项目,移植了UCOS-III进去,任务切换已经没问题。现在就是关于延时函数有点问题。一开始我SysTick配置的是SysTick_Config(RCC_Clocks.HCLK_Frequency / 12000);用这个配置的话,用系统的延时函数OSTimeDly(100, OS_OPT_TIME_DLY, &err)延时是准确的。但是我想用delay_ms和delay_us函数,在网上找了一段代码例程,主芯片用的是STM32F407,但是我放到我的STM32F207上面就不能准确延时了,F407是168MHz的时钟主频,F207是120MHz时钟主频。有哪位大侠知道怎么配置delay_init()这个函数吗?
下面为delay的代码:
static u8  fac_us=0;           
static u16 fac_ms=0;

#define delay_osrunning                OSRunning                        //OS是否运行标记,0,不运行;1,在运行
#define delay_ostickspersec        OSCfg_TickRate_Hz        //OS时钟节拍,即每秒调度次数 ---  这里每秒的调度次数是1000u
#define delay_osintnesting         OSIntNestingCtr                //中断嵌套级别,即中断嵌套次数


void delay_init(u8 SYSCLK)
{
#if SYSTEM_SUPPORT_OS                                                 //如果需要支持OS.
        u32 reload;
#endif
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//SYSTICK使用外部时钟源         
        fac_us=SYSCLK/8;                                                //不论是否使用OS,fac_us都需要使用
#if SYSTEM_SUPPORT_OS                                                 //如果需要支持OS.
        reload=SYSCLK/8;                                                //每秒钟的计数次数 单位为K          
        reload*=1000000/delay_ostickspersec;        //根据delay_ostickspersec设定溢出时间
                                                                                        //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右       
        fac_ms=1000/delay_ostickspersec;                //代表OS可以延时的最少单位          
        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断
        SysTick->LOAD=reload;                                         //每1/OS_TICKS_PER_SEC秒中断一次       
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
#else
        fac_ms=(u16)fac_us*1000;                                //非OS下,代表每个ms需要的systick时钟数   
#endif
}


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));                                //普通方式延时
}


然后主函数
void main(void)
{
  RCC_ClocksTypeDef RCC_Clocks;
  RCC_GetClocksFreq(&RCC_Clocks);
  delay_init(120);          //时钟初始化
  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
  .
  .
  .
}

然后我在调用delay_ms()的时候,比如传参200的话,不是准确延时0.2s。
我认为是在delay_init()里面没有设置好参数,是这样的吗?@zuozhongkai

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

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2017-1-12 17:13:17 | 显示全部楼层
一般都是delay_init()里面出问题了,把你板子配置好的HCLK,PCLK1等这些时钟信息打印出来看一下是不是哪里时钟配置没有处理好
回复

使用道具 举报

6

主题

45

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2016-12-3
在线时间
47 小时
 楼主| 发表于 2017-1-12 18:00:02 | 显示全部楼层
本帖最后由 zhang90283 于 2017-1-12 18:01 编辑
zuozhongkai 发表于 2017-1-12 17:13
一般都是delay_init()里面出问题了,把你板子配置好的HCLK,PCLK1等这些时钟信息打印出来看一下是不是哪里 ...

HCLK ,PCLK1 ,PCLK2都配置没问题

20170112175602.png
回复

使用道具 举报

6

主题

45

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2016-12-3
在线时间
47 小时
 楼主| 发表于 2017-1-12 18:01:01 | 显示全部楼层
本帖最后由 zhang90283 于 2017-1-12 18:02 编辑

在线仿真读到的时钟
回复

使用道具 举报

6

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
216
金钱
216
注册时间
2018-8-13
在线时间
60 小时
发表于 2018-9-7 16:32:05 | 显示全部楼层
zhang90283 发表于 2017-1-12 18:01
在线仿真读到的时钟

你好,我最近也在207上移植ucos,能给个联系方式跟你学习学习吗
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-19 16:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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