1.穩壓電路
Timer 資訊
https://www.gadgetronicx.com/attiny85-t ... nterrupts/
https://www.phippselectronics.com/using ... -attiny85/
請問attiny85,幾個timer 它們的振盪頻為多少?如何使用?
ATtiny85 有兩個計時器:Timer0 和 Timer1。這些計時器的振盪頻率取決於所選的時鐘源。ATtiny85 的內部 RC 振盪器頻率為 8MHz,但也可以使用外部時鐘源。
Timer0
頻率:內部 RC 振盪器為 8MHz。
使用方法:Timer0 是一個 8 位計時器,可以用來計數、生成 PWM 信號、捕捉外部信號等。可以通過設置 TCCR0A 和 TCCR0B 寄存器來配置 Timer0 的操作模式2。
Timer1
頻率:內部 RC 振盪器為 8MHz。
使用方法:Timer1 是一個 8 位計時器,與 Timer0 類似,可以用來計數、生成 PWM 信號等。可以通過設置 TCCR1 寄存器來配置 Timer1 的操作模式2。
如果你想了解更多關於如何配置和使用這些計時器的詳細信息,可以參考這些資源:Gadgetronicx 和 Phipps Electronics。
Clock
attiny85的程式,產生很準確計時器1秒閃爍一次
將 LED 連接到 ATtiny85 的某個 GPIO 腳位(例如 PB0),並通過一個限流電阻接地
Timer0 CTC 模式:
Timer0 被設定為 CTC 模式(Clear Timer on Compare Match),這意味著當計數器達到 OCR0A 的值時,計數器會被重置。
OCR0A 被設定為 124,因此計數器會從 0 計數到 124,共 125 個計數週期。
預分頻器:
預分頻器設定為 1024,這意味著 Timer0 的時鐘頻率為系統時鐘頻率除以 1024。
如果系統時鐘頻率為 8 MHz,則 Timer0 的時鐘頻率為 8 MHz / 1024 = 7812.5 Hz。
中斷頻率:
每個計數週期的時間為 1 / 7812.5 Hz ≈ 128 µs。
125 個計數週期的時間為 125 * 128 µs = 16 ms。
因此,每 16 ms 會觸發一次中斷。
1 秒計時:
每次中斷時,counter 變數會增加 1。
當 counter 達到 125 時,表示已經過了 125 * 16 ms = 2000 ms = 2 秒。
為了實現 1 秒的計時,我們將 counter 的比較值改為 62,這樣 62 * 16 ms ≈ 1 秒。
修正後程式碼
程式說明:#include <avr/io.h>
#include <avr/interrupt.h>
#define LED_PIN PB0 // 定義 LED 連接的腳位
volatile uint8_t counter = 0; // 用於計數的變數
void setup() {
// 設定 LED 腳位為輸出
DDRB |= (1 << LED_PIN);
// 設定 Timer0 為 CTC 模式
TCCR0A |= (1 << WGM01);
// 設定預分頻器為 1024
TCCR0B |= (1 << CS02) | (1 << CS00);
// 設定比較值為 124 (125 個計數週期)
OCR0A = 124;
// 啟用 Timer0 比較匹配 A 中斷
TIMSK |= (1 << OCIE0A);
// 啟用全局中斷
sei();
}
ISR(TIMER0_COMPA_vect) {
counter++; // 每次中斷計數加 1
// 當計數達到 125 時,表示 1 秒已經過去
if (counter >= 125) {
counter = 0; // 重置計數器
PORTB ^= (1 << LED_PIN); // 切換 LED 狀態
}
}
int main(void) {
setup();
while (1) {
// 主迴圈不需要做任何事情
}
return 0;
}
Timer0 CTC 模式:
Timer0 被設定為 CTC 模式(Clear Timer on Compare Match),這意味著當計數器達到 OCR0A 的值時,計數器會被重置。
OCR0A 被設定為 124,因此計數器會從 0 計數到 124,共 125 個計數週期。
預分頻器:
預分頻器設定為 1024,這意味著 Timer0 的時鐘頻率為系統時鐘頻率除以 1024。
如果系統時鐘頻率為 8 MHz,則 Timer0 的時鐘頻率為 8 MHz / 1024 = 7812.5 Hz。
中斷頻率:
每個計數週期的時間為 1 / 7812.5 Hz ≈ 128 µs。
125 個計數週期的時間為 125 * 128 µs = 16 ms。
因此,每 16 ms 會觸發一次中斷。
1 秒計時:
每次中斷時,counter 變數會增加 1。
當 counter 達到 125 時,表示已經過了 125 * 16 ms = 2000 ms = 2 秒。
為了實現 1 秒的計時,我們將 counter 的比較值改為 62,這樣 62 * 16 ms ≈ 1 秒。
修正後程式碼
代碼: 選擇全部
#include <avr/io.h>
#include <avr/interrupt.h>
#define LED_PIN PB0 // 定義 LED 連接的腳位
volatile uint8_t counter = 0; // 用於計數的變數
void setup() {
// 設定 LED 腳位為輸出
DDRB |= (1 << LED_PIN);
// 設定 Timer0 為 CTC 模式
TCCR0A |= (1 << WGM01);
// 設定預分頻器為 1024
TCCR0B |= (1 << CS02) | (1 << CS00);
// 設定比較值為 124 (125 個計數週期)
OCR0A = 124;
// 啟用 Timer0 比較匹配 A 中斷
TIMSK |= (1 << OCIE0A);
// 啟用全局中斷
sei();
}
ISR(TIMER0_COMPA_vect) {
counter++; // 每次中斷計數加 1
// 當計數達到 62 時,表示 1 秒已經過去
if (counter >= 62) {
counter = 0; // 重置計數器
PORTB ^= (1 << LED_PIN); // 切換 LED 狀態
}
}
int main(void) {
setup();
while (1) {
// 主迴圈不需要做任何事情
}
return 0;
}