標(biāo)題: 51單片機(jī)定時(shí)器的原理與使用(22頁(yè)詳細(xì)的word格式教程下載) [打印本頁(yè)]
作者: zixiaojsf 時(shí)間: 2018-5-9 10:08
標(biāo)題: 51單片機(jī)定時(shí)器的原理與使用(22頁(yè)詳細(xì)的word格式教程下載)
定時(shí)器是單片機(jī)的重要功能模塊之一,在檢測(cè)、控制領(lǐng)域有廣泛應(yīng)用。定時(shí)器常用作定時(shí)時(shí)鐘,以實(shí)現(xiàn)定時(shí)檢測(cè),定時(shí)響應(yīng)、定時(shí)控制,并且可以產(chǎn)生ms寬的脈沖信號(hào),驅(qū)動(dòng)步進(jìn)電機(jī)。定時(shí)和計(jì)數(shù)的最終功能都是通過(guò)計(jì)數(shù)實(shí)現(xiàn),若計(jì)數(shù)的事件源是周期固定的脈沖則可實(shí)現(xiàn)定時(shí)功能,否則只能實(shí)現(xiàn)計(jì)數(shù)功能。因此可以將定時(shí)和計(jì)數(shù)功能全由一個(gè)部件實(shí)現(xiàn)。通過(guò)下圖可以簡(jiǎn)單分析定時(shí)器的結(jié)構(gòu)與工作原理。
一、定時(shí)器
1、51單片機(jī)計(jì)數(shù)器的脈沖輸入腳。主要的脈沖輸入腳有Px,y, 也指對(duì)應(yīng)T0的P3.4和對(duì)應(yīng)T1的P3.5,主要用來(lái)檢測(cè)片外來(lái)的脈沖。而引腳18和19則對(duì)應(yīng)著晶振的輸入脈沖,脈沖的頻率和周期為
F = f/12 = 11.0592M/12 = 0.9216MHZ T = 1/F = 1.085us
2、定時(shí)器有兩種工作模式,分別為計(jì)數(shù)模式和定時(shí)模式。對(duì)Px,y的輸入脈沖進(jìn)行計(jì)數(shù)為計(jì)數(shù)模式。定時(shí)模式,則是對(duì)MCU的主時(shí)鐘經(jīng)過(guò)12分頻后計(jì)數(shù)。因?yàn)橹鲿r(shí)鐘是相對(duì)穩(wěn)定的,所以可以通過(guò)計(jì)數(shù)值推算出計(jì)數(shù)所經(jīng)過(guò)的時(shí)間。
3、51計(jì)數(shù)器的計(jì)數(shù)值存放于特殊功能寄存器中。T0(TL0-0x8A, TH0-0x8C), T1(TL1-0x8B, TH1-0x8D)
4、TLx與THx之間的搭配關(guān)系
1)、TLx與THx之間32進(jìn)制。即當(dāng)TLx計(jì)到32個(gè)脈沖時(shí),TLx歸0同時(shí)THx進(jìn)1。這也稱(chēng)為方式0。
2)、TLx與THx之間256進(jìn)制。即當(dāng)TLx計(jì)到256個(gè)脈沖時(shí),TLx歸0同時(shí)THx進(jìn)1。這也稱(chēng)為方式1。在方式1時(shí),最多計(jì)65536個(gè)脈沖產(chǎn)生溢出。在主頻為11.0592M時(shí),每計(jì)一個(gè)脈沖為1.085us,所以溢出一次的時(shí)間為1.085usx65536=71.1ms。
3)、THx用于存放TLx溢出后,TLx下次計(jì)數(shù)的起點(diǎn)。這也稱(chēng)為方式2。
4)、THx與TLx分別獨(dú)立對(duì)自己的輸入脈沖計(jì)數(shù)。這也稱(chēng)為方式3。
5、定時(shí)器初始化
1)、確定定時(shí)器的計(jì)數(shù)模式。
2)、確定TLx與THx之間的搭配關(guān)系。
3)、確定計(jì)數(shù)起點(diǎn)值。即TLx與THx的初值。
4)、是否開(kāi)始計(jì)數(shù)。TRx
(1)和(2)可以由工作方式寄存器TMOD來(lái)設(shè)定,TMOD用于設(shè)置定時(shí)/計(jì)數(shù)器的工作方式,低四位用于T0,高四位用于T1。其格式如下:
GATE:門(mén)控位,用于設(shè)置計(jì)數(shù)器計(jì)數(shù)與否,是否受P3.2或P3.3電壓狀態(tài)的影響。GATE=0時(shí),表示計(jì)數(shù)器計(jì)數(shù)與否與兩端口電壓狀態(tài)無(wú)關(guān);GATA=1時(shí),計(jì)數(shù)器是否計(jì)數(shù)要參考引腳的狀態(tài),即P3.2為高時(shí)T0才計(jì)數(shù),P3.3為高時(shí)T1才計(jì)數(shù)。
C/T:定時(shí)/計(jì)數(shù)模式選擇位。 =0為定時(shí)模式; =1為計(jì)數(shù)模式。
M1M0:工作方式設(shè)置位。定時(shí)/計(jì)數(shù)器有四種工作方式,由M1M0進(jìn)行設(shè)置。
6、計(jì)數(shù)器的溢出
計(jì)數(shù)器溢出后,THx與TLx都?xì)w0。并將特殊功能區(qū)中對(duì)應(yīng)的溢出標(biāo)志位TFx寫(xiě)為1。
好了,理論就講述到這。現(xiàn)在我們通過(guò)一些實(shí)驗(yàn)來(lái)看看怎么使用定時(shí)器。
實(shí)驗(yàn)一、P1口連接的8個(gè)LED燈以1秒鐘的頻率閃爍。
首先上代碼:
- #include "reg51.h"
- char c;
-
- void Timer0_Init() //初始化定時(shí)器
- {
- TMOD = 0x01; //
- TH0 = 0;
- TL0 = 0; //定時(shí)器的計(jì)數(shù)起點(diǎn)為0
- TR0 = 1; //啟動(dòng)定時(shí)器0
- }
-
- void main()
- {
- Timer0_Init();
- while(1)
- {
- if(TF0 == 1) //檢測(cè)定時(shí)器0是否溢出,每到65535次
- {
- TF0=0;
- c++;
- if(c==14) //71ms乘以14為1s
- {
- c=0;
- P1=~P1;
- }
- }
- }
- }
復(fù)制代碼
上述代碼的思路是每計(jì)算14個(gè)溢出,則翻轉(zhuǎn)P1口狀態(tài)。產(chǎn)生一個(gè)溢出的時(shí)間是71.1ms,14個(gè)則約為1s。
- #include "reg51.h"
- sbit LD1 = P1^0;
-
- void Timer0_Init() //初始化定時(shí)器
- {
- TMOD = 0x01; //
- TH0 = 0;
- TL0 = 0; //定時(shí)器的計(jì)數(shù)起點(diǎn)為0
- TR0 = 1; //啟動(dòng)定時(shí)器0
- }
-
- void Timer0_Overflow() //處理定時(shí)器0的溢出事件
- {
- static char c;
- if(TF0 == 1) //檢測(cè)定時(shí)器0是否溢出,每到65535次
- {
- TF0=0;
- c++;
- if(c==14) //71ms乘以14為1s
- {
- c=0;
- LD1=!LD1;
- }
- }
- }
-
- void main()
- {
- Timer0_Init(); //初始化定時(shí)器0
- while(1)
- {
- Timer0_Overflow();
- }
- }
復(fù)制代碼
相比于上個(gè)例子,這里有兩個(gè)區(qū)別,首先是將timer0的溢出事件作為子函數(shù)單獨(dú)出來(lái),其次是注意翻轉(zhuǎn)一個(gè)led燈時(shí)候用的是“!”。
例子三、讓連接到P1口的LED1和LED8燈每1秒鐘閃爍。
- #include "reg51.h"
-
- void Timer0_Init() //初始化定時(shí)器
-
- {
- TMOD |= 0x01; //定時(shí)器0方式1,計(jì)數(shù)與否不受P3.2的影響
- TH0 = 0;
- TL0 = 0; //定時(shí)器的計(jì)數(shù)起點(diǎn)為0
- TR0 = 1; //啟動(dòng)定時(shí)器0
- }
-
- void Timer0_Overflow() //´處理定時(shí)器0的溢出事件
- {
- static char c;
- if(TF0 == 1) //檢測(cè)定時(shí)器0是否溢出,每到65535次
- {
- TF0=0;
- c++;
- if(c==14) //71ms乘以14為1s
- {
- c=0;
- P1 ^= (1<<0);//LD1=!LD1;
- }
- }
- }
-
- void Timer1_Init()
- {
- TMOD|=0x10; //定時(shí)器1方式1,計(jì)數(shù)與否不受P3.3的影響
- TH1=0;
- TL1=0; //定時(shí)器1的計(jì)數(shù)起點(diǎn)為0
- TR1=1; //啟動(dòng)定時(shí)器1
- }
-
- void Timer1_Overflow() //處理定時(shí)器1的溢出事件
- {
- static char c;
- if(TF1==1) //軟件查詢(xún),主循環(huán)每跑完一圈才會(huì)到這里。
- {
- TF1=0;
- c++;
- if(c==14)
- {
- c=0;
- P1 ^= (1<<7);//LD8=!LD8;
- }
- }
- }
-
- void main()
- {
- Timer0_Init(); //初始化定時(shí)器0
- Timer1_Init(); //初始化定時(shí)器1
- while(1)
- {
- Timer0_Overflow();
- Timer1_Overflow();
- }
- }
復(fù)制代碼
相較于例二,例子三有幾個(gè)點(diǎn)值得注意:
1、TMOD初始化為什么采用TMOD |= 0x01或0x10的形式?
首先如果在定時(shí)器初始化函數(shù)中采用TMOD = 0x01和TMOD = 0x10,那么將造成LD1閃爍比LD8閃爍快8倍。分析一下,從main函數(shù)開(kāi)始執(zhí)行,先是初始化timer0,這時(shí)候定時(shí)器1設(shè)置為工作方式1。接著程序執(zhí)行到Timer1_Init(),這時(shí)候TMOD=00010000,即選定了timer1在工作方式1,但同時(shí)timer0重新配置為工作方式0, 也就是32進(jìn)制,所以產(chǎn)生快8倍現(xiàn)象。
那為什么用|這個(gè)符號(hào)就可以做到互不影響呢?|是或運(yùn)算符,即有1出1,全0出0。什么意思呢?舉個(gè)例子,a是11110000,b是10101010,那么a|b就是11111010。通過(guò)引入這個(gè)符號(hào),可以實(shí)現(xiàn)tmod對(duì)兩個(gè)定時(shí)器的獨(dú)立操作。
2、為什么使用P1 ^= (1<<0)可以實(shí)現(xiàn)LD1的控制呢?
首先解釋下^這個(gè)符號(hào)。^稱(chēng)為異或運(yùn)算符,相同出0,不同出1。舉個(gè)例子,a是11110000,b是10101010,那么a^b就是01011010。
然后再來(lái)分析 x ^= (1<<i), 假設(shè)x為10101010,當(dāng)i為1時(shí), (1<<i)為00000010,那么x^ (1<<i)=10101010^00000010=10101000。當(dāng)i為2時(shí),(1<<i)為00000100,那么x^ (1<<i)=10101010^00000100=10101110,以此類(lèi)推。我們發(fā)現(xiàn),x ^= (1<<i)是在將x的第i位翻轉(zhuǎn)而同時(shí)不影響其他位。
因此P1 ^= (1<<0)實(shí)際是在翻轉(zhuǎn)P0口第一位的值,因此也就是在閃爍LD1燈。
上面三個(gè)例子實(shí)際都是采用了軟件查詢(xún)法。即main函數(shù)會(huì)每次進(jìn)入到溢出事件函數(shù)里去判斷TF0或1是否等于1,這樣就浪費(fèi)了大量CPU時(shí)間。同時(shí),實(shí)時(shí)性差,假如在執(zhí)行Timer0_Overflow()的時(shí)候timer1也溢出了,這時(shí)候timer1的溢出事件就沒(méi)有及時(shí)處理。因此下面我們要引入中斷系統(tǒng)。
二、中斷系統(tǒng)
中斷系統(tǒng)是一套硬件電路,它可以在每個(gè)機(jī)器周期對(duì)所有的外設(shè)的標(biāo)志位作查詢(xún)。相比于前面的軟件查詢(xún)(if(xx==1)),中斷系統(tǒng)也可以叫做硬件查詢(xún)。51的中斷系統(tǒng)可查詢(xún)以下6個(gè)標(biāo)志位。
IE0(TCON.1),外部中斷0中斷請(qǐng)求標(biāo)志位。
IT1(TCON.2),外部中斷1觸發(fā)方式控制位。
IE1(TCON.3),外部中斷1中斷請(qǐng)求標(biāo)志位。
TF0(TCON.5),定時(shí)/計(jì)數(shù)器T0溢出中斷請(qǐng)求標(biāo)志位。
TF1(TCON.7),定時(shí)/計(jì)數(shù)器T1溢出中斷請(qǐng)求標(biāo)志位。
RI(SCON.0)或TI(SCON.1),串行口中斷請(qǐng)求標(biāo)志。當(dāng)串行口接收完一幀串行數(shù)據(jù)時(shí)置位RI或當(dāng)串行口發(fā)送完一幀串行數(shù)據(jù)時(shí)置位TI,向CPU申請(qǐng)中斷。
當(dāng)中斷系統(tǒng)查詢(xún)到外設(shè)的標(biāo)志位變?yōu)?時(shí),中斷系統(tǒng)可暫停當(dāng)前的主循環(huán),并且將程序跳轉(zhuǎn)到用戶(hù)預(yù)先指定的函數(shù)中執(zhí)行。要啟動(dòng)中斷系統(tǒng),必須先進(jìn)行中斷初始化,其流程如下:
a、是否要查詢(xún)外設(shè)標(biāo)志(EA=0或EA=1,EA 也叫 CPU中斷允許(總允許)位)
b、查詢(xún)到標(biāo)志1,是否要跳程序
c、跳轉(zhuǎn)的目標(biāo)函數(shù),即中斷服務(wù)子函數(shù)
所以在使用定時(shí)器中斷時(shí),我們只需要首先初始化中斷系統(tǒng),開(kāi)啟總中斷(相當(dāng)于總開(kāi)關(guān)),開(kāi)啟定時(shí)器對(duì)應(yīng)的控制位(相當(dāng)于支路開(kāi)關(guān)),再初始化定時(shí)器即可。中斷系統(tǒng)作為單片機(jī)的外設(shè),只有在某個(gè)中斷產(chǎn)生時(shí)才會(huì)打斷主循環(huán),并由相應(yīng)的中斷號(hào)引入到相應(yīng)的中斷服務(wù)子函數(shù)。下圖是6個(gè)中斷標(biāo)志位的信息。

