原理圖

為什么要使用計時器?
大多數微控制器項目都需要使用精心計時的事件,包括多任務,位沖擊協議,測量等等。這些定時事件可以通過在循環的每次迭代中使用遞增計數器來在軟件中完成。但是,這會浪費可用于執行其他操作的CPU資源,并且此類循環的使用可能難以正確計時。這就是定時器被引入微控制器的原因。現在它們非常普遍,很少找到沒有控制器的控制器。
大多數ATmega設備至少有一個定時器,ATmega168有三個定時器。因此,在本教程中,我們將看看定時器0以及在兩種不同模式下使用時如何將它用于定時事件:正常和比較。
定時器0
定時器0是一個通用的8位定時器,具有一些相當強大的功能,包括比較模式,快速PWM生成和波形生成功能。雖然定時器0可能看起來很復雜,但實際上它使用起來相當簡單,只要你了解其工作原理背后的基礎知識。

定時器0外設布局
首先,AVR上的定時器幾乎與一個由鏈中的一堆觸發器組成的簡單向上計數器相同。每次定時器計時時,它都會遞增一個計數器寄存器,用于跟蹤當前定時器的值。
當定時器達到最大值然后計時時(timer0是一個8位計數器,這意味著它最大值為255),定時器回繞到0并設置定時器溢出位。此位可用于查看計數器是否已溢出,并且在確定特定代碼段是否已停止或未響應的情況下非常有用。
定時器通常可以來自不同的源,包括內部時鐘源和外部I/O引腳。這意味著外部電路可以提供方波,使定時器遞增,或者微控制器本身可以遞增定時器(這通常用作時鐘源)。
一些定時器(如定時器0)有比較單位,允許定時器在定時器等于某個值時觸發中斷。當微控制器需要執行在特定時間過去時執行的事件時,這非常有用。
一個這樣的例子涉及在需要每64uS發送一次脈沖同步脈沖時創建視頻信號(朋友)。其他示例包括多任務,其中微控制器可以每毫秒切換到不同的任務。一旦匹配發生,也可以使這樣的比較單元清除定時器,這樣用戶就不必自己重置定時器。
定時器0:正常模式
在正常模式下,定時器0將在每個時鐘遞增,并且一旦計數器超過其最高值值(255,因為它是一個8位定時器),定時器回繞到值0并設置溢出位(TOV0位在寄存器TIFR0中找到)。
設置定時器0運行在正常模式下,WGM02-WGM01位需要設置為0(注意; WGM02位于TCCR0B中,而位WGM01和WGM00位于寄存器TCCR0A中。

寄存器TCCR0A和TCCR0B中的波形位
定時器0:CTC模式
比較匹配模式(CTC)上的清除定時器與普通模式類似,除非定時器達到的值寄存器OCR0A,定時器清零(復位為0x00)。這可用于創建定時事件,包括延遲和中斷,而無需使用軟件資源(全部在硬件中完成)。
當定時器等于OCR0A的值時,則設置OCF0A,表示匹配在定時器和OCR0A之間發生。要在CTC模式下配置定時器0,需要將WGM02-WMG00位設置為0x02。
定時器0時鐘源
定時器0可以通過外部源(通過T0引腳)或內部I/O時鐘提供時鐘。某些I/O時鐘源可以如表所示進行預分頻,時鐘源選擇位可在TCCR0B寄存器中找到。

從顯示預分量選項的ATmega數據表中提取
關于中斷標志的注意事項
重要的是要注意AVR是為了清除標志,你必須在標志上寫一個邏輯的。這意味著,例如,如果要清除溢出標志,則將1寫入寫入0的寄存器INSTEAD。
示例1:正常模式
此模式顯示在正常模式下使用定時器0來打開和關閉LED每次計數器翻轉(超過255)。
/*
* AVR Timer.c
*
* Created: 08/01/2018 13:16:36
* Author : RobinLaptop
*/
#define setBit(reg, bit) (reg = reg | (1 《《 bit))
#define clearBit(reg, bit) (reg = reg & ~(1 《《 bit))
#define toggleBit(reg, bit) (reg = reg ^ (1 《《 bit))
#define clearFlag(reg, bit) (reg = reg | (1 《《 bit))
#include
int main(void)
{
// Initialize Registers
clearBit(TCCR0A, WGM00); // Configure WGM to be 0x00 for normal mode
clearBit(TCCR0A, WGM01);
clearBit(TCCR0B, WGM02);
setBit(TCCR0B, CS00); // Configure clock source to be clock io at 1024 pre-scale
clearBit(TCCR0B, CS01);
setBit(TCCR0B, CS02);
DDRD = 0xFF; // Make PORT D and output
while (1)
{
// Wait until the TOV0 bit is set
while(!(TIFR0 & (1 《《 TOV0)))
{
}
// Clear the overflow flag by writing a 1 to it. I know, thats dumb but that‘s how it is!
clearFlag(TIFR0, TOV0);
// Toggle the LED (PD0 , Pin 2)
PORTD = PORTD ^ (1 《《 PD0);
}
}
示例2:CTC模式
當定時器0等于OCR0A的值時,該模式將切換LED。一旦匹配發生,定時器將自動復位并設置OCF0A標志。
/*
* Example 2 - CTC.c
*
* Created: 08/01/2018 13:43:06
* Author : RobinLaptop
*/
#define setBit(reg, bit) (reg = reg | (1 《《 bit))
#define clearBit(reg, bit) (reg = reg & ~(1 《《 bit))
#define toggleBit(reg, bit) (reg = reg ^ (1 《《 bit))
#define clearFlag(reg, bit) (reg = reg | (1 《《 bit))
#include
int main(void)
{
// Initialize Registers
clearBit(TCCR0A, WGM00); // Configure WGM to be 0x00 for normal mode
setBit(TCCR0A, WGM01);
clearBit(TCCR0B, WGM02);
setBit(TCCR0B, CS00); // Configure clock source to be clock io at 1024 pre-scale
clearBit(TCCR0B, CS01);
setBit(TCCR0B, CS02);
DDRD = 0xFF; // Make PORT D and output
OCR0A = 0x7F; // Reset the timer once the value of the timer reaches 127
while (1)
{
// Wait until the OCF0A bit is set
while(!(TIFR0 & (1 《《 OCF0A)))
{
}
// Clear the overflow flag by writing a 1 to it. I know, thats dumb but that’s how it is!
clearFlag(TIFR0, OCF0A);
// Toggle the LED (PD0 , Pin 2)
PORTD = PORTD ^ (1 《《 PD0);
}
}
結論
本教程僅涉及計時器能夠做更多事情的計時器。例如,這些定時器可以啟用它們的中斷,這將允許微控制器在設置標志后立即運行時間敏感的代碼。或者,我們可以執行其他代碼,而不是使用while循環來等待溢出標志觸發,這樣可以更有效地利用CPU。很明顯,定時器非常強大,可以為大多數項目帶來巨大的變化!
-
ATmega168
+關注
關注
0文章
9瀏覽量
9511 -
TIMER0
+關注
關注
0文章
21瀏覽量
7722
發布評論請先 登錄
TVS vs TSS 兩種保護機制的深度博弈
NRF54L15DK串行恢復模式沒有了藍牙功能,應該怎樣在藍牙模式下進行ota
用PLC實現卷徑計算的兩種算法
ADI GMSL技術兩種視頻數據傳輸模式的區別
這兩種TVS有啥不同?
兩種散熱路徑的工藝與應用解析
CMOS 2.0與Chiplet兩種創新技術的區別
【BPI-CanMV-K230D-Zero開發板體驗】+兩種開發板間的比較
兩種驅動方式下永磁直線開關磁鏈電機的研究
兩種感應電機磁鏈觀測器的參數敏感性研究
銣原子鐘與CPT原子鐘:兩種時間標準的區別
分享兩種前沿片上互連技術
怎樣在兩種不同模式下使用ATmega168上的Timer0
評論