久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

嵌入式C通用延時驅動的編寫方法

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

相關文章

主站蜘蛛池模板: www.久久99| 国产成人亚洲精品自产在线 | 午夜精品福利视频 | 一区二区影院 | 久久小视频 | 很很干很很日 | 成人免费视频在线观看 | 在线观看中文字幕一区二区 | 美女黄网 | 欧美一区二区在线观看 | 婷婷色国产偷v国产偷v小说 | 精品国产精品三级精品av网址 | 亚洲欧美在线视频 | 亚洲高清在线免费观看 | 久久精品国产一区二区电影 | 国产一区二区黑人欧美xxxx | 免费99精品国产自在在线 | 国产精品99视频 | 美女逼网站 | 久久99精品久久久久久 | 欧美一区二区免费在线 | 国产精品精品视频 | 在线欧美一区 | 翔田千里一区二区 | 欧美一级小视频 | 精品乱子伦一区二区三区 | 成人妇女免费播放久久久 | 成人av观看 | 国产日韩精品视频 | 精品国产欧美 | 日本视频一区二区 | 超碰成人免费 | 国产成人福利在线观看 | 成人福利在线观看 | www.色婷婷 | 亚州成人| 色橹橹欧美在线观看视频高清 | 国产精品美女久久久久久久网站 | 国产黑丝av | 亚洲色图婷婷 | 亚洲欧美日本国产 |