针对第二篇的内容,有个小问题,每次读取后需要把定时器的内容清零
timerWrite(timer,0);
下面程序优化后,并把计数溢出值改的比较高,这样避免反复进入定时器中断可以优化一点。但效果也不行
#include <Arduino.h>
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; //声明一个portMUX_TYPE类型的变量,利用其对主代码和中断之间的同步进行处理
hw_timer_t *timer = NULL;
volatile uint32_t timerCount = 0;
volatile int interruptFlag = 0; //(中断回调函数与主程序共享的变量要加上 volatile 关键字)
volatile int interruptFlag_clear = 0; //(中断回调函数与主程序共享的变量要加上 volatile 关键字)
const int interruptPin = 5; // 外部中断引脚
void IRAM_ATTR interruptHandler() {
portENTER_CRITICAL_ISR(&mux); // 处理并发
interruptFlag_clear = 1;
portEXIT_CRITICAL_ISR(&mux);
}
void setup() {
Serial.begin(115200);
// 配置定时器
timer = timerBegin(10000000); //10M
timerAttachInterrupt(timer, []() {
timerCount++;
});
timerAlarm(timer, 10000000, true, 0); // 设置定时器中断时间间隔
timerStart(timer);
// 配置外部中断
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), interruptHandler, FALLING);
}
void loop() {
// Serial.print("Timer count: ");
// Serial.println(timerCount);
// timerCount = 0;
// delay(1000);
if (interruptFlag_clear == 1) {
interruptFlag++;
if (interruptFlag == 1) {
timerCount = 0; //第一个脉冲,计数清零
} else if (interruptFlag == 101) {
//第二次进入,统计计数个数,并计算频率
// timerStop(timer); //停止计数器
double timer_other = timerRead(timer);
double dre_time = timerCount + timer_other / 10000.0; //单位为微秒
double fre = 100000.0 / (dre_time);
Serial.println("timerCount: " + String(timerCount));
Serial.println("timer_other: " + String(timer_other, 6));
Serial.println("dre_time: " + String(dre_time, 6));
Serial.println("fre: " + String(fre, 6));
timerWrite(timer,0);// This function is used to set counter value of the timer.
timerCount = 0; //清零
interruptFlag = 0;
// timerAlarm(timer, 100, true, 0); // 设置定时器中断时间间隔(这里是 1 秒)
// timerStart(timer); // 重启定时器
}
interruptFlag_clear = 0;
}
}
输入1KHz,得出频率相差快10Hz。