【转】关于PIC常用软件延时的精确计算公式
原帖地址:http://www.pic16.com/bbs/dispbbs.asp?boardID=9&ID=22973
延时在单片机应用中经常要用到,不管是测试还是正是的开发的程序中延时子程序都是随处可见。而延时又分硬件延时和软件延时。本贴所要说的延时是指常用的二重循环的软件延时,并推导出准确的计算公式,该公式能精确到一条指令都不差。因为软件延时比较耗CPU资源,所以可能用的地方不多,也没必要精确一条不差那么准,但我推导的公式也许对这有兴趣的人可能有用。
二重循环延时公式:T(x,y,n)=nxy+3xy+4x+5(x为外循环变量值, y为内循环变量值,n为内循环中nop指令的个数)
三重循环延时公式:T(x,y,z,n)=(3+n)xyz+4xy+4x+5; (x为最外层循环变量值,y为第二层循环变量值,z为最里层循环变量值,n为内循环中nop指令的个数)
n重循环:T(a1,a2,..,an,n)=(3+n)a1a2..an+4(a1a2..an-1+a1a2..an-2+..+a1)+5;(a1为最外层循环变量值,a2为第二层循环变量值,其他的依次类推,an为最里层循环变量值,n为最里层循环nop指令的个数)
具体的延时程序格式以其测试程序见下面的程序:
- list p=16f877a,r=hex
- #include"p16f877a.inc"
- ;***************************************
- cblock 21h
- del_count1,del_count2
- endc
- ;***************************************
- #define x .100
- #define y .32
- ;***************************************
- org 0000h
- nop
- goto main
- org 0008h
- main
- nop ;该处设一个断点,运行到此处,stopwatch应清0
- call delay
- nop ;该处再设一个断点,运行到此处的stopwatch的值应减1才为Delay的准确时间
- goto $
- ;**************************************************
- ;* 延时时间T(x,y)=nxy+3xy+4x+5(us)假设晶振为4MHz *
- ;* x为外循环变量值,y为内循环变量值。 *
- ;* n为内循环中nop指令的个数。 *
- ;* 计算过程: *
- ;* T(x,y)=2+1+1+[1+1+(1+2)*y-1+1+2]*x-1+2 *
- ;* =nxy+3xy+4x+5 *
- ;**************************************************
- delay
- movlw x
- movwf del_count1
- del01
- movlw y
- movwf del_count2
- del02
- nop ;此处的nop指令个数n可以随意添减,此处为2条,但建议1到5条为宜,再多就没意义了。
- nop
- decfsz del_count2,f
- goto del02
- decfsz del_count1,f
- goto del01
- return
- ;******************************************
- end
- ;当内循环nop指令为0个时: Tmax=T(255,255)=196100us=196.1ms
- ; Tmin=T(1,1)=12us=0.012ms
- ;故在该情况下延时范围为:(12us~196.1ms)
注:因为本公式为正向推导的过程,所当确定一个需要延时的时间T时,反向推导它会有多种x,y,n的组合,但肯定有一种时最佳(既最接近)的组合,有兴趣的朋友可以写个程序来计算出这个最佳组合。

















