找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5354|回復(fù): 18
打印 上一主題 下一主題
收起左側(cè)

51定時器---小白有話說

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:53239 發(fā)表于 2013-12-5 09:49 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 Always_Fighting 于 2013-12-5 09:58 編輯

最近看的51定時器方面的,看的有點迷糊,源程序如下,紅色字體就不明白了
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit led1=P1^7;
uint num;

void main ()
{
        TMOD=0x01;
        TH0=(65536-45872)/256;
        TL0=(65536-45872)%256;
        EA=1;
        ET0=1;
        TR0=1;        // 此時定時器已經(jīng)開始啟動,就是開始計數(shù)了吧,                                                                                                                                                                溢出就開始執(zhí)行下邊的中斷程序,可是我的問題來了,
                                當(dāng)T0 溢出之后,TH0和TL0內(nèi)部都清零了嘛 ,                                 此時的T0還繼續(xù)從0開始計數(shù)嗎?
                                還是等中斷函數(shù)運行完再開始計數(shù)呢?
        while(1) ;                                 
}        
void AAA()interrupt 1
{
    TH0=(65536-45872)/256;
        TL0=(65536-45872)%256;
        num++;
        if(num==20)
                {
                  num=0;
                  led1=~led1;
                }
}

此程序就是讓小燈間隔1秒亮滅,書中說道,定時器獨立的部分,一旦啟動就開始計數(shù),
所以不明白了是否溢出后還繼續(xù)從0開始繼續(xù)計數(shù)還是等待!!



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:53239 發(fā)表于 2013-12-5 09:59 | 只看該作者
為什么我的文字格式是這個樣子的呢?
回復(fù)

使用道具 舉報

板凳
ID:57606 發(fā)表于 2013-12-5 14:52 | 只看該作者
你的這個源程序很亂,而且,我個人覺得----無法運行:

1.好幾個沒有定義的變量
2.有未定義的函數(shù)
3.不可控。num起始值是多少?
4.你的EA、ET定義不明

如果實在是格式不好搞,截個圖看看
回復(fù)

使用道具 舉報

地板
ID:53239 發(fā)表于 2013-12-5 15:09 | 只看該作者
kldaft 發(fā)表于 2013-12-5 14:52
你的這個源程序很亂,而且,我個人覺得----無法運行:

1.好幾個沒有定義的變量

這個是郭天祥那本書上的程序,我沒改,運行沒有問題,我就是不明白T0那個定時器在第一次溢出后執(zhí)行什么,是等待中斷函數(shù)執(zhí)行完在開始繼續(xù)加1計數(shù)還是 溢出后立馬就計數(shù)誰也不等  Ps:num沒有賦初值程序是自動默認(rèn)初始值為0吧,我看有的教程是這么說的,那個EA=1不是開總中斷嗎?ET0=1是開定時器0中斷,TR0=1就啟動定時器了,這個好像沒事吧
回復(fù)

使用道具 舉報

5#
ID:18297 發(fā)表于 2013-12-5 15:32 | 只看該作者
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit led1=P1^7;
uint num;

void main ()
{
         TMOD=0x01;
         TH0=(65536-45872)/256;
         TL0=(65536-45872)%256;
         EA=1;
         ET0=1;
         TR0=1;        // 此時定時器已經(jīng)開始啟動,就是開始計數(shù)了吧,(這個正確)                                                                                                                                                                溢出就開始執(zhí)行下邊的中斷程序(這個正確),可是我的問題來了,
                                當(dāng)T0 溢出之后,TH0和TL0內(nèi)部都清零了嘛 (沒有清零),                                 此時的T0還繼續(xù)從0開始計數(shù)嗎?
                                還是等中斷函數(shù)運行完再開始計數(shù)呢?
        while(1) ;                                                                         //空閑死循環(huán)                           
}        
void AAA()interrupt 1
{
     TH0=(65536-45872)/256;                         //這個為重新裝定時器0的初值。(這樣才會每次中斷的定時時間一樣)
         TL0=(65536-45872)%256;
         num++;
         if(num==20)
                 {
                   num=0;
                   led1=~led1;
                 }
}


