前言
我們在學習 51 微控制器的過程中會用到延時,比如一個簡單的流水燈就需要延時來控制依次點亮的時間,或者一些模組在微控制器發出讀資料指令後,需要延時幾十微秒才可以讀出資料等等,這些都離不開延時,所以我們需要一個精準的延時函式來滿足我們的需求。
本篇介紹一個最簡單並且延時最精準的 51 微控制器延時函式的生成方法。
STC-ISP
我們說學習 51 微控制器,大部分學習的都是國產的 STC89C51 微控制器,我就是從這款微控制器入門的。
STC89C51 是 STC 這家公司研發生產的,同時 STC 提供了一個下載程式設計燒錄軟體——STC-ISP,這款軟體可是一個好東西,不會有朋友只用它來下載程式吧?
它有好多強大且實用的功能,本篇介紹一下它的軟體延時計算器功能。
如何下載
進入 STC 官網,將頁面向下就可以找到下載連結啦。
STC 官網 >> 點選跳轉
如何使用
開啟軟體,找到“ 軟體延時計算器 ”,設定引數後,點選生成程式碼後複製即可。
注意:設定的引數一定要和使用的微控制器引數相匹配。
最佳化程式碼
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
上面是我從軟體中生成複製的程式碼,軟體已經自動生成了一個函式供我們呼叫,短短几步就做好了一個延時函式,確實不錯。
但這個函式在呼叫時只能延時 1ms
,如果說我想延時 2ms、3ms、4ms...
難道要不停的呼叫函式嗎?或者再去軟體中生成新的延時函式?那豈不是很麻煩。
其實不必這樣,我們只需簡單的最佳化一下程式碼,就可以實現我們想要的功能。
更改思路如下:
軟體所生成的函式是延時
1ms
,就是說微控制器執行這個函式的程式體時用時為1ms
。理解這個以後,我們便可以最佳化程式啦。
首先我們用
while
迴圈把程式體框住,然後每執行一次讓控制while
迴圈結束的變數減一,這個變數我們透過形參傳遞到函式中。
注意:當使用
_nop_()
函式(可理解為軟體延時)時,必須在開頭新增標頭檔案#include <intrins.h>
。
_nop_()
函式相當於一個空操作(可以理解為 NOP 空操作指令),而_nop_()
函式的空操作產生的時間與晶振有關,所以在上文中設定引數要與使用的微控制器引數相匹配。
最佳化後的程式碼如下:
#include <intrins.h>
void Delay1ms(unsigned int _ms) //@11.0592MHz
{
unsigned char i, j;
while (_ms--)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
如何呼叫
經過我們最佳化後的延時函式在呼叫時極其簡單,只需在呼叫函式的語句中放入實參就好啦。
呼叫演示程式碼如下:
#include <reg52.h>
#include <intrins.h>
void Delay1ms(unsigned int _ms); /* 宣告延時函式 */
void main()
{
Delay1ms(1); /* 實參為 1,則延時 1ms */
Delay1ms(20); /* 實參為 20,則延時 20ms */
Delay1ms(500); /* 實參為 500,則延時 500ms */
/* ...... */
}
void Delay1ms(unsigned int _ms) //@11.0592MHz
{
unsigned char i, j;
while (_ms--)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
後記
至此,51 微控制器的延時函式就編寫完成啦, 快去試著生成一個延時函式,將它應用到你的專案當中吧。