高精度延时函数的实现
2019-07-13 15:16发布
生成海报
1、用for函数实现
void udelay()
{
int i;
for(i=0; i 在udelay函数中,用一个for循环进行延时,但是我们怎么确定xxx这个值呢? 可以用test函数,每次udelay后就拉高一个GPIO,然后再udelay一次后拉低GPIO。并用示波器测测量出波形,通过不停的调整xxx的值,直到波形的间隔为1微妙。 当然,这样有两个明显的缺点(1)需要使用示波器,比较麻烦(2)for循环在SDRAM和nor flash运行的速度不一样,所用的时间就不一样,所以精度就不准的。所以我们使用第二种方法
2、用定时器实现
(1)每来一个CLK,计数值减一(2)减到0后,重新加载初始值假设Tclk=0.1us,当定时器里面的计数值减了10,就对应了1us比如,以jz2440的芯片为例void timer_init()
{
/*设置TIMER0的时钟*/
/* Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
* = 50000000 / (4 + 1) / 2
* = 5000000
* 每减1,对应0.2us
* 每减5,对应1us
* 50000减到0,对应10ms
*/
TCFG0 = 4; /*Prescaler 0 = 4,用于timer0,1*/
TCFG1 &= ~0xf;/*MUX0 : 1/2*/
/*设置TIMER0的初值*/
TCNTB0 = 50000; /*10Ms中断一次*/
/*加载初值,启动timer0*/
TCON |= 1<<1; /*Update from TCNTB0 & TCMPB0*/
/*设置为自动加载*/
TCON &= ~(1<<1);
TCON |= (1<<0) | (1<<3); /*bit0:start , bit3: auto reload*/
/*设置中断*/
register_irq(10, timer_irq);
}
/*为了保证精度,尽量少调用函数*/
void udelay(int n)
{
int cnt = n * 5; //n us对应n*5个计数值
int pre = TCNTO0; //当前的计数值可以从这个寄存器读
int cur;
int delta;
while(cnt > 0)
{
cur = TCNTO0;
if( cur <= pre )
{
delta = pre - cur;
}
else
{
delta = pre + (50000 - cur);//减到0后,会重新加载初始值,有可能cur大于pre
}
cnt = cnt - delta;
pre = cur;
}
}
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