回復(fù)

使用道具 舉報

6#
ID:53239 發(fā)表于 2013-12-5 15:46 | 只看該作者
zjjhtony 發(fā)表于 2013-12-5 15:32
#include
#define uchar unsigned char
#define uint unsigned int

謝謝啊 第一次溢出后 TH0和TLO為什么沒有全部變0啊 ?
回復(fù)

使用道具 舉報

7#
ID:18297 發(fā)表于 2013-12-5 15:51 | 只看該作者
TH0和TL0在工作方式2時,能自動裝載定時器的初值。
在其他工作方式時, TH0和TL0都需要軟件重新寫入。它不會自動清零。
回復(fù)

使用道具 舉報

8#
ID:53239 發(fā)表于 2013-12-5 15:55 | 只看該作者
zjjhtony 發(fā)表于 2013-12-5 15:51
TH0和TL0在工作方式2時,能自動裝載定時器的初值。
在其他工作方式時, TH0和TL0都需要軟件重新寫入。它不 ...

這樣啊,那么在溢出時TH0和TL0內(nèi)部都是 11111111 11111111 這樣嗎?
回復(fù)

使用道具 舉報

9#
ID:53239 發(fā)表于 2013-12-5 15:55 | 只看該作者
游客 110.205.89.x 發(fā)表于 2013-12-5 15:47
zjjhtony 大神的解釋非常好 我終于看懂了

說說你是怎么理解的啊
回復(fù)

使用道具 舉報

10#
ID:18297 發(fā)表于 2013-12-5 16:12 | 只看該作者
各位,對不起,我搞錯了,定時器在溢出后,TH0和TL0內(nèi)部會自動清零。
我們?yōu)榱诉_(dá)到每次相同的固定的定時時間,才會在中斷程序中進(jìn)行重寫入相同的初值。
抱歉!
回復(fù)

使用道具 舉報

11#
ID:18297 發(fā)表于 2013-12-5 16:15 | 只看該作者
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit led1=P1^7;
uint num;

void main ()
{
         TMOD=0x01;
         TH0=(65536-45872)/256;
         TL0=(65536-45872)%256;
         EA=1;
        // ET0=1;     //不產(chǎn)生中斷。
         TR0=1;
                while(1)
                {
                        P1=TH0;
                        P2=TL0;
                }                                 
}     
使用以上程序,在仿真軟件可以看出,P1,P2是不停循環(huán)變換的,單步仿真能看到TH0和TL0被清零。
抱歉。
回復(fù)

使用道具 舉報

12#
ID:1 發(fā)表于 2013-12-5 21:52 | 只看該作者
工作方式2

在介紹這種式方式之前先讓我們思考一個問題:上一次課我們提到過任意計數(shù)及任意定時的問題,比如我要計1000個數(shù),可是16位的計數(shù)器要計到65536才滿,怎么辦呢?我們討論后得出的辦法是用預(yù)置數(shù),先在計數(shù)器里放上64536,再來1000個脈沖,不就行了嗎?是的,但是計滿了之后我們又該怎么辦呢?要知道,計數(shù)總是持續(xù)重復(fù)的,流水線上計滿后馬上又要開始下一次計數(shù),下一次的計數(shù)還是1000嗎?當(dāng)計滿并溢出后,計數(shù)器里面的值變成了0(為什么,能參考前面課程的說明),因此下一次將要計滿65536后才會溢出,這可不符合要求,怎么辦?當(dāng)然辦法很簡單,就是每次一溢出時執(zhí)行一段程序(這常常是需要的,要不然要溢出干嗎?)能在這段程序中做把預(yù)置數(shù)64536送入計數(shù)器中的事情。所以采用工作方式0或1都要在溢出后做一個重置預(yù)置數(shù)的工作,做工作當(dāng)然就得要時間,一般來說這點時間不算什么,可是有一些場合我們還是要計較的,所以就有了第三種工作方式&#0;&#0;自動再裝入預(yù)置數(shù)的工作方式。

