Arduino 使用timer進行延遲,不使用loop,達到按鈕控制led方向
2025/01/09 17:16
瀏覽105
迴響0
推薦0
引用0
#include
#include
#define F_CPU 16000000UL // 定義 CPU 時鐘頻率
#define PRESCALER 256 // 選擇預分頻器 256
volatile bool ledState = false; // LED 狀態:false 表示熄滅,true 表示點亮
volatile unsigned int overflow_count = 0;
const byte forwardBtnPin = 3;
// 右到左,左到右
volatile bool forward = true;
int ledPins[] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; // The LED pins
int num = sizeof(ledPins) / sizeof(int);
// 目前在哪個 LED 上進行亮滅
volatile int ledIdx = 0;
void setup() {
// 設置 LED Pins
for (int i = 0; i < num; i++) {
pinMode(ledPins[i], OUTPUT);
digitalWrite(ledPins[i], LOW); // 確保所有 LED 初始熄滅
}
// 設置按鈕
pinMode(forwardBtnPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(forwardBtnPin), forwardInterrupt, FALLING);
// 初始化 TIMER1
timer1_normal_setup();
}
void timer1_normal_setup() {
// 設定 TIMER1 為普通模式 (Normal Mode)
TCCR1A = 0; // WGM[1:0] = 0
TCCR1B = 0; // WGM[3:2] = 0
// 設定預分頻器為 256
TCCR1B |= (1 << CS12); // CS12=1, CS11=0, CS10=0
TCCR1B &= ~((1 << CS11) | (1 << CS10));
TCNT1 = 0; // 計數器初始值設為 0
TIMSK1 |= (1 << TOIE1); // 啟用 TIMER1 溢出中斷
sei(); // 啟用全域中斷
}
void loop() {
// loop 函式內容保持空
}
ISR(TIMER1_OVF_vect) {
overflow_count++;
// 每次溢出時間: (65536 * 256) / 16,000,000 = 1.048576 秒
if (overflow_count >= 2) { // 2 秒達成
overflow_count = 0; // 重置計數
if (ledState) {
// 如果 LED 目前是亮的,熄滅 LED
digitalWrite(ledPins[ledIdx], LOW);
ledState = false; // 切換為熄滅狀態
} else {
// 如果 LED 目前是暗的,切換到下一個 LED 並點亮
if (forward) {
ledIdx += 1;
if(ledIdx >= num) ledIdx = 0;
} else {
ledIdx -= 1;
if(ledIdx <= 0="" ledidx="num" -="" 1="" div="">
}
digitalWrite(ledPins[ledIdx], HIGH);
ledState = true; // 切換為點亮狀態
}
}
}
// 按鈕中斷服務例程
void forwardInterrupt() {
forward = !forward; // 切換方向
}
你可能會有興趣的文章:
限會員,要發表迴響,請先登入



