M0的库函数DrvSYS_Delay(n)的误差较大的问题
用逻辑分析仪测试了一下M0的库函数DrvSYS_Delay(),在us级别感觉误差大得不能接受,在ms级别还行!HCLK 用的PLL,12M*4倍频,48M,Systick的source是HCLK
读出的时钟数据都没问题! us级别,考虑CPU跑50M的话,1个us才50个CPU clock cycle,
bl指令进函数就要3、4个cycle,出函数也要3、4个cycle,
程序跑在flash上可能又要加1、2个cycle,
再加上DrvSYS_Delay函数自身的代码,50个cycle一会儿就没了。
虽然回答马老师说,喜欢函数更甚于喜欢写寄存器,
但对这个时间量级,还是要具体分析。 是啊,我设置的48M,SysTick的source是HCLK
算上你说的那些,如果我给10us,就是480个cycle应该够了吧!
但是感觉100us内差距都很远的!
还有就是,库函数没有提供串口的设置定时计数器的初始值的函数,
只有函数设置没秒中断几次,这样好像不太够吧???
不知道是否我看资料不够详细!!!
感觉库还是不够,所以需要库操作与寄存器操作并行使用,这样混淆好像不太好! X-Hawk 兄,感觉你的基础很扎实,能否也出点学习笔记哦!
能否留个QQ,方便联系问请教问题!
谢谢! 楼上的,不客气,也在学习的。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) 是的,我正想宏定义一个函数!
谢谢兄台指点!
其实对于库,我也是这么理解的,我们可以通过了解库的实现去了解寄存器!
从系统的DrvSYS_Delay(us)方法中,其实已经高手我们,怎么设置sysTick了!!
我们可以根据我们的只是,自己写一些特定功能的库函数,而不一定是绝对通用的,绝对通用的函数要进行很多逻辑判断和运算,
效率自然就低了!! 搜到这里来的,顶一下 顶~ 回复【1楼】X-Hawk
虽然回答马老师说,喜欢函数更甚于喜欢写寄存器,
但对这个时间量级,还是要具体分析。
-----------------------------------------------------------------------
我的观点是辨证发展的。
从寄存器老老实实、踏踏实实的开始,将来就能驾御“库”,知道什么时候用库,什么时候不用库。
从不用delay_ms()老老实实、踏踏实实的开始,将来就能驾御delay_ms(),知道什么时候可以用delay_ms(),什么时候不可以用delay_ms()。
真正会用库的高手,肯定能直接操作寄存器,出了问题也能很快找到原因和解决办法。但这需要从操作寄存器开始积累的。
没有付出,就没有收获。付出的越多,收获也会越大。 都是高手, 顶一下.
页:
[1]