實(shí)驗(yàn)四、使用中斷系統(tǒng)實(shí)現(xiàn)LD1燈每1秒鐘閃爍。
- #include "reg51.h"
-
- void Timer0_Init()
- {
- TMOD|=0x01;
- TH0=56320/256; //計(jì)數(shù)起點(diǎn)為56320 ==10ms溢出一次
- TL0=56320%256;
- TR0=1;
- }
-
- void Timer1_Init()
- {
-
- }
-
- void ISR_Init() //初始化中斷系統(tǒng)
- {
- EA=1; //啟動(dòng)中斷系統(tǒng)
- EX0=0; //-->IE0
- ET0=1; //-->TF0 控制位置1,表明當(dāng)TF0置1時(shí),中斷系統(tǒng)將介入
- EX1=0; //-->IE1
- ET1=0; //-->TF1
- ES=0; //-->RI,TI
-
- }
-
- //以下中斷服務(wù)子程序,我們希望中斷系統(tǒng)來(lái)調(diào)用,而不是我們?cè)趍ain函數(shù)里面調(diào)用,因此使用interrupt. */
-
- void IE0_isr() interrupt 0
- {
-
- }
-
- /*void TF0_isr() interrupt 1 //71.1ms 進(jìn)入一次,但如果要求10MS進(jìn)來(lái)一次呢?
- {
- static char c;
- c++;
- if(c==14)
- {
- P1^=(1<<0);
- c=0;
- }
- }
- */
- void TF0_isr() interrupt 1 //10ms 進(jìn)入一次
- {
- static char c;
- TH0=56320/256; //重裝初值
- TL0=56320%256;
- c++;
- if(c==100)
- {
- P1^=(1<<0);
- c=0;
- }
- }
-
- void IE1_isr() interrupt 2
- {
-
- }
-
- void TF1_isr() interrupt 3
- {
-
- }
-
- void RI_TI_isr() interrupt 4
- {
-
- }
-
- void main()
- {
- Timer0_Init();
- Timer1_Init();
- ISR_Init();
-
- while(1)
- {
- //...
- //發(fā)現(xiàn)溢出后,中斷系統(tǒng)根據(jù)中斷號(hào)尋找中斷子服務(wù)函數(shù),并強(qiáng)行暫停主循環(huán)并進(jìn)入子函數(shù)
- //...
- }
- }
復(fù)制代碼
顯然使用中斷系統(tǒng)查詢(xún)得到的1s更為精確。因?yàn)橹袛嘞到y(tǒng)獨(dú)立于main函數(shù)運(yùn)行。另外本程序還預(yù)裝了timer0的初值,這樣的話就可以實(shí)現(xiàn)比71ms更小的時(shí)間片,比如要求10ms就進(jìn)入中斷。關(guān)于初值的設(shè)定,請(qǐng)參考下圖。
實(shí)驗(yàn)五、用定時(shí)器實(shí)現(xiàn)數(shù)碼管顯示1234。
- //數(shù)碼管的定時(shí)掃描,每5ms顯示一個(gè)數(shù)碼管,也就是說(shuō)相同的數(shù)碼管,每20ms會(huì)被重新裝入同樣的數(shù)值,根據(jù)人眼的延遲效應(yīng),人眼觀測(cè)到的數(shù)碼管上的數(shù)值是靜態(tài)的。
- #include "reg51.h"
- unsigned int count;
- extern void load_smg();
- void Timer0_Init()
- {
- TMOD|=0X01;
- TH0=60928/256;
- TL0=60928%256;//每5ms進(jìn)入一次中斷
- TR0=1;
- }
-
- void isr_Init()
- {
- EA=1;
- ET0=1; //TF0 如果這個(gè)標(biāo)志為1,進(jìn)入中斷子函數(shù)
- }
-
- void TF0_isr() interrupt 1
- {
- TH0=60928/256;
- TL0=60928%256;//重裝初值
- load_smg();
- }
-
- void main()
- {
- Timer0_Init();
- isr_Init();
- while(1)
- {
-
- }
-
- }
-
- #include "reg51.h"
- //char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};
- code char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};
- char smgbuf[4]={1,2,3,4}; //從RAM的smgbuf這個(gè)地址開(kāi)始連續(xù)存放4個(gè)數(shù),并且每個(gè)數(shù)占一個(gè)單元。
- extern unsigned int count; //外部申明,表示并不在這里申明
-
- void fill_smgbuf() //向LED緩沖區(qū)填充數(shù)據(jù)
- {
- smgbuf[0]=count/1000; //千位
- smgbuf[1]=(count%1000)/100; //百位
- smgbuf[2]=((count%1000)%100)/10; //十位
- smgbuf[3]=((count%1000)%100)%10; //個(gè)位
- }
-
- void load_smg() //將數(shù)碼管顯示緩沖區(qū)的數(shù)據(jù),顯示到數(shù)碼管上
- {
- static char i;
- fill_smgbuf();
- i++;
- if(i>=4)
- {
- i=0;
- }
- P0=0xFF; //消除上一個(gè)循環(huán)的影子
- P2 = ~(1<<i);
- P0 = seg[smgbuf[i]];
- }
復(fù)制代碼
實(shí)驗(yàn)六、實(shí)現(xiàn)按鈕控制數(shù)碼管上的數(shù)值加1或減1,并且當(dāng)按住按鈕不放時(shí),能實(shí)現(xiàn)快速的增減。
這里的關(guān)鍵點(diǎn)在于如何實(shí)現(xiàn)快速增減,具體請(qǐng)?jiān)敿?xì)分析代碼。代碼鏈接點(diǎn)擊打開(kāi)鏈接
https://zhidao.baidu.com/question/561457023576622684.html
單片機(jī)中TCON和TMOD寄存器,無(wú)論是匯編程序還是C語(yǔ)言程序,都可以直接賦值。具體賦值多少,根據(jù)以上兩寄存器各位具體功能確定。




