nigel1983 发表于 2019-4-16 12:39:50

STM32L0 us延时误差大,不知原因!好心人指教!谢谢!

voidConfigure_TIMTimeBase(void)
{
    uint32_t v;
//TIM2使用的时钟为HSI 16MHz(AHB,APB1总线未分频)
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
LL_TIM_SetPrescaler(TIM2, 16);
LL_TIM_SetCounterMode(TIM2,LL_TIM_COUNTERMODE_DOWN);   
}


voidDelayUs(uint16_t us)
{      
    LL_TIM_SetCounter(TIM2,us);   
    LL_TIM_EnableCounter(TIM2);   
    while( LL_TIM_IsEnabledCounter(TIM2) && !LL_TIM_IsActiveFlag_UPDATE(TIM2))
    {
    }   
    LL_TIM_ClearFlag_UPDATE(TIM2);
    LL_TIM_DisableCounter(TIM2);   
}
延时误差相当大,延时越长误差越大。没搞懂原因. 2ms误差0.14ms (140us)。
用SYSTICK定时器精度正常,误差一直在14us左右(由于HSI是RC时钟和代码的原因导致,在可接受范围内)

edmundlee 发表于 2019-4-16 13:00:54

LL_TIM_SetPrescaler(TIM2, 15);

MrJiu 发表于 2019-4-16 14:17:37

不知道什么东西需要那么高的要求!!!我一般us级别的延时,都是用的while,差不多就可以了。。。如果要高要求,以你的这种写法肯定不行,进函数,出函数,都需要时间的,甚至都达到us级别了。。。用寄存器,而且最好是能够计算到进栈,出栈,甚至定位到汇编,一句一句计算。。。这也才是最精确的!!!

toofree 发表于 2019-4-16 14:29:48

用定时器死等,还不如软件死等呢。
用while做延时粗调,NOP做短延时补尝微调。
要求高的话,还可以分段细化延时,比如Delay_us()、Delay_10us()、Delay_100us()、Delay_ms()、Delay_10ms()、Delay_100ms()。

Kevin201707 发表于 2019-4-16 15:50:18

LL_TIM_SetPrescaler(TIM2, 15);
可以用更少的分频,更多的计数 看一看。

nigel1983 发表于 2019-4-16 16:44:40

感谢这么多人关注指教!感谢大家,我只是奇怪精度为什么差这么多!我再试试!

nigel1983 发表于 2019-4-16 16:49:32

我测试了一下 16MHz时钟空跑while一次约0.44us,控制得好也算比较精准我的MCU是L073R8t6

edmundlee 发表于 2019-4-16 16:50:34

nigel1983 发表于 2019-4-16 16:44
感谢这么多人关注指教!感谢大家,我只是奇怪精度为什么差这么多!我再试试! ...

LL_TIM_SetPrescaler(TIM2, 15);
我的回复你都没看明白?
分频16, 是写成16-1的, 你写16就变成分频17了, 明白?

nigel1983 发表于 2019-4-19 09:38:32

好的,谢谢!明白了!

Dylan疾风闪电 发表于 2019-4-19 09:53:29

延时可以使用滴答器 systick,
例如:
配置中断触发间隔1us;
SysTick_Handler中断只计数count。
应用时只需要对count监测差值,就能得到准确的us延时。其精度取决于时钟源/晶振:)
页: [1]
查看完整版本: STM32L0 us延时误差大,不知原因!好心人指教!谢谢!