文章目录
- 前言
- 一、ESPTIMER定时器的介绍
- 1.1 定时器是什么
- 二、分频系数
- 2.1 为什么需要分频系数
- 2.2 分频系数怎么计算
- 三、定时器的使用
- 3.1 初始化定时器对象
- 3.2 设置中断时间
- 3.3 设置回调函数
- 3.4 使能定时器
- 四、示例代码
- 总结
前言
在嵌入式系统中,定时器是一项重要的功能,它能够以预定的时间间隔触发特定的功能或任务。ESP32是一款强大的开发板,通过使用Arduino编程语言,我们可以轻松地使用定时器功能来实现各种应用。本文将介绍如何在ESP32上使用定时器。
一、ESPTIMER定时器的介绍
1.1 定时器是什么
单片机(Microcontroller)中的定时器是一种硬件模块,用于计时、计数和生成定时事件。定时器通常由一个或多个计时/计数器组成,并且具有相关的控制逻辑和寄存器。它是单片机中的重要组件,广泛应用于各种实时计时、时间测量和定时操作的应用中。
定时器在单片机中的作用包括:
事件计时:定时器可以用于测量两个事件之间的时间间隔。开发者可以使用定时器来计算传感器读数之间的时间间隔、测量电平持续时间或定时特定操作的执行时间。
周期性操作:定时器可以配置为以固定的时间间隔生成中断或触发相关事件。这种周期性操作对于周期性数据采集、控制信号的生成和实时任务的调度非常有用。
脉冲宽度调制(PWM):定时器通常可以生成PWM信号,用于控制模拟电路、执行数字-模拟转换或驱动电机等设备。通过调整定时器的计数值和输出设置,可以实现不同占空比的PWM信号。
超时检测:使用定时器可以实现超时检测功能,以便在特定时间内接收或处理输入数据。例如,通过设定定时器的计数值和预定时间,可以检测输入信号是否在指定时间内到达。
时基生成:定时器可以用于生成时基信号,例如时钟信号或其他时间参考信号,用于同步其他硬件模块的操作。
定时器在单片机中的具体实现和功能会根据芯片架构和制造商的不同而有所差异。每个单片机都会提供特定的定时器模块,并且通常包括计数器、预分频器、控制寄存器和中断机制等。开发者可以通过配置和操作这些寄存器来实现所需的定时功能。
总的来说,单片机中的定时器是一种硬件模块,用于计时、计数和生成定时事件。它在实时计时、时间测量、周期性操作和时基生成等应用中发挥着重要作用。开发者可以利用定时器来满足各种特定的计时和定时需求,从而实现单片机系统的功能扩展和更高级的应用。
二、分频系数
2.1 为什么需要分频系数
首先我们需要知道怎么算一个时钟的周期,他有下面这个公式计算:
在72MHz的CPU中,他每一个时钟周期的频率就是
预分频系数一般是用在计时器中的,在计时器中,他的原理就是计数,计数到指定产生一个中断而已,
计数器寄存器为16位寄存器,他可以存储最大0xFFFF
个数据,当有一个时钟过来的时候,他的计数值+1
,那么我们就可以计算他的中断产生一次多少us了。当从0计数到0xFFFF
时,我们可以计算出他的时间为大约910us
,那如果我们1ms或者1us产生中断怎么办,现在这样就不够用了啊,这样就出现了我们的分频系数,他的原理就是在计数寄存器前面在加一个计数的,这样达到分频的效果
ESP32的可自动重载的向上/向下计数器是一个32位的定时器,16 位预分频器
2.2 分频系数怎么计算
如果我们设置分频系数为1
时,他会从0计数到1,再到0,到0时他发出一个时钟周期,这样输入给计数器的时钟频率就只有36MHz了,再通过计数器的原理就可以发现他的中断时间延长了,比如说我的分频系数为10,那么我们可以进行计算他一次中断的时间:
分频系数为10的时候,计数器得到的时钟频率为7.2MHz
,他的周期为
那么一个周期为1.3889us
,如果计数器为0~0xFFFF,则我们可以算出一次中断的时间为:大约91,021.5615us
一次中断
三、定时器的使用
3.1 初始化定时器对象
我们可以使用下面这个函数来初始化一个定时器对象:
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp);
参数1为哪个定时器,参数2为分频系数,参数3为计数的方向,他的返回值为定时器句柄
3.2 设置中断时间
我们可以通过下面这个函数设置自动装载值和是否自动装载:
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload);
参数1为定时器句柄,参数2为自动装载值,参数3为是否循环执行
3.3 设置回调函数
我们可以使用下面这个函数设置回调函数:
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge);
参数1为你要设置定时器的句柄,参数2为回调函数,他的类型为:void (void)
类型
edge用于指定触发中断的边沿类型。边沿类型指定了触发中断的条件,可以选择为上升沿(rising edge)或下降沿(falling edge)。
当edge为true时,表示使用上升沿触发中断。也就是说,当输入信号从低电平变为高电平时,触发中断。
当edge为false时,表示使用下降沿触发中断。也就是说,当输入信号从高电平变为低电平时,触发中断。
3.4 使能定时器
我们可以使用下面这个函数使能某个定时器:
void timerAlarmEnable(hw_timer_t *timer)
参数为定时器句柄指针。
四、示例代码
#include <Arduino.h>
void TIMx_ISR(void)
{
LED_TOGGLE();
}
void timx_int_init(uint16_t arr, uint16_t psc)
{
timer = timerBegin(TIMx_INT, psc, true); /* 初始化定时器0 */
timerAlarmWrite(timer, arr, true); /* 设置中断时间 */
timerAttachInterrupt(timer, &TIMx_ISR, true); /* 配置定时器中断回调函数 */
timerAlarmEnable(timer); /* 使能定时器中断 */
}
void setup()
{
timx_int_init(5000, 8000); /* 定时器初始化,定时时间为500ms */
}
void loop()
{
/* 死循环,不做事情,等待定时器中断触发 */
delay(1000);
}
总结
通过本文,我们学习了在ESP32 Arduino中使用定时器的基本原理和步骤。我们了解了ESP32的定时器库,它提供了简单而强大的定时器功能。我们学习了如何初始化定时器、设置定时器的时间间隔和回调函数,并通过示例代码演示了如何使用定时器执行特定任务。
定时器功能在许多应用中都非常有用,例如周期性传感器读取、任务调度、定时触发等。ESP32的定时器功能为我们带来了更大的灵活性和控制力,使得开发各种应用变得更加简单和高效。
希望本文对你在ESP32 Arduino上使用定时器有所帮助。如果你希望深入学习和探索定时器的更高级功能,建议查阅ESP32的官方文档和相关教程。祝你在ESP32项目中取得成功!