中级会员
 
- 积分
- 313
- 金钱
- 313
- 注册时间
- 2016-12-3
- 在线时间
- 47 小时
|
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
|
|