void delay_us(u32 nus)
{
u32 ticks;
u32 told,tnow,tcnt=0;
GET_CORE_CNT(told); //读取内核定时器数值
ticks=nus*48; //目标延时节拍数=需要延时时间(us)*CORE_CLK(MHz)/4
while(1)
{
GET_CORE_CNT(tnow);
if(tnow!=told)
{
if(tnow<told)tcnt=0xFFFFFFFF-told+tnow; //CORE_CNT递增32位,计算已延时节拍数
else tcnt=tnow-told;
if(tcnt>=ticks)break; //延时完成
}
};
}
离线
内核定时器频率为内核时钟的1/4
离线
感谢分享
离线
如果用y=kx+b的方式表示延时曲线,假设准确延时为直线y=x,实测内部192M时钟源情况下,12M线程延时大概是y=0.99415x+1.245,x为期望延时,y为实测延时。
根据经验分析,k值应该是时钟误差,换用外部晶振可以减小。b值则是调用函数、取值、译码、计算等造成的,线程频率越高,误差越小。
在以上猜测基础上,10us以内延时用本代码没有什么精确性可言,且各线程误差受线程频率影响较大。不考虑时钟误差的情况下,延时越长越精确,不同频率的线程延时结果越接近,如果是ms级延时,则可以认为是通用延时。
我脑补了半天也没想到10us以内的通用延时怎么写。
离线
@游乐场
微秒级的延时还是得用硬件定时器,做成宏函数或内联函数就没有调用损耗了。
离线
GET_CORE_CNT 宏展开是什么
离线
GET_CORE_CNT 宏展开是什么
是读取内核定时器的计数器,取一个指针的值
离线