DSP

DSP软件延时

2019-07-13 09:40发布

软件延时: 晶振是20Mhz CLKINDIV 再 PLLCR CLKINDIV=0 晶振频率/2  CLKDIV=1  晶振频率不变 PLLCR取值为从010 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