單片機的定時器


轉載於:https://blog.csdn.net/tabactivity/article/details/99649928?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

TMOD:定時器/計數器模式控制寄存器TMOD是一個逐位定義的8位寄存器,但只能使用字節尋址,其字節地址為89H。

D7

D6

D5

D4

D3

D2

D1

D0

GATE

C/T

M1

M0

GATE

C/T

M1

M0

D0~D3為T0定時/計數器的設置,D4~D7為T1定時/計數器的設置 。

GATE  :為門控位,GATE=0時,只要在編寫程序時,使TCON中的TRO或TR1為1,就可以啟動定時器/計數器工作。

                                 GATE=1時,不僅要在編寫程序時,使TCON中的TRO或TR1為1,且需要外部引腳也為高電平,才能工作。

C/T    :定時/計數模式切換,C/T=0時為定時模式,C/T=1時為計數模式。

M1,M0:用來選擇定時計/計數器的工作方式,一般使用都是采用16位的計時計數器。

M1

M0

工作模式

說明

0

0

0

13位計時計數器 (8192)

0

1

1

16位計時計數器 (65536)

1

0

2

8位計時計數器,可自動重新載入計數值 (256)

1

1

3

當成兩組獨立的8位計時器(256,T0和T1不能同時用)

 

TCON:控制寄存器,作用是控制定時器的啟、停,標志定時器溢出和中斷情況。

D7

D6

D5

D4

D3

D2

D1

D0

TF1

TR1

TF0

TR0

IE1

IT1

IE0

IT0

TF1  :TF1=1表示T1有中斷產生。(Timer Flag,定時器標志位)

TR1  :TR1=1表示T1開始運行。(單片機中T0引腳,需要高低電平的驅動)

TF0  :TF0=1表示T0有中斷產生。

TR0  :TR0=1表示T0開始運行。(單片機中T1引腳,需要高低電平的驅動)

IE1   :IE1=1表示INT1有中斷產生。

IT1   :IT1=1表示INT1為下降沿觸發,IT1=0表示INT1為低電平觸發。

IE0   :IE0=1表示INT0有中斷產生。

IT0   :IT0=1表示INT0為下降沿(負跳變)觸發,IT0=0表示INT0為低電平觸發。

中斷允許寄存器  IE (A8H)

D7

D6

D5

D4

D3

D2

D1

D0

EA

ET2

ES

ET1

EX1

ET0

EX0

EA    :整體中斷允許位;EA=1允許中斷。

ET2   :T2中斷允許位;ET2=1允許中斷(S52才有)。

ES    :串行中斷允許位;ES=1允許中斷。

ET1   :T1中斷允許位;ET1=1允許中斷。

EX1   :INT1中斷允許位;EX1=1允許中斷。

ET0   :T0中斷允許位;ET0=1允許中斷。

EX0   :INT0中斷允許位;EX0=1允許中斷。

 

在程序中,通過設訂兩個8位寄存器中TH與TL的值,來決定定時值和計數值。TH與TL的計算過程如下:

假設定時器的時間常數為X,定時器的位數為N
定時時間T=(2的N次方-X)12/單片機晶振頻率   (例如11.0592MHZ的振盪器頻率F=1/11.0592)
N為定時器的工作方式(關於定時/計數器的4中工作方式,以下會有具體介紹):

 方式0時,N=13(此為TH為8位,TL為5位)
 方式1時,N=16(此為TH為8位,TL為8位)
 方式2時,N=8(此為TH為8位,TL為0位)

方式3時,N=8(此為TH為8位,TL為8位,只適用於T0,且T0被分成兩個獨立的8位計數器TH與TL)


根據定時時間和工作方式,通過公式:定時時間T=(2的N次方-X)12/單片機晶振頻率,計算出時間常數X
把X轉換成二進制數,高8位送給TH1,低8位送給TL1,就可以啟動定時器開始定時了。

定時器的3種工作方式圖解:

工作方式0:

工作方式1:

工作方式2:

工作方式3:

總結定時器的操作步驟如下:

1.選擇工作方式(設置M0,M1的值) 

2.選擇控制方式GATE(為0是只要軟件設定好參數即可,為1則需要軟件設定參數,且定時器/計數器的中斷引腳需要為高電平)

3.確定定時器的工作模式,是定時模式還是計數模式 C/T.

4.給定時器設初值(設置THX與TLX)

5.開啟定時器中斷(設置ET0或ET1)

6.開啟總中斷(設置EA的值)

7.定時器/計數器的選擇T0/T1(設置TR1或TR0的值)

例:設置一個LED燈每500ms的評率閃爍

 
#include<reg52.h>
 
 
 
sbit led = P1^0;
 
int i = 0;
 
 
 
void timer1_init()
 
{
 
TMOD = 0x10; //定時器0選擇工作方式1
 
TH1 = 0x4C;    //設置初始值,定時50ms
 
TL1 = 0x00;
 
EA = 1;    //打開總中斷
 
ET1 = 1;    //打開定時器0中斷
 
TR1 = 1;    //啟動定時器0
 
}
 
 
 
