一:定时器基础知识:
定时器是单片机内部集成,可以通过编程控制。单片机的定时功能是通过计数来实现的,当单片机每一个机器周期产生一个脉冲时,计数器就加一。定时器的主要功能是用来计时,时间到达之后可以产生中断,提醒计时时间到,然后可以在中断函数中去执行功能。二:硬件定时器和软件定时器
定时器可以基于硬件也可以基于软件实现,两者有各自的特点和适用场景:
硬件定时器是由微控制器硬件提供的定时功能,由专门的计时/计数器电路实现。硬件定时器的最大优势在于精确度高和可靠性强,因为它们不受软件任务和操作系统调度的影响。当需要非常精确的定时功能,如产生PWM信号或者获取精确的时间测量时,硬件定时器是首选。由于定时操作由硬件直接完成,即使主CPU忙于其他任务,定时器仍然可以在预定时间到达时准确地执行回调操作。
软件定时器是由操作系统或者软件库实现的定时器,它们利用操作系统提供的机制来模拟定时器功能。软件定时器的实现受到当前系统负载和任务调度策略的影响,三:定时器基本参数
ESP32S3芯片具有多个硬件定时器,例如 Timer0、Timer1、Timer2 等,每个定时器都包含多个通道。可以通过指定定时器号和通道号来选择具体使用的定时器和通道。基本的定时器参数包括:定时器号、通道号、预分频器、自动重新加载值、定时器中断使能等。
以下是一些基本概念和定时器的共有属性:
计时器(Counter): 定时器的核心组件,负责持续计数。
定时器溢出(Overflow): 当计数器达到其最大值然后归零时发生。
预置值(Preset Value): 计数器达到该值时会产生中断或其它事件。
分频器(Prescaler): 用于减小计数器接收的时钟信号频率,以延长定时器的最大计时范围。
中断(Interrupt): 当定时器达到预置值时,可以配置它来产生一个中断,中断处理程序将执行一些任务。
四:软件编写流程
4.1 创建定时器对象
hw_timer_t *timer = NULL;
4.2 初始化定时器
void setup() {
Serial.begin(115200);
// Set BTN_STOP_ALARM to input mode
pinMode(BTN_STOP_ALARM, INPUT_PULLUP);
// Create semaphore to inform us when the timer has fired
timerSemaphore = xSemaphoreCreateBinary();
// Set timer frequency to 1Mhz
timer = timerBegin(1000000);
// Attach onTimer function to our timer.
timerAttachInterrupt(timer, &onTimer);
// Set alarm to call onTimer function every second (value in microseconds).
// Repeat the alarm (third parameter) with unlimited count = 0 (fourth parameter).
timerAlarm(timer, 1000000, true, 0);
}4.3 定时器中断服务函数
void ARDUINO_ISR_ATTR onTimer() {
// Increment the counter and set the time of ISR
portENTER_CRITICAL_ISR(&timerMux);
isrCounter = isrCounter + 1;
lastIsrAt = millis();
portEXIT_CRITICAL_ISR(&timerMux);
// Give a semaphore that we can check in the loop
xSemaphoreGiveFromISR(timerSemaphore, NULL);
// It is safe to use digitalRead/Write here if you want to toggle an output
}五:软件代码如下:
主程序代码如下所示:
void loop() {
// If Timer has fired
if (xSemaphoreTake(timerSemaphore, 0) == pdTRUE) {
uint32_t isrCount = 0, isrTime = 0;
// Read the interrupt count and time
portENTER_CRITICAL(&timerMux);
isrCount = isrCounter;
isrTime = lastIsrAt;
portEXIT_CRITICAL(&timerMux);
// Print it
Serial.print("onTimer no. ");
Serial.print(isrCount);
Serial.print(" at ");
Serial.print(isrTime);
Serial.println(" ms");
}
// If button is pressed
if (digitalRead(BTN_STOP_ALARM) == LOW) {
// If timer is still running
if (timer) {
// Stop and free timer
timerEnd(timer);
timer = NULL;
}
}
}下载验证如下所示:

我要赚赏金
