定時器的原理與應用
定時器/計數器的方式和控制寄存器
~方式寄存器TMOD
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
定時器1 | 定時器0 |
---|
M1、M0爲工作選擇位,用於對T0的4種工作方式,T1的3種工作方式(前三種)進行選擇,選擇情況如下
M1 | M0 | 工作方式 | 方式說明 |
---|---|---|---|
0 | 0 | 0 | 13位定時/計數器 |
0 | 1 | 1 | 16位定時/計數器 |
1 | 0 | 2 | 8位自動重置定時/計數器 |
1 | 1 | 3 | l兩個8位定時/計數器(只有T0有) |
C/T:定時或計數器選擇位
- C/T=1:計數器方式
- C/T=0:定時方式
GATE:門控位。(一般給0)用於控制定時/計數器的啓動是否受外部中斷請求信號的影響
- GATE=0: 僅由TR0,TR1置位分別啓動定時器T0、T1
- GATE=1:由外部中斷引腳INT0、INT1來啓動定時器T0、T1
~控制寄存器TCOM
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
TF0(TF1):計數溢出標誌位,當計數器計數溢出時,該位置1。
TR0(TR1):定時器運行控制位
- TR0(TR1)=0 停止定時器/計數器工作
- TR0(TR1)=1 啓動定時器/計數器工作
IE0(IE1):外部中斷0(或1)的請求標誌位
- 當CPU採樣到P3.2(P3.3)出現有效中斷請求時,此位由硬件置1。在中斷響應完成後轉向中斷服務時,再由硬件自動清0。
IT0(IT1):外中斷請求信號方式控制位
- IT0(IT1)=1 脈衝方式(後沿負跳有效)
- IT0(IT1)=0 電平方式(低電平有效)此位由軟件置1或清0。
定時器/計數器的工作方式
開始先來介紹一下初值有什麼用?——初值就是爲了設置定時時間或次數
方式0——13位定時/計數器方式
- 計數值N和初值X的關係: X=8192-N/(12/fosc)
- 初值定義:
- 定時/計數器0:TH0(高八位),TL0(低八位)
- 定時/計數器1:TH1(高八位),TL1(低八位)
- 上次計數完,計數器爲0,要重複計數需重置初值
方式1——16位定時/計數器方式
- 計數值N和初值X關係:X=65536-N/(12/fosc)
- 上次計數完,計數器爲0,要重複計數需重置初值
方式2——8位自動重置定時/計數器(下同)
方式3——8位定時/計數器(只有配置T0才能使用)
- 計數值N和初值X的關係:X=256-N/(12/fosc)
- 上次計數完,計數器自動重置初值。不需要用戶重置
注意:
- fosc爲晶振頻率,51單片機一般爲12MHz或者11.0592MHz
- 單片機的單位:μs
代碼部分
實現效果
- 通過定時器0中斷實現數碼管1s循環變化
定時器0中斷需要初始化參數
- TMOD
- TH0
- TL0
- ET0
- EA
- TR0
電路圖展示
代碼
#include"reg51.h"
unsigned char count=0,num=0;
unsigned char str[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//數碼顯示數字
void inittimer()
{
TMOD=0x01;//0000 0001 定時器0 方式1-16位定時器
TH0=(65536-50000)/256;//定時50ms 取高八位,因此除以256=2^8,相當於初值》8位
TL0=(65536-50000)%256; //取低八位,因此求餘256
ET0=1;//開啓定時器0中斷
EA=1;//開啓總中斷
TR0=1;//開啓定時0
}
void display()
{
P2=str[count];
if(count==10)
{
count=0;
}
}
void main()
{
inittimer();//初始化定時器
while(1)
{
display();//數碼管顯示
}
}
//定時器中斷服務函數
void timer_isr() interrupt 1//0表示外部中斷0,1表示定時器中斷0,2表示外部中斷1,3表示定時器中斷1,4表示串口中斷
{
TH0=(65536-50000)/256;//重新賦初值
TL0=(65536-50000)%256;
num++;
if(num==20)//50ms*20=1s
{
count++;//中斷中要做的事
num=0;
}
}