DSP

高精度延时函数的实现

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; } }