|
使用定時器必須弄清的幾個概念!
在MCU中(M16),定時器是獨(dú)立的一個模塊,M16有三個獨(dú)立的定時器模塊,即T/C0、T/C1和T/C2;其中T/C0和T/C2都是8位的定時器,而T/C1是一個16位的定時器。定時器的工作是獨(dú)立于CPU之外自行運(yùn)行的硬件模塊。
1、定時器何時開始工作(或說計數(shù))的?
當(dāng)TCCR0!=0x00任何模式下,只要MCU一上電,T/C就開始計時工作。其實(shí)TCCR0主要是定時器的預(yù)分頻和波形模式、比較匹配模式的設(shè)置,說到預(yù)分頻,不得不提一下這個模塊,這個模塊是T/C0、T/C1共用的一個模塊,但可以有不同的分頻設(shè)置。
2、定時器是如何進(jìn)行工作的:說到定時器的工作,不得不說三個個重要參數(shù):TCNT0、OCR0,TIMSK,TCNT0是設(shè)置定時器的計時初始值,定時器開始工作后立即從TCNT0一直累加到0XFF,累加過程所消耗的時間就是我們需要的定時時間;OCR0是一個比較設(shè)定值,當(dāng)TCNT0的值累計到OCR0時(TNCT0==OCR0),如果有開啟比較匹配中斷功能,那么此時就會產(chǎn)生比較中斷,所以,OCR0的值一般都是設(shè)置在TCNT0初始值和0XFF之間,之外的任何值都不會產(chǎn)生比較中斷。TIMSK是一個中斷使能位設(shè)置,就是我們需要計時器溢出中斷或是比較匹配中斷功能或兩者都要時就對TIMSK的相應(yīng)寄存器位進(jìn)行設(shè)置。
3、定時器的中斷使用,一個定時器可以有兩個中斷資源可利用,一個只溢出中斷,另一個是比較匹配中斷,如上面2所說的。想說明的溢出中斷子程序內(nèi)一般要有重載TCNT0的初始值,否則,TCNT0就會從0X00開始累加計數(shù)到0XFF,所耗費(fèi)的時間就不我們想要的時間。比較中斷就是當(dāng)TCNT0==OCR0時,發(fā)生比較匹配中斷;所以,中斷子程序中一般只插入少量的處理代碼,否則,會發(fā)生所謂的中斷套嵌的現(xiàn)象,由于M16不支持中斷套嵌,這樣會使得中斷子程序中的部分代碼無法執(zhí)行,嚴(yán)重時會造成系統(tǒng)崩潰。
4、TCNT0和OCR0的值換算:對于8bit的計時器,TCNT0一般可以由下面的公式換算:
TCNT0=256-(TV*F)/N;
TV: 所想要設(shè)定的定時時間,單位,us
F: 晶振頻率(MHz)
N: 分頻因子
為了更清楚了解定時器的工作原理,以下是本人與古老師的一段QQ對話,或許看了,你會更能理解定時器:
天地(179748613) 10:33:21
想問一個定時器的問題:定時器的剛開始是從0x00開始累加直到TCNT0,還是從TCNT0開始直到0xFF的
天地(179748613) 10:34:40
銅河哥
萬金油(158755213) 10:35:22
取決于定時器的工作方式
天地(179748613) 10:36:08
工作方式是由那個寄存器控制的
萬金油(158755213) 10:36:35
你自己看看手冊吧
天地(179748613) 10:37:46
沒有的,找了手冊,沒有相關(guān)說明
]
古欣(286629322) 10:42:26
從TCNT0開始直到0xFF的
天地(179748613) 10:43:10
謝謝
銅河(69383181) 10:45:55
剛才不在哈
天地(179748613) 11:12:06
還想問一個問題:定時器支持中斷套嵌嗎?
古欣(286629322) 11:13:34
不支持
天地(179748613) 11:14:05
謝謝
天地(179748613) 11:17:55
定時器的下一次計時開始是從產(chǎn)生溢出中斷后立即開始還是待中斷子程序處理完成后開始計時,
天地(179748613) 11:19:28
老古,幫我一下,我正在論壇里寫關(guān)于定時器的使用的帖子,必須摸清這些概念
古欣(286629322) 11:20:47
中斷后立即開始
古欣(286629322) 11:21:31
也就是說 只要在中斷中不更改TCNT的值,定時的精確度就只取決于晶振了
古欣(286629322) 11:21:55
因此可以使用TC2加一個外部32.768晶振來實(shí)現(xiàn)精確一秒定時
天地(179748613) 11:24:03
那溢出中斷子程序中不是還要個TCNT0重載一下嗎?中斷發(fā)生后立即計時,TCNT0不是從0X00開始了
古欣(286629322) 11:24:38
是的 中斷之后 TCNT從0開始
古欣(286629322) 11:25:14
如果中斷程序中修改了TCNT 就會錯過計時周期 造成誤差
天地(179748613) 11:25:42
0X00到0XFF耗時不是我們需要的值呀
古欣(286629322) 11:25:47
因此 普通的定時方式 是不能用來做 精確的鐘表的
天地(179748613) 11:25:58
我們需要的時間值
古欣(286629322) 11:26:47
這就是你需要解決的問題了 如果精度要求不高 可以在中斷中修改TCNT的值
古欣(286629322) 11:27:12
如果精度要求高 可以采用比較匹配中斷,在中斷中向前加OCR即可
古欣(286629322) 11:27:41
或者采用特殊的晶振,特殊的分頻,達(dá)到從0到0xFF的時間正好是你需要的時間
古欣(286629322) 11:28:04
我們的開發(fā)板上有32.768K晶振,256分頻之后,恰好是一秒
古欣(286629322) 11:28:14
我們也提供了這個例子程序
天地(179748613) 11:29:32
那就是計時器第一個循環(huán)周期是從TCNT0累加到0XFF,從第2個周期開始,以后的循環(huán)周期都是從0X00累加到0XFF,是這樣吧
古欣(286629322) 11:30:32
如果你不在定時器中斷中重載TCNT
古欣(286629322) 11:30:35
就是這樣的
天地(179748613) 11:32:09
你剛說溢出中斷后立即開始重新計時,這與中斷中是否重載TCNT沒有任何關(guān)系呀
古欣(286629322) 11:33:35
你在定時器中斷中重載是用戶行為,你的程序來控制的
古欣(286629322) 11:33:52
自動從0開始,是定時器自身的工作
天地(179748613) 11:36:10
那就是說:溢出中斷的定時并不是一個穩(wěn)定的切精確的定時,反而比較匹配中斷會相對穩(wěn)定和精確,是這樣吧
古欣(286629322) 11:38:31
不是
古欣(286629322) 11:38:44
是你在操作TNCT時 引入了誤差
天地(179748613) 11:44:08
那就有一種現(xiàn)象:就是某個計時周期結(jié)束后,計時器立即開計時,是從0X00開始往上累加,當(dāng)溢出中斷子程序中有重載TCNT,一旦重載被執(zhí)行完成,計時器就從TCNT開始計時,無論此時計時器的累計值大于TCNT,還是小于TCNT,是這樣嗎?
古欣(286629322) 11:47:23
是的 理解正確
天地(179748613) 11:48:37
那這樣的工作方式誤差是否會被累積?也就是誤差會不會越來越大?
古欣(286629322) 11:49:26
當(dāng)然會被累積 一年能有幾分鐘吧
古欣(286629322) 11:49:35
以往用51的時候就存在這個問題
古欣(286629322) 11:49:51
AVR 的TC2 可以外接 時鐘 很好的解決了這個問題
天地(179748613) 11:51:26
如果系統(tǒng)復(fù)位,這些誤差會不會回到初始狀態(tài)?
古欣(286629322) 11:52:13
看來你還是沒有理解 呵呵,這會兒在一邊看笑話的人 也該不少吧
古欣(286629322) 11:52:56
每一個中斷造成的誤差是相同的
古欣(286629322) 11:53:31
你用的時間越長 誤差累計的越多 過一段時間 你需要調(diào)一下你的表
天地(179748613) 11:54:14
我大概了解了
天地(179748613) 11:55:04
斷電復(fù)位可以回復(fù)原有的誤差吧
天地(179748613) 11:56:24
多謝古老大
古欣(286629322) 11:56:43
斷電復(fù)位 一切重頭開始了 那沒有話說
天地(179748613) 11:58:27
幾天的如覆大山的心情,這下輕松了,謝謝老古
天地(179748613) 11:59:19
古欣(286629322) 12:00:29
這段解釋對初學(xué)者挺有意義 復(fù)制到論壇吧
天地(179748613) 12:00:50
我是準(zhǔn)備這樣做
|
|