找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 8256|回復(fù): 8
收起左側(cè)

51單片機(jī)的定時(shí)器

[復(fù)制鏈接]
ID:51090 發(fā)表于 2014-10-15 22:46 | 顯示全部樓層 |閱讀模式
以前學(xué)了好幾次單片機(jī),都是半途而廢,這次要把基礎(chǔ)打好點(diǎn)才行。
話說定時(shí)器還是很重要的。。。

對(duì)51單片機(jī)來說,其實(shí)定時(shí)器和計(jì)數(shù)器是一樣的東西,下面把它們統(tǒng)稱為定時(shí)器了。

51單片機(jī)有兩個(gè)定時(shí)器,它們的核心是兩個(gè)16位的加1計(jì)數(shù)器T0和T1,它們又被分為兩個(gè)8位的計(jì)數(shù)器TH0,TL0,TH1,TL1。

當(dāng)作為計(jì)數(shù)器使用時(shí),計(jì)數(shù)脈沖來自外部引腳P3.4(T0)和P3.5(T1)。當(dāng)該腳的輸入信號(hào)發(fā)生由高到低的負(fù)跳變時(shí),讀數(shù)器TH、TL的值就加1。
定時(shí)器其實(shí)也是計(jì)數(shù),只不過計(jì)數(shù)的脈沖來源的內(nèi)部時(shí)鐘。

程序是怎樣知道定時(shí)器的時(shí)間到了呢?用中斷啦。。。
定時(shí)器使用的是加法計(jì)數(shù),而且只在計(jì)數(shù)溢出時(shí)才申請(qǐng)中斷,因此,要實(shí)現(xiàn)自定義定時(shí)或計(jì)數(shù),需要自己計(jì)算計(jì)數(shù)的起點(diǎn),并將它們填到TH、TL中。
也就是說,如果我要記1000個(gè)時(shí)鐘脈沖,我就將TH和TL的值設(shè)到距離最大值還差1000的位置。
假設(shè)計(jì)數(shù)的最大值是MAX(工作模式不同,這個(gè)值不同),則起點(diǎn)X的計(jì)算方法如下:
在計(jì)數(shù)方式下,X=MAX-計(jì)數(shù)值
在定時(shí)方式下,X=MAX-定時(shí)值/T,其中T為單片機(jī)的機(jī)器周期。如當(dāng)機(jī)器周期=0.5us時(shí),如果定時(shí)器工作于模式0,MAX = 2^13 * 0.5us = 4.096ms;如果工作于模式1,則最大定時(shí)值為MAX = 2 ^ 16 * 0.5us = 32.768ms。
在注意的是,在溢出后,除了模式2之外,程序都要重新裝入初值!

使用定時(shí)器的步驟:
1. 指定工作模式,即TMOD寄存器;
2. 裝入初始值,即對(duì)TH和TL賦值;
3. 啟動(dòng)定時(shí)器中斷,通過賦值IE和優(yōu)先級(jí)寄存器IP來實(shí)現(xiàn),如果不使用中斷,則忽略此步驟;
4. 啟動(dòng)定時(shí)器,即置位TR0或TR1。

模式0:
此模式為13位計(jì)數(shù)器,使用TH及TL中的低5位組成,此模式主要是為了向前兼容而設(shè)計(jì)的;在此模式下,當(dāng)TL的低5位溢出時(shí),向TH進(jìn)位,當(dāng)TH溢出時(shí),計(jì)數(shù)器清零,同時(shí)TF置1,另外發(fā)出中斷請(qǐng)求。
模式1:
此模式為16位計(jì)數(shù)器,使用TH和TL中的所有位,此模式方便計(jì)算初值,而模式0中要由TH和TL中的5位組成一個(gè)13位的數(shù),麻煩。
模式2:
此模式是8位自動(dòng)重新裝入的計(jì)數(shù)器,其中TH作為計(jì)數(shù)初值寄存器,初值在程序中設(shè)置,程序初始化時(shí),TL=TH,當(dāng)TL溢出時(shí),自動(dòng)設(shè)置TL=TH,重新計(jì)數(shù),TF標(biāo)志置1,TH中的數(shù)不受影響。溢出信號(hào)還將送到串行通信系統(tǒng),產(chǎn)生串口通訊的波特率。
模式3:
此模式是將TL和TH分成兩個(gè)獨(dú)立的計(jì)數(shù)器。T1沒有模式3,只有T0有模式3。如果T0工作在方式3下,那么T1就只能工作在0、1、2方式下,因?yàn)門R1及TF1已經(jīng)被T0借用。

可以通過TMOD和TCON兩個(gè)寄存器控制它們。

TMOD
---------------------------------------------------------
                   用于T1          |         用于T0              
