前言 我們在學習 51 單片機的過程中會用到延時,比如一個簡單的流水燈就需要延時來控制依次點亮的時間,或者一些模塊在單片機發出讀數據指令後,需要延時幾十微秒才可以讀出數據等等,這些都離不開延時,所以我們需要一個精準的延時函數來滿足我們的需求。 本篇介紹一個最簡單並且延時最精準的 51 單片機延時函數 ...
前言
我們在學習 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 單片機的延時函數就編寫完成啦, 快去試著生成一個延時函數,將它應用到你的項目當中吧。
本文作者:main工作室
本文鏈接:https://www.cnblogs.com/main-studio/p/17059320.html
版權聲明:本文為「main工作室」的原創文章,遵循 CC BY-NC-ND 4.0 版權協議,著作權歸作者所有,轉載請註明出處!
鼓勵博主:如果您覺得文章對您有所幫助,可以點擊文章右下角【推薦】一下。您的鼓勵就是博主最大的動力!