软件延时:
晶振是20Mhz的
先CLKINDIV 再 PLLCR
CLKINDIV=0 晶振频率/2 CLKDIV=1 晶振频率不变
PLLCR取值为从0到10
SYSCKOUT=晶振与CLKINDIV关系过后*PLLCR
例如一个晶振20Mhz CLKINDIV=0 PLLCR=0X06
SYSCLKOUT=(20Mhz/2)*PLLCR=60Mhz
CPURATE=1/60Mhz=0.016667*10^-6=16.667*10^-9
则有#define CPU_RATE 16.667L
再例如一个晶振20MhzCLKINDIV=0 PLLCR=0XA
SYSCLKOUT=100Mhz
CPURATE=1/100Mhz=10*10^-9=10L
#define DELAY_US(A) DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)
extern void DSP28x_usDelay(Uint32 Count);
;// The C assembly call from the DELAY_US(time) macro will
;// look as follows:
;// extern void Delay(long LoopCount);
;//
;// MOV AL,#LowLoopCount
;// MOV AH,#HighLoopCount
;// LCR _Delay
;// Or as follows (if count is less then 16-bits):
;// MOV ACC,#LoopCount
;// LCR _Delay
;//###########################################################################
;// $TI Release: DSP280x C/C++ Header Files V1.70 $
;// $Release Date: July 27, 2009 $
;//###########################################################################
.def _DSP28x_usDelay
.sect "ramfuncs"
.global __DSP28x_usDelay
_DSP28x_usDelay:
SUB ACC,#1
BF _DSP28x_usDelay,GEQ ;; Loop if ACC >= 0
LRETR
;There is a 9/10 cycle overhead and each loop
;takes five cycles. The LoopCount is given by
;the following formula:
; DELAY_CPU_CYCLES = 9 + 5*LoopCount
; LoopCount = (DELAY_CPU_CYCLES - 9) / 5
; The macro DELAY_US(A) performs this calculation for you
LoopCount = (DELAY_CPU_CYCLES - 9) / 5
对比可知:
DELAY_CPU_CYCLES=
其中CPU_RATE=10L,所以上上式可以简写为:DSP28x_usDelay((A*100-9)/5)
DELAY_CPU_CYCLES=A*100
就是这个函数实际上延时的CPU周期数目,CPU_RATE=1/100M=10^-8s
一般A是一个比较大的数,至少要比100大,要不然延时没有意义,所以9可以忽略,最终
DELAY_CPU_CYCLES=A*100;这个公式很重要,记住这个是控制CPU时钟周期的个数。
延时时间:A*100*CPU_RATE=A*100*1/100M=Aus
正如函数名字所说是一个延时us级别的函数。
所以当A=5000,DELAY_CPU_CYCLES=A*100=5*10^5个CPU周期,也就是5*10^5*10^-8==5ms,再加个外循环让其循环
200次,就是1s的软件延时。
下面是CPURATE为100M时,延时1s的函数:
for(i=0;i<200;i++)
{
DELAY_US(5000);
}
误差应该出现在-9处
看到的一个实例,在实验室的圆网印花机项目中,师兄用到的一个延时函数:
// Time Delay:
extern void DSP_delay(Uint32 loopCount); // See DSP_delay.asm
// delay ( 9 + loopCount*5 ) SYSCLKOUT_Cycles
void delay_us(Uint32 N_us)
{
DSP_delay((N_us*ONE_US_CYC_CNT - 9)/5);
}
利用我上面的分析,CPURATE为1/40M,记住RATE指的是周期,==0.25*10^-7==25*10^-9=25L
所以为(A*(1000/25)-9)/5==(A*40-9)/5
CPU_RATE==1/40M.
DELAY_CPU_CYCLES=A*40;延时这么多个CPU周期的时间。
A*40*1/40 000000==Aus