1.定時(shí)器介紹
1.1、什么是定時(shí)器
(1)Soc(單片機(jī))的一種內(nèi)部外設(shè)
(2)定時(shí)器就是CPU的“鬧鐘”
1.2、什么是計(jì)數(shù)器
(1)定時(shí)器就是用計(jì)數(shù)的原始實(shí)現(xiàn)的
(2)計(jì)數(shù)器可以計(jì)算外部脈沖個(gè)數(shù)
1.3、定時(shí)器如何工作
(1)第1步:先設(shè)置好定時(shí)器的時(shí)鐘源(如果需要的話)
(2)第2步:初始化時(shí)鐘相關(guān)寄存器
(3)第3步:設(shè)置定時(shí)時(shí)間(計(jì)數(shù)個(gè)數(shù))
(4)第4步:設(shè)置中斷處理程序
(5)第5步:打開定時(shí)器
(6)運(yùn)行時(shí):定時(shí)器計(jì)數(shù)到后產(chǎn)生中斷,然后執(zhí)行中斷isr。
2.軟件控制硬件的關(guān)鍵——寄存器
2.1、什么是寄存器
(1)register
(2)寄存器,寄存,內(nèi)容可變,一般按位定義。也就是內(nèi)容要么是1要么是0.
(3)寄存器使用地址訪問,編程上像內(nèi)存一樣
2.2、寄存器的工作原理
(1)寄存器和硬件之間有雙向影響。寄存器位上的1/0可以控制LED亮滅,鍵盤的按下也可以改變寄存器位上的1/0。
(2)軟件可以讀寫寄存器
(3)總結(jié):寄存器時(shí)軟件能夠控制硬件的關(guān)鍵
2.3、單片機(jī)學(xué)習(xí)的關(guān)鍵就是各種寄存器
(1)單片機(jī)的學(xué)習(xí)主要包括2個(gè):CPU和各種內(nèi)部外設(shè)
(2)各種內(nèi)部外設(shè)的編程接口就是寄存器
(3)熟悉一款單片機(jī)其實(shí)就是熟悉他的寄存器
(4)寄存器會(huì)隨著單片機(jī)的復(fù)雜化而變得復(fù)雜
(5)學(xué)會(huì)用C語言操作寄存器的技巧
3.51單片機(jī)的定時(shí)器簡介
看數(shù)據(jù)手冊
外部12MHZ晶振,單片機(jī)工作在12T模式下,則內(nèi)部時(shí)鐘頻率是1MHZ,則時(shí)鐘脈沖寬度為1us(1/1MHZ=1us)。外部12MHZ晶振,單片機(jī)工作在6T模式下,則內(nèi)部時(shí)鐘頻率是2MHZ,則時(shí)鐘脈沖寬度為1us(1/2MHZ=0.5us)。
4.定時(shí)器的主要寄存器介紹
4.1、TCON

