羞羞小视频在线观看_羞羞视频免费入口网站_羞羞视频下载APP_男女羞羞视频软件

歡迎光臨東莞市飛江電子科技有限公司官網(wǎng)!
全國咨詢熱線

13926563901

18925580829

飛江淘寶店鋪

首頁>技術(shù)資料>51單片機(jī)

嵌入式C通用延時(shí)驅(qū)動(dòng)的編寫方法

發(fā)布時(shí)間:2018-03-26   瀏覽量:

  在嵌入式C編程中,免不了要用到軟件延時(shí)。這一般通過循環(huán)語句實(shí)現(xiàn)。通過控制循環(huán)語句的循環(huán)次數(shù),便可獲得多種不同的延時(shí)時(shí)間。為了便于使用和提高程序代碼的復(fù)用率,一般又將循環(huán)語句封裝成一個(gè)帶參數(shù)的函數(shù),稱為延時(shí)函數(shù)。如:
    void wait(unsigned int n)
    {
        unsigned int i;
        for(i=0;i
    }
 
    延時(shí)函數(shù)的參數(shù)(形參,如上例中的變量 n ),即為控制循環(huán)語句循環(huán)次數(shù)的變量。這樣,在需要軟件延時(shí)的時(shí)候,只需要調(diào)用延時(shí)函數(shù),并將實(shí)際參數(shù)(實(shí)參,即n的實(shí)際值)代入形參,便可獲得與該實(shí)際參數(shù)對(duì)應(yīng)的延時(shí)時(shí)間。
    這便是經(jīng)典的軟件延時(shí)的實(shí)現(xiàn)方法,非常簡(jiǎn)單。
    但細(xì)心的讀者會(huì)發(fā)現(xiàn):延時(shí)函數(shù)的參數(shù)(比如上面的 n ),表征的是循環(huán)語句的“循環(huán)次數(shù)”,而不是“實(shí)際的延時(shí)時(shí)間”。一般來說,假令循環(huán)語句每循環(huán)一次的時(shí)間為 b(注意,單位是“步”,即一個(gè)時(shí)鐘周期,下同),函數(shù)調(diào)用、傳值和返回所需的固有時(shí)間為 a ,那么,給定參數(shù) n 時(shí),調(diào)用一次延時(shí)函數(shù)實(shí)際實(shí)現(xiàn)的延時(shí)時(shí)間應(yīng)為 t = a + b*n , ——而不是 n !
    這就意味著,當(dāng)需要的延時(shí)時(shí)間為 t 時(shí),應(yīng)當(dāng)傳入的實(shí)參為 n = (t-a)/b,而不是 t 。這樣,為了獲得比較準(zhǔn)確的延時(shí),每次調(diào)用函數(shù)之前,都要手工計(jì)算實(shí)際參數(shù),很不方便;其次,當(dāng)需要改變晶振頻率的時(shí)候,程序中所有的延時(shí)參數(shù)都要重新計(jì)算,這顯然不利于程序的移植。
    為了解決這兩個(gè)問題,提高程序的可移植性,可以利用宏定義的方式,對(duì)延時(shí)函數(shù)進(jìn)行參數(shù)預(yù)修正。例如,對(duì)上面給出的wait延時(shí)函數(shù),可以使用下面的宏定義:
    #define delay(n)   wait(     (   (n) - a  ) / b     )
 
    這樣,調(diào)用 delay(t) 就意味著調(diào)用 wait( (t-a)/b ) ,從而得到時(shí)間為t的延時(shí),實(shí)現(xiàn)了參數(shù)與延時(shí)時(shí)間的同步,使用起來更加方便。
    為了進(jìn)一步提高可移植性,使軟件延時(shí)能夠適應(yīng)不同的晶振頻率,應(yīng)當(dāng)順著上面的思路選擇尋找更優(yōu)方案。那么,應(yīng)當(dāng)怎樣做呢?其實(shí)方法很簡(jiǎn)單。假設(shè)調(diào)用某個(gè)延時(shí)函數(shù) wait_step(n) 可以獲得 n 步的延時(shí),又設(shè)工作頻率為 f1,即每步的運(yùn)行時(shí)間為 T=1/f1,則實(shí)際獲得的延時(shí)時(shí)間為 t= n*T=n/f1。當(dāng)工作頻率變?yōu)?f2=C*f1 時(shí),程序運(yùn)行速度快了C倍,為了仍然獲得時(shí)間為t的延時(shí),程序運(yùn)行的步數(shù)應(yīng)當(dāng)是原來的C倍,即要調(diào)用wait_step(n*C)。這樣,我們就可以定義下面的宏,來完成(n*C)的運(yùn)算:
    #define   C    4
    #define   delay_t(n)  wait_step( n*C )
    第一行一般寫在文件開頭,當(dāng)修改晶振頻率時(shí),只需修改這一處就行了,不必在程序中對(duì)各個(gè) wait_step(n)的參數(shù)一一修改,大為方便。
 
    按照上面介紹的方法,可以編寫出準(zhǔn)確、易用、通用的延時(shí)驅(qū)動(dòng)。
    下面給出一個(gè)完整的延時(shí)驅(qū)動(dòng)程序。這是筆者早期編寫的版本,最近重新整理過。編繹器是ICC AVR V7.13A,運(yùn)行環(huán)境是AVR系列的所有芯片。使用的語句有三個(gè):
               微秒級(jí)延時(shí):delay_us(n);    延時(shí)n微秒
 
               毫秒級(jí)延時(shí):delay_ms(n);   延時(shí)n毫秒
               秒級(jí)延時(shí):    delay_s(n);      延時(shí)n秒 (最大65秒)
 
 
 
 
 
/*********************************************************************
 
        文件名  : DELAY.H
 
        功    能  : 通用的 軟件延時(shí) 驅(qū)動(dòng)文件。
        版    本  : 2009.11.27
 
        創(chuàng)建者  : 白羽
        聯(lián)    系  :
 
        說    明  : 使用時(shí)修改“配置信息”即可;其他地方請(qǐng)不要改
 
*********************************************************************/
#ifndef  _DELAY_H_
#define  _DELAY_H_
#define  uchar unsigned char
#define  uint  unsigned int
 
 
/*****************   ★○★  配 置 信 息  ★○★   ******************/
 
#define  CRYSTAL    8.0            //設(shè)置晶振頻率。單位是 MHZ
 
/************************************************************************/
 
 
#define  delay_us(T)  \
wait_us(  (T) > 14.0/CRYSTAL   ?   ((T)*CRYSTAL-8)/6.0   :   1   )
 
#define  delay_ms(T)  wait_ms( T )
 
#define  delay_s(n)  delay_ms(1000*(n))
 
/*********************************************************************
        函數(shù)名 : wait_us
        功  能 : 微秒(us)級(jí)的延時(shí)(粗糙)
        說  明 : 延時(shí)時(shí)間為:T = 8 + 6 * n (步)
/********************************************************************/
void wait_us( unsigned int n )
{
   do{
      n--;
   }while(n);
}
 
/*********************************************************************
        函數(shù)名 : wait_ms
        功  能 : 毫秒(us)級(jí)的延時(shí)
        說  明 : 當(dāng)do...while內(nèi)部為992us延時(shí)的時(shí)候,誤差為17步。
/********************************************************************/
void delay_ms( unsigned int n )
{
   do { 
      delay_us(992);  
   }while(--n);
}
 
 
#endif