https://blog.csdn.net/zn2016/article/details/53353818
51定時(shí)器使用2016年11月26日 18:56:03
閱讀數(shù):1020
1.設(shè)置特殊功能寄存器TMOD,配置好工作模式。
TMOD中M0/M1的配置決定定時(shí)器(0或1)的工作模式。
M1 = 0,M0 = 0,工作模式0,由THn的8位和TLn的5位組成一個(gè)13位的定時(shí)器。
M1 = 0,M0 = 1,工作模式1,由THn和TLn組成1個(gè)16位的定時(shí)器。
M1 = 1,M0 = 0,工作模式2,8位自動(dòng)重裝模式,定時(shí)器溢出后由THn重裝的TLn中。
M1 = 1,M0 = 1,工作模式3,禁用定時(shí)器1,定時(shí)器0變成兩個(gè)8位的定時(shí)器。
2.設(shè)置計(jì)數(shù)寄存器TH0,TL0的初值。
3.設(shè)置TCON,通過(guò)TR0置1,來(lái)讓定時(shí)器開(kāi)始計(jì)數(shù)。
4.判斷TCON寄存器的TF0位,檢測(cè)定時(shí)器是否溢出。
注意:定時(shí)器計(jì)數(shù)溢出后,TF0會(huì)置位,如果沒(méi)有開(kāi)定時(shí)器中斷則需要軟件清零TF0位。如果開(kāi)定時(shí)器中斷則TF0位由硬件清理。謹(jǐn)記:定時(shí)器溢出后給TH0,TL0 重裝載值。
定時(shí)器在每一個(gè)機(jī)器周期計(jì)數(shù)向上加1。
完整的Word格式文檔51黑下載地址:
51單片機(jī)定時(shí)器的原理與使用.docx
(1.34 MB, 下載次數(shù): 52)
2018-5-9 10:07 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者: lyseg 時(shí)間: 2019-3-30 17:16
xiexie!!!
歡迎光臨 (http://www.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
国产黄色小视频
|
久久精彩
|
国产精品久久久乱弄
|
欧美aaa一级片
|
国产伦精品一区二区三区照片91
|
成人字幕网zmw
|
国产农村一级片
|
亚洲国产精品视频
|
国产中文字幕亚洲
|
亚洲综合精品
|
欧美韩一区二区三区
|
午夜视频免费在线观看
|
剑来高清在线观看
|
亚洲视频中文字幕
|
欧美一区二区三区四区在线
|
亚洲成人免费视频
|
www.日韩高清
|
av在线一区二区三区
|
国产欧美精品一区
|
一区二区三区在线
|
久草视
|
国产精品永久在线观看
|
亚洲成人免费
|
国产99热|
欧美一级免费看
|
亚洲成人av在线
|
91福利在线导航
|
久久一二
|
国产在线小视频
|
精品一区二区三区四区外站
|
91麻豆精品国产91久久久更新资源速度超快
|
精品日韩在线
|
国产91久久精品一区二区
|
91精品观看
|
亚洲人成人一区二区在线观看
|
国产伦精品一区二区
|
国产日韩视频在线
|
九九热国产视频
|
www.jizzjizz|
亚洲高清视频一区二区
|
www.xxxx欧美|