前段時間我們發布了更多關於 毫秒()函數 de Arduino的現在我們將深入研究 Arduino定時器,要開始使用此功能,請了解此板如何管理 MCU 的時間,以及除了 millis() 之外的其他功能。
什麼是 Arduino 計時器?
El Arduino 計時器,或計時器,是由硬件實現的功能(在微控制器中,借助產生時鐘脈衝並設置“節奏”的石英晶體,無需外部硬件或 IC 555),允許通過時鐘控制臨時事件內部的。 例如,讓任務間隔發生,進行精確的時間測量等,獨立於草圖代碼。
想像一下,您使用 延遲()函數,這將阻止 Arduino MCU 上的執行,直到經過指定的時間,然後繼續執行程序,但計時器不會阻止。 它將隨著 MCU 繼續同時執行其他指令而計時。 這是很大的優勢。
計時器與 中斷 Arduino的,因為它們將通過它們執行以完成某些特定任務。 換句話說,Arduino Timer是一個在某個時間觸發的函數,執行一個中斷函數。 這就是為什麼了解這些中斷也很重要的原因。
模式
Arduino定時器有 2種操作模式,能夠使用它:
- 脈寬調製信號: 你可以控制 Arduino 引腳 (~).
- CTC(比較匹配清除計時器): 對計數器內的時間進行計數,當它達到定時器寄存器中指定的值時,執行中斷。
它有多少個定時器? 定時器的類型
那裡 3個定時器 在盤子上 Arduino UNO,儘管其他頂板上可能還有更多:
- 計時器0: 8 位,可以從 0 計數到 255(256 個可能的值)。 由 delay()、millis() 和 micros() 等函數使用。 不建議對其進行修改,以免改變程序。
- 計時器1:等於 Timer 0。由 UNO 中的 Servo 庫使用(用於 MEGA 的 Timer 5)。
- 計時器2:16 位,範圍從 0 到 65.525(65.536 個可能值)。 用於tone() 函數,如果不使用,可以在您的應用程序中自由使用。
- 定時器 3、4、5(僅在 Arduino MEGA 上): 都是 16 位的。
Arduino 計時器如何工作?
至 使用 Arduino 計時器,了解這一切如何在此開發板的 MCU 中以電子方式工作是至關重要的:
- 時鐘頻率:是每秒能夠開發的周期數,在 Arduino 的情況下是 16 Mhz,或者相同,時鐘信號每秒振盪 16.000.000 次(週期)。
- 期: 用 T 表示,以秒為單位,是周期的倒數。 例如,T=1/C,這將導致 1/16000000 = 0.0000000625,即完成每個循環所需的時間。 而頻率是周期的倒數,所以 f = 1/T。
- 週期: 是每單位時間出現的信號的每一次重複。 在 Arduino 上,它會在一秒鐘內達到 16M。 或者是什麼相同,在這種情況下,當 16 萬個週期過去時,已經過去了 625 秒。 因此,可以說一個週期需要XNUMX ns。
- 信號邊緣:時鐘信號是方波,邊沿可以是上升沿或下降沿。 邊緣是信號從以下位置變化時的直線:
- 0(低)到 1(高):上升沿。
- 1(高)到 0(低):下降沿。
邊緣很重要,因為 Arduino 計時器測量信號邊緣的周期。 A) 是的 接觸者 它隨著每個週期遞增,當它達到寄存器值時,將執行中斷。
因此,一旦你知道這一點,如果你有 Arduino MCU 上的 16Mhz,並且使用8位定時器,可以說每16微秒(256/16000000)或4位(16/65536)每16000000毫秒發生一次中斷。 因此,如果將 16 位計數器寄存器設置為最大值,值為 65535,則中斷將在 4 ms 發生以執行任何任務。
當計數器達到最大可能值時, 它將再次返回 0. 也就是說,發生溢出,它會從頭開始倒計時。
要控制計時器的增加速率,您還可以使用 預分頻器,它取值 1、8、64、256 和 1024 並像這樣改變時間:
定時器速度(Hz)= Arduino的時鐘頻率/預分頻器
如果為 1,則控制器將增加至 16 Mhz,如果為 8 至 2 Mhz,如果為 64 至 250 kHz,依此類推。 請記住,會有一個定時器計數器狀態比較器來比較計數器和預分頻器的值,直到它們相等,然後執行一個動作。 所以, 中斷頻率 由公式給出:
中斷速度(Hz)=Arduino/預分頻器時鐘頻率(比較器寄存器值+1)
幸運的是,我們不能 修改記錄 Arduino 計時器,因為它將由我們在代碼中使用的庫處理。 但如果不使用它們,則應該對其進行配置。
Arduino IDE 中的示例
為了更好地理解這一切,我在這裡展示了 Arduino IDE 的兩個草圖代碼,您可以通過它們體驗定時器的使用。 第一個是每秒閃爍連接到 Arduino 引腳 8 的 LED 的代碼:
#define ledPin 8 void setup() { pinMode(ledPin, OUTPUT); // Configurar Timer1 TCCR1A = 0; //Registro control A a 0, pines OC1A y OC1B deshabilitados TCCR1B = 0; //Limpia el registrador TCCR1B |= (1<<CS10)|(1 << CS12); //Configura prescaler a 1024: CS12 = 1 y CS10 = 1 TCNT1 = 0xC2F8; //Iniciar timer para desbordamiento a 1 segundo //65536-(16MHz/1024/1Hz - 1) = 49912 = 0xC2F8 en hexadecimal TIMSK1 |= (1 << TOIE1); //Habilitar interrupción para Timer1 } void loop() { } ISR(TIMER1_OVF_vect) //Interrupción del TIMER1 { TCNT1 = 0xC2F7; // Reniciar Timer1 digitalWrite(ledPin, digitalRead(ledPin) ^ 1); //Invierte el estado del LED }
編程 LED 的閃爍或閃爍,就像前面的情況一樣每秒一次,但這次使用 CTC,即比較:
#define ledPin 8 void setup() { pinMode(ledPin, OUTPUT); // Configuración Timer1 TCCR1A = 0; //Registro de control A a 0 TCCR1B = 0; //Limpiar registro TCNT1 = 0; //Inicializar el temporizador OCR1A = 0x3D08; //Carga el valor del registro de comparación: 16MHz/1024/1Hz -1 = 15624 = 0X3D08 TCCR1B |= (1 << WGM12)|(1<<CS10)|(1 << CS12); //Modo CTC, prescaler de 1024: CS12 = 1 y CS10 = 1 TIMSK1 |= (1 << OCIE1A); //Habilita interrupción por igualdad de comparación } void loop() { } ISR(TIMER1_COMPA_vect) //Interrupción por igualdad de comparación en TIMER1 { digitalWrite(ledPin, digitalRead(ledPin) ^ 1); //Invierte el estado del LED }買盤 Arduino UNO 版本3