(1)8個(gè)位,但是有4個(gè)名字:TF、TR、IE、IT,每個(gè)名字的符號(hào)都有2個(gè),后面分別帶0和1,對應(yīng)T0和T1.
(2)TF:timer flag,定時(shí)器(溢出)標(biāo)志位,是只讀(軟件只是通過讀取TF1來知道硬件的狀態(tài),而不用去寫這一位來設(shè)置硬件的狀態(tài))的。timer定時(shí)時(shí)間到了后會(huì)做2件事情:第一個(gè)是把TF標(biāo)志改為1,第二個(gè)是產(chǎn)生中斷讓CPU去中斷處理;TF是硬件清零的(由1變0是自動(dòng)的,不需要軟件來干預(yù)。)有一些CPU的設(shè)計(jì)時(shí)需要軟件去清零的(一般高級(jí)芯片),這時(shí)候用戶的程序就一定要記得給標(biāo)志位清零,不然就不能重復(fù)進(jìn)入中斷或者反復(fù)不停的重復(fù)進(jìn)入中斷。
(3)TR就是timer run,就是定時(shí)器的啟動(dòng)計(jì)數(shù)的開關(guān)。當(dāng)我們把整個(gè)定時(shí)器初始化好了以后,我們給TR位寫1就可以開始計(jì)數(shù)了。TR位和GATE位有一定關(guān)聯(lián)性。
(4)GATE是TMOD寄存器中的,也有2個(gè)分別對應(yīng)T0和T1。GATE位中文名叫門控位,工作方式是:當(dāng)GATE=0時(shí)(相當(dāng)于門是打開的,此時(shí)GATE位是可以忽略的),此時(shí)定時(shí)器開關(guān)就只受TR位影響。具體就是TR=1開啟計(jì)數(shù),TR=0結(jié)束計(jì)數(shù)。當(dāng)timer用來計(jì)數(shù)時(shí),很關(guān)鍵的就是什么條件下計(jì)數(shù),什么條件下不計(jì)數(shù)。當(dāng)GATE=0時(shí)計(jì)數(shù)條件只有TR1一個(gè)(TR1=1就計(jì)數(shù),TR1=0就不計(jì)數(shù)),當(dāng)GATE=1時(shí)是否計(jì)數(shù)不僅取決于TR1還取決于INT1引腳(P3.3),實(shí)際規(guī)則是:當(dāng)TR1=1并且INT1引腳也為高電平時(shí)才會(huì)計(jì)數(shù)。
1000 = 0x3E8 = 高0x3 低0xE8 => TL0 = 0xE8 TH0 = 0x3
8888 = 0x22B8 = 高0x22 低0xB8 => TL0 = 0xB8 TH0 = 0x22
4.2、IE&IT
(1)IE也是個(gè)標(biāo)志位,作用就是用來展示硬件的狀態(tài)改變的。比如IE1對應(yīng)外部中斷1(INT1),平時(shí)不發(fā)生INT1時(shí)IE1=0,當(dāng)INT1發(fā)生中斷時(shí),硬件自動(dòng)IE1=1,當(dāng)CPU處理了INT1時(shí)硬件會(huì)自動(dòng)給IE1=0(硬件自動(dòng)清零)。
(2)IT是用來設(shè)置外部中斷的中斷觸發(fā)方式的。所謂中斷的觸發(fā)方式,就是指硬件在某種條件下才會(huì)被判定為要產(chǎn)生中斷,所以其實(shí)就是中斷產(chǎn)生的條件。中斷觸發(fā)方式一般就是:邊沿觸發(fā)和電觸發(fā)2種。邊沿觸發(fā)又分為上升沿觸發(fā)、下降沿觸發(fā)、雙邊沿觸發(fā);電平觸發(fā)方式分為高電平觸發(fā)、低電平觸發(fā)2種。
4.3、TMOD
(1)GATE上面已經(jīng)講過了
(2)C/T位,設(shè)置T0/T1工作在定時(shí)器模式還是計(jì)數(shù)器模式。1表示計(jì)數(shù)器,0表示定時(shí)器。
(3)M1+M0,2個(gè)位一起來表示T0/T1處于哪種工作模式下,一般有4種:13位、16位、8位自動(dòng)重載、雙8位。

5.定時(shí)器編程實(shí)踐
5.1、實(shí)驗(yàn)?zāi)康?/h2>
(1)使用定時(shí)器來完成LED閃爍
(2)原來實(shí)現(xiàn)閃爍時(shí)中間的延遲是用delay函數(shù)實(shí)現(xiàn)的,在delay的過程中CPU要一直耗在這里不能去做別的事情。這是之前的缺點(diǎn)。
(3)本節(jié)用定時(shí)器來定一個(gè)時(shí)間,在這個(gè)定時(shí)器定時(shí)時(shí)間內(nèi)CPU還可以去做主任務(wù),定時(shí)時(shí)間到產(chǎn)生中斷,在中斷處理程序isr中讓LED閃爍即可。
5.2、如何編程
(1)定時(shí)(timer初始化)
(2)主程序做事
(3)中斷處理程序
(4)我們開發(fā)板的定時(shí)器最多能定多長時(shí)間?
內(nèi)部時(shí)鐘頻率是1MHZ,時(shí)鐘周期是1us。最多能定65535(16位定時(shí)器),也就是說最大定時(shí)時(shí)間為65535*1us=65535us=65.535ms。
如果要定比較長的時(shí)間(2s),定時(shí)器直接是不能夠滿足的,解決辦法是多次定時(shí)后加起來構(gòu)成一個(gè)長時(shí)間。
(5)計(jì)算TL0和TH0:
①確定自己定時(shí)時(shí)間,定為50ms
②確定內(nèi)部時(shí)鐘周期,因?yàn)?2T模式,外部晶振12MHZ,所以為:1us
③定時(shí)個(gè)數(shù)就是:50ms/1us=50000
④TL0 = 50000 % 256, TH0 = 50000 / 256(設(shè)置錯(cuò)誤,下面有說)
0xC3 0x50 => 195 80
#include <reg51.h>
unsigned char count; // 10次,對應(yīng)500ms
sbit LED = P0^1; // LED對應(yīng)的GPIO定義
#define CNT 20
void timer0_isr(void) interrupt 1 using 1
{
TL0 = 50000 % 256;
TH0 = 50000 / 256; // 手工重載計(jì)數(shù)值
if (count-- == 0)
{
// 說明已經(jīng)中斷了10次了,500ms到了,干活了
LED = !LED; // LED取反
count = CNT;
}
}
void main(void)
{
TMOD = 0x01; // T0設(shè)置工作在定時(shí)器模式下,16位定時(shí)器
TL0 = 50000 % 256;
TH0 = 50000 / 256;
TR0 = 1; // 開啟計(jì)數(shù)器,開始計(jì)數(shù)了
ET0 = 1; // 開啟T0中斷
EA = 1; // 開啟中斷總開關(guān)
count = CNT; // 10次,對應(yīng)500ms
while (1); // 主任務(wù)
}
6.定時(shí)時(shí)間設(shè)置錯(cuò)誤糾正
6.1、加法定時(shí)器和減法定時(shí)器
(1)定時(shí)器的原理就是計(jì)數(shù)器,加法定時(shí)器計(jì)數(shù)方法是從我們給定的值開始計(jì)數(shù),直到溢出(比如16位定時(shí)器最大值為0xffff,也就是65535,計(jì)數(shù)值到達(dá)這個(gè)值就溢出了)。減法定時(shí)器是從我們給定的值開始減1,減到0就溢出了。
(2)實(shí)例來看,比如16位定時(shí)器。我們設(shè)置的計(jì)數(shù)值為1000,則如果是減法定時(shí)器那么計(jì)數(shù)個(gè)數(shù)就是1000,如果是加法計(jì)數(shù)器則計(jì)數(shù)個(gè)數(shù)就是65535-1000=64535。
(3)51單片機(jī)就是典型的加法定時(shí)器
(4)現(xiàn)代的單片機(jī)或者嵌入式SoC,一般常用的都是減法定時(shí)器了。雖然加法定時(shí)器和減法定時(shí)器都能實(shí)現(xiàn)功能,但是明顯減法定時(shí)器更加直觀,因?yàn)椴挥萌ザ嗉右徊接?jì)算計(jì)數(shù)個(gè)數(shù)。
6.2、51單片機(jī)定時(shí)器設(shè)置值計(jì)算
計(jì)算TL0和TH0:
①確定自己定時(shí)時(shí)間,定為50ms
②確定內(nèi)部時(shí)鐘周期,因?yàn)?2T模式,外部晶振12MHZ,所以為:1us
③定時(shí)個(gè)數(shù)就是:50ms/1us=50000
④計(jì)數(shù)個(gè)數(shù)是50000,那么寫進(jìn)去TL0和TH0里面的計(jì)數(shù)值應(yīng)該是65535-50000=15535
⑤TL0 = 15535% 256, TH0 = 15535/ 256