既然要自動得新裝入預(yù)置數(shù),那么預(yù)置數(shù)就得放在一個地方,要不然裝什么呢?那么預(yù)置數(shù)放在什么地方呢?它放在T(0/1)的高8位,那么這樣高8位不就不能參與計數(shù)了嗎?是的,在工作方式2,只有低8位參與計數(shù),而高8位不參與計數(shù),用作預(yù)置數(shù)的存放,這樣計數(shù)范圍就小多了,當(dāng)然做任可事總有代價的,關(guān)鍵是看值不值,如果我根本不需要計那么多數(shù),那么就能用這種方式?磮D4,每當(dāng)計數(shù)溢出,就會打開T(0/1)的高、低8位之間的開關(guān),計預(yù)置數(shù)進(jìn)入低8位。這是由硬件自動完成的,不需要由人工干預(yù)。

常常這種式作方式用于波特率發(fā)生器(我們將在串行接口中講解),用于這種用途時,定時器就是為了供給一個時間基準(zhǔn)。計數(shù)溢出后不需要做事情,要做的僅僅只有一件,就是重新裝入預(yù)置數(shù),再開始計數(shù),而且中間不要任何延遲,可見這個任務(wù)用工作方式2來完成是最妙不過了。

出至:http://www.torrancerestoration.com/mcuteach/235.html
回復(fù)

使用道具 舉報

13#
ID:53239 發(fā)表于 2013-12-6 12:41 | 只看該作者
zjjhtony 發(fā)表于 2013-12-5 16:12
各位,對不起,我搞錯了,定時器在溢出后,TH0和TL0內(nèi)部會自動清零。
我們?yōu)榱诉_(dá)到每次相同的固定的定時時 ...

原來如此,謝謝!
回復(fù)

使用道具 舉報

14#
ID:53239 發(fā)表于 2013-12-6 12:41 | 只看該作者
zjjhtony 發(fā)表于 2013-12-5 16:15
#include
#define uchar unsigned char
#define uint unsigned int

好的,回去試試看
回復(fù)

使用道具 舉報

15#
ID:53239 發(fā)表于 2013-12-6 12:42 | 只看該作者
admin 發(fā)表于 2013-12-5 21:52
工作方式2

在介紹這種式方式之前先讓我們思考一個問題:上一次課我們提到過任意計數(shù)及任意定時的問題, ...

,謝謝老大!
回復(fù)

使用道具 舉報

16#
ID:7485 發(fā)表于 2013-12-7 15:02 | 只看該作者
計數(shù)器/定時器在計數(shù)到0FFFFH后,再加1就是0000H,再加1就是0001H。

所以應(yīng)該是有“清零”的。

中斷源產(chǎn)生中斷請求后,在中斷入口處一般是由一個跳轉(zhuǎn)指令到中斷服務(wù)程序。在中斷程序中,重新給計數(shù)器THx、TLx賦初值,這時計數(shù)器TLx已經(jīng)不是“0”了,而是4或5了。所以如果對精準(zhǔn)要求嚴(yán)格的話,應(yīng)考慮這一點。

當(dāng)然自動重裝載不存在這個問題,所以是很精準(zhǔn)的。
回復(fù)

使用道具 舉報

17#
ID:53239 發(fā)表于 2013-12-9 11:05 | 只看該作者
ahshmj 發(fā)表于 2013-12-7 15:02
計數(shù)器/定時器在計數(shù)到0FFFFH后,再加1就是0000H,再加1就是0001H。

所以應(yīng)該是有“清零”的。

謝謝!
回復(fù)

使用道具 舉報

18#
ID:7485 發(fā)表于 2013-12-9 13:10 | 只看該作者
Always_Fighting 發(fā)表于 2013-12-5 15:55
這樣啊,那么在溢出時TH0和TL0內(nèi)部都是 11111111 11111111 這樣嗎?

TH0和TL0內(nèi)部都是 11111111 11111111時,并不是溢出,再加1變成1 0000 0000 0000 0000時,才產(chǎn)生溢出。由于定時器只有16為,16位全為0,第17位為1,但是被舍棄了,所以只能是0.
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表