---------------------------------------------------------
GATE | C/T  |  M1  |  M0  |  GATE  |  C/T  |  M1  |  M0 |

TCON
------------------------------------------------------------
     用于定時(shí)/讀數(shù)器        |          用于中斷
------------------------------------------------------------
TF1  | TR1  | TF0  |  TR0  |  IE1  |  IT1  |  IE0  |  IT0  |
------------------------------------------------------------

TF是溢出的標(biāo)志,TR是運(yùn)行控制位,當(dāng)置TR0=1時(shí),定時(shí)器1即啟動(dòng)。
IT是外部中斷觸發(fā)方式選擇位,0是低電平觸發(fā),1是負(fù)跳變觸發(fā)。
IE是外部中斷請(qǐng)求位。

定時(shí)/計(jì)數(shù)器有四種工作方式,TMOD中的M1和M0即為指定工作方式;
C/T決定是工作于定時(shí)還是計(jì)數(shù)方式;
GATE可控制定時(shí)器的啟動(dòng),當(dāng)GATE=0時(shí),定時(shí)器僅由TR控制,當(dāng)GATE=1時(shí),除TR置1外,還必須等待外部脈沖輸入端P3.4或P3.5有個(gè)高電平,定時(shí)器才能啟動(dòng)。若外部輸入低電平,則定時(shí)器關(guān)閉,這樣可由外部控制定時(shí)器的啟停。

初值計(jì)算舉例(以T0為例):
模式0, 6MHz的晶振,單片機(jī)的機(jī)器周期為12/6MHz=2us=0.002ms,如果要定時(shí)1ms,則有算式:1ms = (2^13-X)*0.002,解出X=7692=0x1E0C,轉(zhuǎn)化為2進(jìn)制為1111000001100,這里面低5位要放到TL中,即TL0=01100=0xC,其余放到TH中,即TH0=11110000=0xF0;
模式1, 12MHz的晶振,單片機(jī)的機(jī)器周期為12/12MHz=1us=0.001ms,如果要定時(shí)10ms,則有算式: 10ms=(2^16-X)*0.001,解出X=55536=0xD8F0,則TH0=0xD8,TL0=0xF0;
模式3, 6MHz的晶振,機(jī)器周期為2us=0.002ms,如果要定時(shí)200us,則有200=(2^8-X)*2,解出X = 156 = 0x9C, 則TL0 = 0x9C

程序舉例:
T0工作于方式1,定時(shí)時(shí)間50ms,輸出周期為1000ms的方波,晶振為11.0592MHz
機(jī)器周期為12/11.0592us,最大值為2^16=65536,X=0x4C00
程序如下:

#include "reg51.h"

sbit P0_1 = P0^1;
char i = 0;

void main()
{
    TMOD = 0x01; //T0方式1
    TL0  = 0x00; //TL0的初值
    TH0  = 0x4C; //TH0的初值
    ET0  = 1;    //打開定時(shí)器0的中斷允許開關(guān)
    EA   = 1;    //開中斷
    TF0  = 0;
    TR0  = 1;  
    while(1);
}

void Int_T0() interrupt 1 using 2
{
    TL0 = 0x00; //重新裝入初值
    TH0 = 0x4C;
i++;
if (i==10)
    {
P0_1 = !P0_1;
i = 0;
}
}

下面這段中斷的程序還須進(jìn)一步研究,呵呵

回復(fù)

使用道具 舉報(bào)

ID:67472 發(fā)表于 2014-10-16 11:50 來自手機(jī) | 顯示全部樓層
謝謝樓主
回復(fù)

使用道具 舉報(bào)

ID:67422 發(fā)表于 2014-10-16 20:28 | 顯示全部樓層
謝謝分享
回復(fù)

使用道具 舉報(bào)

ID:92169 發(fā)表于 2015-10-18 15:19 | 顯示全部樓層
其實(shí)你的中斷服務(wù)函數(shù)里面盡量不要那么多,只要留下i++;后面的可以寫在while里面
回復(fù)

使用道具 舉報(bào)

ID:92169 發(fā)表于 2015-10-18 15:20 | 顯示全部樓層
我也在學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:92785 發(fā)表于 2015-10-18 18:24 | 顯示全部樓層
謝謝樓主了!
回復(fù)

使用道具 舉報(bào)

ID:104763 發(fā)表于 2016-7-16 17:13 | 顯示全部樓層
樓主,關(guān)于定時(shí)器復(fù)用的有沒有
回復(fù)

使用道具 舉報(bào)

ID:120095 發(fā)表于 2016-7-17 15:42 | 顯示全部樓層
對(duì)于初學(xué)者非常的重要
回復(fù)

使用道具 舉報(bào)

ID:226737 發(fā)表于 2019-11-19 19:23 | 顯示全部樓層
謝謝你的分享!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表