单片机定时器总结
最近在學(xué)習(xí)郭天祥老師的單片機(jī)教程,遇到很多問(wèn)題,期間看了很多博客,終于對(duì)單片機(jī)的定時(shí)器有些了解,在此像CSDN優(yōu)秀的博主表示感謝,由于這是我第一次寫(xiě)博客(研究?jī)?nèi)容很淺)為了以后復(fù)習(xí)方便以及希望各位優(yōu)秀的童鞋幫我指正錯(cuò)誤哈哈
最后再?gòu)U話一句,本人學(xué)的很菜,不懂得東西太多了,寫(xiě)的也肯定,,,,所以不喜勿噴喲,,,,
言歸正傳:
定時(shí)器/計(jì)數(shù)器:顧名思義既能定時(shí)又能計(jì)數(shù)。它存在于單片機(jī)內(nèi)部的一個(gè)獨(dú)立硬件部分,依賴晶振產(chǎn)生固定的時(shí)間間隔,產(chǎn)生一定的時(shí)間間隔后會(huì)引起定時(shí)器中斷,從而產(chǎn)生的時(shí)間信息傳送給主程序。
51單片機(jī)有2個(gè)定時(shí)器,分別是T0和T1,52單片機(jī)比51單片機(jī)多了一個(gè)T2定時(shí)器,但51和52的定時(shí)器設(shè)置差不多。
首先解釋一下常規(guī)概念:
周期:周期是物體循環(huán)一周的時(shí)間
頻率:1秒鐘內(nèi)循環(huán)的次數(shù)
(補(bǔ)充下:單片機(jī)是靠脈沖來(lái)工作的,一個(gè)脈沖產(chǎn)生一個(gè)操作)
單片機(jī)中包括四個(gè)周期:分別是時(shí)鐘周期、機(jī)器周期、指令周期、狀態(tài)周期
時(shí)鐘周期:也叫振蕩周期,定義為時(shí)鐘脈沖(晶振頻率)的倒數(shù)
即產(chǎn)生一個(gè)脈沖的時(shí)間。例如12M晶振,時(shí)鐘周期是1/12us
機(jī)器周期:單片機(jī)訪問(wèn)一次存儲(chǔ)器的時(shí)間,稱為一個(gè)機(jī)器周期。以51單片機(jī)為例,它有固定的機(jī)器周期,一個(gè)機(jī)器周期包含六個(gè)狀態(tài)例如,取指令、存儲(chǔ)器讀、存儲(chǔ)器寫(xiě)等。即機(jī)器周期等于6個(gè)狀態(tài)周期,而一個(gè)狀態(tài)周期是2個(gè)時(shí)鐘周期,因此一個(gè)機(jī)器周期又等于12個(gè)時(shí)鐘周期。單片機(jī)的晶振最常用的是12MHZ,11.0592MHZ,當(dāng)晶振是12MHZ時(shí):時(shí)鐘周期是1/12us,機(jī)器周期是12*(1/12us)=1us,產(chǎn)生一次機(jī)器周期的時(shí)間是1us,也就是向寄存器每傳入1個(gè)數(shù),機(jī)器周期的時(shí)間是1us. 11.0592MHZ的晶振同理。
定時(shí)器的應(yīng)用舉例(數(shù)碼管1、3、5個(gè)亮,時(shí)間間隔是1s,以12M的晶振為例,本程序只涉及定時(shí)器T0,16位)
設(shè)計(jì)思路:以12Mhz的晶振來(lái)說(shuō),機(jī)器周期是1us,計(jì)滿TH0、TL0就需要2^16-1個(gè)數(shù),再來(lái)一個(gè)數(shù)就“溢出”產(chǎn)生中斷,一次溢出也就是65536us,約等于65.5ms,所以定時(shí)時(shí)間1s超出范圍,因此需要進(jìn)入中斷20次,每次中斷50ms。
初始化程序需要完成以下工作:
1. 對(duì)TMOD賦值,以確定T0和T1的工作方式
本文只涉及T0,所以令T1定時(shí)器端口全為0,對(duì)于T0定時(shí)器:門控位GATE=0,C/T=0(定時(shí)器模式) ,M1M0=01(方式一為16位定時(shí)計(jì)數(shù)器)。所以TOMD=0x01
2. 計(jì)算初值,并將其寫(xiě)入TH0、TL0和TH1、TL1
假設(shè)單片機(jī)的晶振的頻率是12MHZ,那么一個(gè)機(jī)器周期的時(shí)間就是1us,計(jì)滿TH0、TL0就需要2的16次方-1個(gè)數(shù),再來(lái)一個(gè)數(shù)就“溢出”產(chǎn)生中斷,一次溢出也就是65536us,約等于65.5ms,因此如果我們要定時(shí)65.5ms的話,就可以這樣做,但是定的時(shí)間如果不是65.5ms的話,則需要裝入定時(shí)器中一個(gè)初值。假設(shè)我們要計(jì)數(shù)的個(gè)數(shù)是N個(gè),設(shè)裝入的初值是X,則X=2^16-N,比如要裝50000個(gè)數(shù)的話,初值X=65536-50000=15536,然后把15536對(duì)256取模15536/256=60裝入TH0中,15536%256=176裝入TL0中。因?yàn)閷?shí)驗(yàn)板上的晶振是11.0592MHZ,可知機(jī)器周期=1.09us,比如說(shuō)我們要定時(shí)50ms(50000us)那么計(jì)數(shù)的個(gè)數(shù)是N=50000/1.09=45872,再計(jì)算初始值X=65536-45872=19664,,再分別計(jì)算TH0和TL0中具體裝多少就可以了。(本文是以12M晶振為例)
3. 中斷發(fā)生時(shí),則對(duì)IE賦值,開(kāi)放中斷
圖為中斷允許控制位
開(kāi)總中斷EA=0;
外部中斷允許控制位EX0=1,允許外部中斷0中斷
4. 使TR0和TR1置位,啟動(dòng)定時(shí)/計(jì)數(shù)定時(shí)器定時(shí)或計(jì)數(shù)
TR0=1,啟動(dòng)定時(shí)/計(jì)數(shù)器定時(shí)或者計(jì)數(shù)
完整代碼
下面展示一些 內(nèi)聯(lián)代碼片。
/* 將定時(shí)器0設(shè)置為1s,進(jìn)入中斷一共20次,每次進(jìn)入中斷50ms現(xiàn)象:1/3/5數(shù)碼管顯示從0到F靜態(tài)*/#include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit dula=P2^6; sbit wela=P2^7; uchar num,tt; uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 }; void main(){ num=0;tt=0;TMOD=0x01;//設(shè)置定時(shí)器0位工作方式1 ,由于TMOD的字節(jié)地址是89H,不能被8整除,所以不能位尋址sbt=?TH0=(65536-50000)/256; //計(jì)算初值:高8位TL0=(65536-50000)%256; //計(jì)算初值:低8位EA=1;//開(kāi)總中斷ET0=1;//開(kāi)定時(shí)器0中斷TR0=1;//啟動(dòng)定時(shí)器0 開(kāi)始定時(shí),計(jì)50ms時(shí)馬上進(jìn)入中斷子程序wela=1;P0=0xEA; //第1、3、5個(gè)數(shù)碼管全是0;最高位和次高位全是1,低電平有效 1、、3、、5亮wela=0;//27、28、29三句是打開(kāi)位選信號(hào)dula=1;//開(kāi)段選P0=0x3f;//開(kāi)始數(shù)碼管顯示0dula=0;//關(guān)段選while(1){if(tt==4)//只有進(jìn)入中斷20次,(每進(jìn)去一次中斷時(shí)間為50ms)才有可能tt=20{tt=0;num++;//依次加一if(num==16)num=0;dula=1;P0=table[num];dula=0;} } } void exter0() interrupt 1 //當(dāng)設(shè)置的初值加滿才進(jìn)去中斷 {TH0=(65536-50000)/256; //計(jì)算初值:高8位TL0=(65536-50000)%256; //計(jì)算初值:低8位;tt++; //計(jì)數(shù) }下面是我參考的一些博客,希望對(duì)大家有所幫助
http://bbs.elecfans.com/jishu_178566_1_1.html
https://blog.csdn.net/weixin_42119585/article/details/103587848
這是我的第一篇博客,寫(xiě)的不好大家多多指導(dǎo),大家一起加油
總結(jié)
- 上一篇: opencv+python图像识别,麻将
- 下一篇: ASW3410设计说明|双通道 2切1/