void main()
 
{
 
led = 1;
 
timer1_init();//定時器1的初始化
 
while(1)
 
{
 
if(i==10)
 
{
 
led = ~led;
 
i = 0; //注意i需要零
 
}
 
}
 
}
 
 
 
void timer1() interrupt 3
 
{
 
TH1 = 0x4C;    //設置初始值,定時50ms
 
TL1 = 0x00;
 
i++;
 
}

 

 

c51單片機中斷程序中的interrupt1,2,3是由什么決定的?

interruput X 語句 X是中斷標號 計算公式是 :(地址-3)/8=中斷標號,其中“地址”*/
指的是 中斷服務程序 的入口地址,比如:
外部中斷0,入口地址為0003H,對應的中斷標號為0
外部中斷1,入口地址為0013H(十進制為19),對應中斷標號為2
定時器0中斷,入口地址為000BH(十進制為11),對應中斷標號為1
定時器1中斷,入口地址為001BH(十進制為27),對應標號為3
串口中斷,入口地址為0023H(十進制為35),對應中斷標號4
入口地址在數據手冊里有

https://zhidao.baidu.com/question/365087067.html

 

由TL0的低5位(高3位未用)和TH0的8位組成。TL0的低5位溢出時向TH0進位,TH0溢出時,置位TCON中的TF0標志,向CPU發出中斷請求。由TL0的低5位(高3位未用)和TH0的8位組成。TL0的低5位出時向TH0進位,TH0溢出時,置位TCON中的TF0標志,向CPU發出中斷請求。,由TL0的低5位(高3位未用)和TH0的8位組成。TL0的低5位溢出時向TH0進位,TH0溢出時,置位TCON中的TF0 

 

http://www.21ic.com/jichuzhishi/mcu/timer/2018-04-23/758372.html

 

6.STC89C52RC單片機定時器示例代碼2:

問:在中斷函數里為什么要重新賦初值呢?TH0 = XX,TL0 =XX?

因為進入中斷,其值減為0,如果不重裝初值,下次計數值就是65535,而不TH0 << 8 | TL0 ,比如上圖中的922.

https://zhidao.baidu.com/question/178452295.html

----------------------------------------------------

TH0 ,TL0怎么算:

比如計時10毫秒,10ms= 10000ms  / 1.085 (機器周期)= 9216 次,意思就是當機器運行9216次 就為10ms

65535 (16位最大計數值) - 9216 = 56319 ,換成 16進制=0xDBFF ,分別賦值給TH0=0xDB, TL0 =0xFF

----------------------------------------------------

機器周期怎么算?

51單片機而言,一個機器周期等於12個晶振的周期。公式就是:12/fsoc

12/11.0592 =1.085(約等於)   , 11.0592是晶振頻率

----------------------------------------------------

波特率=(2SMOD / 32) * T1溢出率

溢出速率=(計數速率)/(256-TH1初值)
溢出速率=fosc/[12*(256-TH1初值)]

11.0592M
9600=(2÷32)×((11.0592M/12)/(256-TH1))

9600 = 0.0625 * (11059200/ 12)/(256-TH1))

9600 = 57600/(256-TH1))

(256-TH1)) = 57600/9600

(256-TH1))  = 6

TH1  = 256- 6

TH1=250

----------------------------------------------------

以下轉自:https://blog.csdn.net/lile777/article/details/45719283?utm_source=blogxgwz3

當SMOD=1時,K=2,波特率加倍,公式為:
                   波特率=K×11059200/32×12×(256-TH1)
所以,TH1=0xfa=256-(2×11059200/384×波特率) 其中波特率為9600
這時,及時令TH1=0xff,所得波特率最大只能為57600,也就是說,這樣無法得到115200的波特率。。。



這樣就只有采用其他方法了:
1、換晶振,用22.1184M晶振,在TH1=0xff時,剛好可以產生115200波特率。
2、采用6個時鍾周期的單片機(換單片機啊。。。)
3、增強型51單片機有定時器2!(幸好偶用的是增強型。。。)

就用第三種方法啦!這時的波特率公式如下:
               波特率=11059200 / { 32×[65536-(RCAP2H,RCAP2L)] }    
其中的RCAP2H,RCAP2L為自動重裝值,由上式得:
               RCAP2H,RCAP2L=65536-11059200 / (32×波特率) 
這樣得波特率為115200時,RCAP2H,RCAP2L=0xff,0xfd,初始化程序如下:



void init_com( void ) 
{ 
     SCON=0x50; //串口工作方式1,8位UART,波特率可變  
     TH2=0xFF;           
     TL2=0xFD;    //波特率:115200 晶振=11.0592MHz 
     RCAP2H=0xFF;   
     RCAP2L=0xFD; //16位自動再裝入值



/*****************/
     TCLK=1;   
     RCLK=1;   
     C_T2=0;   
     EXEN2=0; //波特率發生器工作方式



/*****************/
    TR2=1 ; //定時器2開始
}



OK!
這樣就實現用51單片機+11.0592的晶振,產生115200的波特率了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM