<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 51單片機(jī)之寄存器-3.1單片機(jī)定時(shí)器

          51單片機(jī)之寄存器-3.1單片機(jī)定時(shí)器

          作者: 時(shí)間:2016-11-21 來源:網(wǎng)絡(luò) 收藏
          前面我們講解了如何通過軟件來延時(shí),從而達(dá)到了提升了燈亮與滅的間隔時(shí)間,其過程是讓cpu干別的事情,從而達(dá)到延時(shí)的效果。但是軟件延時(shí)不是很精確,這里我們學(xué)習(xí)一種比較精確的硬件延時(shí),也叫定時(shí)器。定時(shí)器怎么理解呢?這里舉個(gè)簡單的例子來說明。
          圖1 鬧鐘的操作?

          講定時(shí)器之前我們來看看如何操作鬧鐘,這個(gè)生活中的小例子,相信大家都很熟悉。首先我們要設(shè)定定時(shí)時(shí)間,定時(shí)多久呢?我們通過調(diào)節(jié)如圖中紅色區(qū)域指針來告訴鬧鐘定時(shí)多久。然后開啟鬧鐘,怎么樣開啟呢?如上圖中藍(lán)色部分,按下按鈕讓鬧鐘知道現(xiàn)在要開啟定時(shí)的功能了。很簡單的兩個(gè)動(dòng)作,鬧鐘設(shè)置就完成了。之后就是鬧鐘自己的事情了。你就可以去干別的事情了,比如看電影,睡覺,喝茶等等。那么定時(shí)的時(shí)間到了怎么樣告訴你呢?大家都知道,通過響鈴來告訴你時(shí)間到了。懂得了鬧鐘的過程,那么類比一下就很容易明白單片機(jī)定時(shí)器。前面講過,單片機(jī)是人設(shè)計(jì)的產(chǎn)品,自然反映人的思維過程。只不過在單片機(jī)中,它把日常用的詞匯專業(yè)化了,功能復(fù)雜了一點(diǎn)?,F(xiàn)在我們來按照鬧鐘的思維講述單片機(jī)定時(shí)器。

          本文引用地址:http://www.ex-cimer.com/article/201611/319546.htm
          圖2 定時(shí)器的操作示意圖?

          首先我們看看如何開啟定時(shí)器,在鬧鐘中我們使用手來按下按鈕,這樣鬧鐘定時(shí)就開啟了。在單片機(jī)中只有0和1,那么很容易想到采用0和1控制定時(shí)的開關(guān),并給它取個(gè)名字(TR0). 如何理解這個(gè)名字了,T表示timer, R表示run,0表示定時(shí)器,合起來就表示定時(shí)器0運(yùn)行控制,這樣很容易就記住了定時(shí)器的開關(guān)控制。那么下一個(gè)問題,定時(shí)多長時(shí)間。講這個(gè)問題之前我們先來看看鬧鐘如何計(jì)時(shí)的。秒鐘每走一格就是1s,走10格我們就知道走了10s,也就是說我們可以通過查看格子的數(shù)目來知道時(shí)間的量。在單片機(jī)中如何計(jì)時(shí)呢?如上圖,有兩個(gè)寄存器TH0和TL0,很容易想到,可以用TH0和TL0中存放的數(shù)據(jù)來知道時(shí)間。鬧鐘中每一個(gè)格子是1秒鐘,那么在TH0和TL0中每放一個(gè)數(shù)是多少時(shí)間呢。定時(shí)器計(jì)時(shí)是通過晶振來完成的。這里我們使用的晶振大小為11.0592M,表示一秒鐘時(shí)間內(nèi),晶振運(yùn)行11.0592次,那么運(yùn)行一次的時(shí)間為[1/(11.0592M)]S, TH0和TL0中每計(jì)數(shù)一次需要晶振運(yùn)行12次(至于為什么,后面我們會(huì)講到),因此需要的時(shí)間為12×[1/(11.0592M)]S. 為了方便計(jì)算我們把它換成微秒單位: (12/11.0592)Us. 可見時(shí)間長度是通過TH0和TL0來完成的。那么能不能只用一個(gè)TL0來計(jì)數(shù)呢?當(dāng)然可以。因此這里就涉及到了計(jì)時(shí)模式的問題,TH0+TL0構(gòu)成16bit的計(jì)時(shí)器,或者只使用TL0或者使用TH0(8bit)和TL0低5位。那么我用TH0高4位和TL0低7位可不可以?不可以,我們不去追問為什么,單片機(jī)工程師設(shè)計(jì)的,我們要做的就是了解它的規(guī)則。既然工作模式有這么多,那么單片機(jī)怎么知道要使用哪種工作模式。很明顯需要有個(gè)寄存器來告訴單片機(jī)這個(gè)信息,這個(gè)寄存器叫TMOD. 如上圖所示的M0和M1,很容易知道2個(gè)位就能產(chǎn)生4種組合情況(00/01/10/11),這樣分別對應(yīng)與定時(shí)器的4種工作模式。最后一個(gè)問題,到點(diǎn)響鈴。鬧鐘定時(shí)到了會(huì)發(fā)出響鈴來通知你,那么在單片機(jī)中到點(diǎn)了會(huì)通知CPU,怎么通知呢,如上圖所示中的TF0(F-full表示滿了,也就是溢出), TH0/TL0滿了TF0就會(huì)由0變1,然后通過硬件通知CPU時(shí)間到了。這樣就完成了整個(gè)定時(shí)過程。從以上分析可以看出,定時(shí)器的操作過程與鬧鐘非常相似,只不過單片機(jī)的定時(shí)器在計(jì)數(shù)方面復(fù)雜了一點(diǎn),多了幾種工作模式?,F(xiàn)在相信大家已經(jīng)大概了解單片機(jī)定時(shí)器了。

          ?現(xiàn)在我們根據(jù)所講的內(nèi)容,舉一個(gè)簡單例子,通過定時(shí)器0來控制LED亮一秒滅一秒。按照上面過程,我們一步一步來分析

          (1) 確定定時(shí)多長時(shí)間

          前面講了定時(shí)時(shí)間是通過TH0和TL0來控制的,那么使用TH0和TL0之前先要設(shè)定工作模式,用16bit還是8bit或者其他。這里我們選擇16bit。怎么選呢?表1中給出了定時(shí)器0和1工作模式的控制寄存器,8個(gè)位的初始化值都是0,綠色部分用來控制定時(shí)器1,黃色部分用來控制定時(shí)器0,現(xiàn)在我們只看黃色部分。一共4個(gè)控制位,Gate,C/T,M1,M0. 很容易看到,Gate,C/T都要設(shè)置0,現(xiàn)在要選中16bit的工作模式,那么M1M0=01. 因此TMOD=00000001=0X01 假設(shè)在圖2中,TL0,TH0初始值為0,那么16bit最多可以裝下65535,考慮到溢出,因此這里取65536,每裝一個(gè)數(shù)需要(12/11.0592)Us,那么裝65536需要,UnitT=65536×(12/11.0592)約等于71000Us,也就是71ms. 現(xiàn)在我要定時(shí)1s,很明顯,TH0和TL0不夠用,那是不是要多增加幾個(gè)TH0和TL0,沒有必要。我們可以通過軟件來解決硬件上的不足,最簡單的方式就是使用循環(huán)多次。比如我讓UnitT為10ms,那么循環(huán)100次就是1秒了。那么怎么設(shè)置UnitT=10000Us, UnitT=(65536-X) × (12/11.0592)=10000Us, 其中X為TH0和TL0組成的16bit的初始值。將這個(gè)等式改進(jìn)一下:

          UnitT=(65536-X) / 0.9216, 在該式中UnitT×0.9216要小于65536,并且要保證UnitT×0.9216為正整數(shù),因此UnitT的取值范圍為:

          10000

          因此簡單來看,UnitT可以取10ms, 20ms, 30ms, 40ms, 50ms, 60ms, 70ms,

          再根據(jù)我們最終要定時(shí)的時(shí)間為1000ms, 因此UnitT只能取10ms, 20ms, 50ms,這樣根據(jù)UnitT=(65536-X) / 0.9216就能計(jì)算出初始值X,

          這里我們?nèi)nitT=50ms, X=19456,16進(jìn)制表示為: 4C00H, 因此TH0= 0X4C, THL0=0X00.

          因此這樣我們就確定了定時(shí)時(shí)間用的初始值,TH0和TL0,并且需要重復(fù)20次

          (2) 啟動(dòng)定時(shí)器

          如何啟動(dòng)定時(shí)器,查看表2定時(shí)器控制寄存器TCON,只要設(shè)置TR0=1即可。表2中涉及到中斷的問題我們暫時(shí)不管,這里我們只討論定時(shí)器,下一講談中斷。這里為什么能直接設(shè)置TR0,為什么在設(shè)置定時(shí)器工作模式時(shí)不能直接設(shè)置M1M0,而要通過TMOD來設(shè)置。這個(gè)涉及到尋址方式的問題,我們暫時(shí)不討論。

          (3) 響鈴?fù)ㄖ?/p>

          那么鬧鐘響鈴對應(yīng)定時(shí)器的哪個(gè)部分。前面我們設(shè)置了TH0和TL0,初始值為19456,然后不停的增大直到65535,再增大一個(gè)變成65536此時(shí)TH0和TL0裝不下了,因此溢出,此時(shí)單片機(jī)通過硬件將TF0從0變?yōu)?來通知CPU,查看表2中TF0的說明可知。因此TF0的值對應(yīng)著響鈴。

          (4) 點(diǎn)亮LED

          我們要讓LED延時(shí)1s后點(diǎn)亮或者熄滅,因此這里需要一個(gè)參數(shù)來對定時(shí)器TF0的溢出次數(shù)計(jì)數(shù),當(dāng)溢出20次時(shí),表示定時(shí)到了1s。

          這樣我們很容易的得出程序的框架圖,

          參考代碼如下:

          #include "reg52.h"

          sbit LED=P1^0;

          void main(void)

          {

          unsigned char CYC = 0;

          TMOD=0X01;

          TH0=0X4C;

          TL0=0X00;

          TR0=1;

          while(1)

          {

          if (TF0==1)

          {

          TF0=0;

          TH0=0X4C;

          TL0=0X00;

          CYC++;

          if(CYC==20)

          {

          CYC=0;

          if(LED==0)

          {

          P1=0XFF ;

          LED=1;

          }

          else

          {

          LED=0;

          P1=0X00;

          }

          }

          }

          }

          }



          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();