只需兩步便可生成 51 微控制器最精準的延時函數

2023-01-18 12:01:13

前言

我們在學習 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 微控制器的延時函數就編寫完成啦, 快去試著生成一個延時函數,將它應用到你的專案當中吧。