概述
在程序設(shè)計中我們經(jīng)常會用到延時,對于精度要求不高的應(yīng)用來說我們一般采用插入語句等待的方式來實現(xiàn),對于精度高的應(yīng)用來說我們一般采用定時器中斷來實現(xiàn)。本章主要內(nèi)容包括:
- 延時時間的調(diào)試
- 定時器功能介紹
- 定時器應(yīng)用實例介紹
6.1延時調(diào)試
前面程序中用到的延時通過執(zhí)行多條語句來實現(xiàn)的,那么我們會問執(zhí)行一條語句需要多長時間,延時1ms又需要多少條語句,延時的精度高嗎?下面講解的內(nèi)容將包含以上內(nèi)容。眾所周知,晶振為單片機提供了時間基準(zhǔn),在晶振的節(jié)拍下程序按時間順序往下執(zhí)行,在單片機應(yīng)用中有三個重要的時間概念,分別為時鐘周期、機器周期和指令周期。
時鐘周期: 單片機晶振頻率的倒數(shù),例如開發(fā)板的板載晶振為11.0592MHz,時鐘周期為1/11.0592us,是51單片機的最基本,最小的時間單位。
機器周期: 單片機完成一條最基本指令操作所需要的時間,51單片機的一個機器周期等于12個時鐘周期,RY-51開發(fā)板機器周期:12/11.0592us=1.09us。
指令周期: 執(zhí)行一條指令所需的時間,一般由若干個機器周期組成。當(dāng)然根據(jù)指令的不同所需的機器周期也不同,只需一個機器周期的簡單指令,稱之為單周期指令,包含兩個機器周期的指令稱之為雙周期指令。
以RY-51單片機開發(fā)板為例,執(zhí)行一條最簡單的語句需要至少1.09us,復(fù)雜的語句需要多個1.09us來實現(xiàn)。因此,我們常常在程序中通過添加數(shù)目不等的簡單語句來實現(xiàn)延時,但是延時的精度往往不會太高,我們可以通過keil軟件的仿真功能來確定延時的大概數(shù)值。接下來講解延時函數(shù)仿真功能,我們以延時10ms為例進行介紹。
#include< reg52.h >
sbit led0 = P1^0;//LED小燈管腳定義
sbit FM = P2^4;//蜂鳴器管腳位定義
sbit Key17 = P3^0;//獨立按鍵管腳定義
void delayms(unsigned int z)//延時函數(shù)
{
unsigned int x,y;
for(x=z;x >0;x--)
for(y=70;y >0;y--);
}
void main()
{
while(1)
{
delayms(10);//延時10ms
delayms(10);//延時10ms
delayms(10);//延時10ms
}
}
首先,根據(jù)前面介紹的步驟建立一個工程,并編輯好如上所示的代碼。這個代碼和前面講解的代碼有點不同,我們先把延時的語句寫成一個函數(shù)delayms(),將其放在主程序之外。在主程序中調(diào)用函數(shù)來實現(xiàn)延時。改變延時函數(shù)的輸入?yún)?shù)便可改變延時語句的條數(shù),因此延時變得非常的靈活。主程序中我們對延時函數(shù)進行了三次調(diào)用,接下來我們看看執(zhí)行一次函數(shù)調(diào)用需要多長時間。
在keil軟件快捷按鈕菜單欄中找到配置,點擊進入如下圖所示的子菜單:
如上圖所示,在”Target”目錄先將仿真晶振設(shè)置為“11.0592”。
如圖所示,在“C51”目錄下將代碼優(yōu)化等級設(shè)置為“0:Constant folding”。
設(shè)置好如上規(guī)則后,點擊菜單欄的debug快捷鍵如下圖所示,進入調(diào)試模式,可以看到程序進程已經(jīng)執(zhí)行到了第17條代碼。
接下來給17,18,19三條語句設(shè)置斷點,將鼠標(biāo)移到語句處點擊右鍵選擇“insert/Remove Breakpoint”,設(shè)置好之后語句左邊會出現(xiàn)紅色的小方塊。當(dāng)程序執(zhí)行到斷點時,程序便會停止下來。
如圖6-5所示,當(dāng)程序順序執(zhí)行的黃色箭頭停留在第17行時,所使用的時間為:0.00042209s,如圖左側(cè)所示。
點擊如圖6-6左上角的程序執(zhí)行快捷鍵,程序進程黃色箭頭停留在第18行,即執(zhí)行完了一條延時函數(shù)語句delayms(10),觀察左下角的進程時間為:0.01057943s將執(zhí)行語句前后時間相減,結(jié)果約等于10.1ms,因此與我們延遲10ms的要求相符。
通過調(diào)用函數(shù)實現(xiàn)延時的方法在單片機編程中是非常常見的,經(jīng)過上面的延時調(diào)試可見這種方法的精度并不是很高,對應(yīng)特殊應(yīng)用場合我們一般采用定時器的方式實現(xiàn)。
6.2定時器介紹
定時器的功能很容易理解,就是到了某個指定的時間會提示設(shè)定者,我們平常使用的鬧鐘實際上可看作是一個定時器。定時器是單片機的重要資源,那么我們什么時候會使用到單片機的定時器功能呢?正常情況下我們一直在運行單片機的主程序,在主程序中假設(shè)我們需要1s之后去執(zhí)行某個操作,這時我們只好在主程序中進行延時,直到1s時間到了再去執(zhí)行相應(yīng)的操作,那么在這個延時的過程中主程序別的事情干不了了,這樣就很浪費系統(tǒng)的資源。
如果我們這個時候使用定時器功能就可以很好的解決這個問題。首先,我們在主程序中設(shè)定定時器定時1s,并啟動定時器開始計時,因為定時器的運行和單片機的主程序執(zhí)行是分開的,不會相互影響,因此主程序繼續(xù)往下執(zhí)行。當(dāng)1s的時間到了,定時器告訴主程序,這個時候主程序停下當(dāng)前正在干的活而去響應(yīng)定時器。
STC89C52系列單片機內(nèi)置2個16位的定時器,同時也可以當(dāng)作計數(shù)器來用,分別為定時器0(T0),定時器1(T1),每個定時器有4種工作方式。那么定時器是如何計時的呢?我們以定時器T0工作在16位模式下進行介紹。16位的二進制的最大值為:0b1111,1111,1111,1111=65535。首先,我們需要給這個16位的寄存器賦初始值,假設(shè)為1000,當(dāng)我們在主程序中啟動定時器T0,此時這個寄存器會每12個時鐘周期從1000開始往上加1,直到加到65535,當(dāng)再加1后,定時器T0就溢出了,寄存器值從65535變成0,當(dāng)溢出后定時器會告訴主程序,定時時間到了。所以我們只要改變這個初始值1000就可以得到不同的定時時間了。細心的同學(xué)可能會發(fā)現(xiàn),當(dāng)初始值為0的時候可以定時的時間最長。那么我們來看看定時器T0工作在16位模式下最長能定時多久。我們開發(fā)采用的時鐘頻率為11.0592MHz,因此,每12個時鐘周期時間為:12/11.0592us=1.09us。啟動定時器后,從初始值0累加到65535再到溢出為0,總共累加了65536次。因此,最大定時長度為:1.09us*65536=71.4ms。
6.3定時器使用
前面介紹了51系列單片機中定時器的工作原理,這節(jié)將重介紹定時器的使用。前面介紹過單片機的某個功能的實現(xiàn)都有特殊功能寄存器SFR有關(guān),當(dāng)然定時器的使用也不例外,特殊功能寄存器列表如下表所示:
表6-1 定時器/計數(shù)器特殊功能寄存器列表
TCON是一個8位定時器/計數(shù)器中斷控制寄存器,可位尋址,即每一位可單獨賦值。B7、B6為定時器T1控制位,B5、B4為定時器T0控制位,如下表所示:
表6-2 TCON寄存器
TF0:定時器/計數(shù)器0中斷溢出標(biāo)志位。T1被允許計數(shù)后,從初始值開始加1計數(shù)。當(dāng)最高位產(chǎn)生溢出時由硬件置“1”TF0,向CPU請求中斷,一直保持到CPU響應(yīng)中斷時,才由硬件清零“0”TF0,另外,TF0也可由程序查詢清零“0”。
TF1:定時器/計數(shù)器1中斷溢出標(biāo)志位。功能與TF0類似。
TR0:定時器T0的運行控制位。該位由軟件置位和清零。當(dāng)TR0=1時就允許T0開始計數(shù)。
TR1:定時器T1的運行控制位。該位由軟件置位和清零。當(dāng)TR1=1時就允許T1開始計數(shù)。
其它位為外部中斷相關(guān)內(nèi)容,與定時器功能無關(guān),這里暫時不做介紹。
前面講的這幾個位是定時器中斷控制位,TR0賦值為1后,定時器T0開始運行,當(dāng)定時器T0溢出時,單片機硬件會將TF0位置1。我們可以在程序中通過查詢這個位是否為1來確定定時是否到達。另外,我們?nèi)绻O(shè)置了定時器中斷函數(shù),當(dāng)定時到達后,單片機程序會跳轉(zhuǎn)到定時器中斷函數(shù),并且由硬件將TF0清零。
TCON是一個可位尋址的寄存器,在單片機程序中可以直接對TCON賦值,或者對其中的位進行直接賦值。
圖6-7 定時器模式寄存器
TMOD為定時器模式寄存器,寄存器的高4位為定時器1模式位,低四位為定時器0模式位,高低位的功能類似,下面以定時器0為例:
C/T:定時器、計數(shù)器功能選擇位。清零作為定時器,置1作為計數(shù)器。
表6-3 模式選擇
定時器/計數(shù)器功能原理圖如下圖所示:
圖6-8 定時器/計數(shù)器功能原理圖
如上圖所示,當(dāng)作為定時器或計數(shù)器時唯一的區(qū)別為輸入的時鐘不一樣。當(dāng)作為定時器時,輸入的時鐘為系統(tǒng)時鐘,而當(dāng)作定時器時,系統(tǒng)輸入時鐘為外部引腳。
6.4定時器應(yīng)用實例
本節(jié)我們介紹定時器的兩種應(yīng)用實例進行介紹,第一種為程序查詢方式響應(yīng)定時器的溢出,第二種為中斷函數(shù)處理的方式響應(yīng)定時器溢出。應(yīng)用定時器實現(xiàn)的功能為每隔50ms使led0小燈閃爍一次,并使用定時器T0,工作在模式1,即16位定時的模式下。
6.4.1程序查詢方式實例
定時器使用步驟:
- 配置定時器模式控制寄存器TMOD;
- 裝載定時器初始值TH0,T0;
- 置位TR0,啟動定時器開始計時;
- 主程序查詢定時器中斷標(biāo)志位TF0。
假設(shè)設(shè)置定時器0為每1ms溢出1次,因此在主程序中累計查詢到50次便使led小燈閃爍一次。根據(jù)前面介紹的方法計算出定時器0初始值65536-FOSC/12 * 1 * 10-3,程序設(shè)計如下圖所示:
#include< reg52.h >
#define FOSC 11059200 //單片機晶振頻率
#define T_1ms (65536 - FOSC/12/1000) //定時器初始值計算
sbit led0 = P1^0;
unsigned char count = 0;
void main()
{
TMOD = 0x01; //定時器工作模式配置
TL0 = T_1ms; //裝載初始值
TH0 = T_1ms >>8;
TR0 = 1; //啟動定時器
while(1)
{
if(TF0==1)
{
TF0 = 0; //軟件清零
TL0 = T_1ms;//重裝初始值
TH0 = T_1ms >>8;
count++;
if(count >=50)// 每一毫秒進入一次中斷,達到50次則為50ms,翻轉(zhuǎn)小燈。
{
count = 0;
led0 = ~led0;
}
}
}
}
如上圖所示,在主程序開始階段,對TMOD進行賦值來配置定時器T0為工作模式1,然后對TL0,TH0寄存器進行初始化賦值,緊接著啟動定時器T0開始計數(shù)。完成上述步驟后,進入主程序循環(huán),在循環(huán)中不斷的檢測TF0,當(dāng)檢測到定時器溢出后將TF0清零,重新轉(zhuǎn)載定時器初始值,當(dāng)溢出達到50次后翻轉(zhuǎn)led小燈的值。這里需要注意的地方是,當(dāng)判斷到溢出后需要通過軟件對TF0進行軟件清零。結(jié)合我們前面學(xué)習(xí)的知識,大家可以根據(jù)自己的需求來改變程序的功能,加深對定時器功能的理解。
6.4.2中斷響應(yīng)方式實例
中斷響應(yīng)方式與程序查詢方式略有不同,在程序初始化處需要打開定時器中斷,當(dāng)定時器溢出后程序跳轉(zhuǎn)到中斷入口程序,并由硬件自動清理TF0,可在中斷程序中實現(xiàn)led小燈閃爍的功能。
定時器使用步驟:
- 配置定時器模式控制寄存器TMOD;
- 裝載定時器初始值TH0,T0;
- 置位TR0,啟動定時器開始計時;
- 允許定時器中斷,并開啟總中斷;
- 進入中斷程序。
- 在中斷程序中重載定時器初始值,并閃爍led小燈。
程序設(shè)計如下圖所示:
#include< reg52.h >
#define FOSC 11059200 //單片機晶振頻率
#define T_1ms (65536 - FOSC/12/1000) //定時器初始值計算
sbit led1 = P1^1;
unsigned char count = 0;
void main()
{
TMOD = 0x01; //定時器工作模式配置
TL0 = T_1ms; //裝載初始值
TH0 = T_1ms >>8;
TR0 = 1; //啟動定時器
ET0 = 1; //允許定時器中斷
EA = 1; //開總中斷
while(1); //循環(huán)
}
void timer0() interrupt 1
{
TL0 = T_1ms;//重裝初始值
TH0 = T_1ms >>8;
count++;
if(count >=50)// 每一毫秒進入一次中斷,達到50次則為50ms,翻轉(zhuǎn)小燈。
{
count = 0;
led1 = ~led1;
}
}
6.4本章小結(jié)
本章介紹了延時函數(shù)的調(diào)試,定時器基礎(chǔ)知識的介紹以及定時器功能的應(yīng)用實例。結(jié)合我們我們程序的介紹,多多練習(xí)下載試驗逐步的熟練掌握延時函數(shù)、定時器功能的應(yīng)用。
-
單片機
+關(guān)注
關(guān)注
6067文章
44982瀏覽量
650289 -
晶振
+關(guān)注
關(guān)注
35文章
3262瀏覽量
70094 -
定時器
+關(guān)注
關(guān)注
23文章
3298瀏覽量
118853 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5675瀏覽量
104562
發(fā)布評論請先 登錄
電機控制基礎(chǔ)知識1—定時器基礎(chǔ)知識與PWM輸出原理

定時器基礎(chǔ)知識與PWM輸出原理是什么
52單片機有幾個定時器?52單片機定時器1和52單片機定時器2程序?qū)Ρ?/a>
淺談定時器基礎(chǔ)知識與PWM輸出原理

51單片機——定時器的原理和使用

51單片機的定時器與計數(shù)器

51單片機定時器/計數(shù)器

電機控制基礎(chǔ)——定時器基礎(chǔ)知識與PWM輸出原理

評論