okelec 发表于 2010-11-4 16:19:31

M0的库函数DrvSYS_Delay(n)的误差较大的问题

用逻辑分析仪测试了一下M0的库函数DrvSYS_Delay(),在us级别感觉误差大得不能接受,在ms级别还行!
HCLK 用的PLL,12M*4倍频,48M,Systick的source是HCLK
读出的时钟数据都没问题!

X-Hawk 发表于 2010-11-8 18:21:14

us级别,考虑CPU跑50M的话,1个us才50个CPU clock cycle,
bl指令进函数就要3、4个cycle,出函数也要3、4个cycle,
程序跑在flash上可能又要加1、2个cycle,
再加上DrvSYS_Delay函数自身的代码,50个cycle一会儿就没了。

虽然回答马老师说,喜欢函数更甚于喜欢写寄存器,
但对这个时间量级,还是要具体分析。

okelec 发表于 2010-11-10 02:18:06

是啊,我设置的48M,SysTick的source是HCLK
算上你说的那些,如果我给10us,就是480个cycle应该够了吧!
但是感觉100us内差距都很远的!

还有就是,库函数没有提供串口的设置定时计数器的初始值的函数,
只有函数设置没秒中断几次,这样好像不太够吧???

不知道是否我看资料不够详细!!!

感觉库还是不够,所以需要库操作与寄存器操作并行使用,这样混淆好像不太好!

okelec 发表于 2010-11-10 02:19:17

X-Hawk 兄,感觉你的基础很扎实,能否也出点学习笔记哦!
能否留个QQ,方便联系问请教问题!
谢谢!

X-Hawk 发表于 2010-11-10 09:55:04

楼上的,不客气,也在学习的。QQ最近大战360, 咱力挺周流氓的,哈哈。。。

DrvSYS_Delay的主要问题,可能处在这句中的除法运算
SysTick->LOAD = (us * (SystemCoreClock / 10000)) / 100;

除法在这里是个函数调用,并非硬件指令完成的。
执行两次除法函数的时间,就相当可怕了。

函数库虽然不一定效率很高,学习起来却是最省事的,清楚明白的让我们知道怎么改。
如果确定用48M的话,建议仿效函数库,重新定义一个My_DrvSYS_Delay, 完全不要函数调用并去掉除法。

#define My_DrvSYS_Delay(us) do                                                 \
{                                                                              \
    SysTick->LOAD = (us) * (48000000 / 1000000);                               \
    SysTick->VAL= (0x00);                                                    \
    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;      \
    /* Waiting for down-count to zero */                                       \
    while((SysTick->CTRL & (1 << 16)) == 0);                                 \
} while(0)

okelec 发表于 2010-11-10 11:00:44

是的,我正想宏定义一个函数!
谢谢兄台指点!

其实对于库,我也是这么理解的,我们可以通过了解库的实现去了解寄存器!
从系统的DrvSYS_Delay(us)方法中,其实已经高手我们,怎么设置sysTick了!!
我们可以根据我们的只是,自己写一些特定功能的库函数,而不一定是绝对通用的,绝对通用的函数要进行很多逻辑判断和运算,
效率自然就低了!!

xiaojian 发表于 2010-11-27 09:17:54

搜到这里来的,顶一下

liguohx 发表于 2011-1-20 12:02:41

顶~

machao 发表于 2011-1-20 15:22:01

回复【1楼】X-Hawk

虽然回答马老师说,喜欢函数更甚于喜欢写寄存器,
但对这个时间量级,还是要具体分析。

-----------------------------------------------------------------------
我的观点是辨证发展的。

从寄存器老老实实、踏踏实实的开始,将来就能驾御“库”,知道什么时候用库,什么时候不用库。

从不用delay_ms()老老实实、踏踏实实的开始,将来就能驾御delay_ms(),知道什么时候可以用delay_ms(),什么时候不可以用delay_ms()。

真正会用库的高手,肯定能直接操作寄存器,出了问题也能很快找到原因和解决办法。但这需要从操作寄存器开始积累的。

没有付出,就没有收获。付出的越多,收获也会越大。

nomorehest 发表于 2012-1-28 19:31:16

都是高手, 顶一下.
页: [1]
查看完整版本: M0的库函数DrvSYS_Delay(n)的误差较大的问题