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

main工作室發表於2023-01-18

前言

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

相關文章