ESP32学习笔记(六) 定时器
目录:
ESP32学习笔记(一) 芯片型号介绍
ESP32学习笔记(二) 开发环境搭建 VSCode+platformio
ESP32学习笔记(三) 硬件资源介绍
ESP32学习笔记(四) 串口通信
ESP32学习笔记(五) 外部中断
ESP32学习笔记(六) 定时器
ESP32学习笔记(七) 复位和时钟
1 定时器组(TIMG)
ESP32 芯片包含两个硬件定时器组。每组有两个通用硬件定时器。它们都是基于 16 位预分频器和 64 位自动重载功能的向上/向下计数器的 64 位通用定时器。
TIMGn_Tx 的 n 代表组别, x 代表定时器编号。
1.1 相关API
hw_timer_t * timerBegin(uint8_t timer, uint16_t divider, bool countUp); //定时器开启
//参数:
//num : 定时器编号 0-3
//divider:分频数 16-bit 时钟预分频器,分频系数为 2-65536
//countUp: 是否是累加模式
void timerEnd(hw_timer_t *timer);
void timerSetConfig(hw_timer_t *timer, uint32_t config);
uint32_t timerGetConfig(hw_timer_t *timer);
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge); //将定时器绑到中断上
//参数:
//*timer : 目标定时器 ( 计时器结构体指针 hw_timer_t * )
//void (*fn)(void) : 中断函数入口地址
//中断边沿触发 : 是否跳变沿触发中断 定时器中断触发方式有: 电平触发中断(level type) 边缘触发中断(edge type)
void timerDetachInterrupt(hw_timer_t *timer);
void timerStart(hw_timer_t *timer);
void timerStop(hw_timer_t *timer);
void timerRestart(hw_timer_t *timer);
void timerWrite(hw_timer_t *timer, uint64_t val);
void timerSetDivider(hw_timer_t *timer, uint16_t divider);
void timerSetCountUp(hw_timer_t *timer, bool countUp);
void timerSetAutoReload(hw_timer_t *timer, bool autoreload);
bool timerStarted(hw_timer_t *timer); //判断定时器是否开启
uint64_t timerRead(hw_timer_t *timer);
uint64_t timerReadMicros(hw_timer_t *timer);
uint64_t timerReadMilis(hw_timer_t *timer);
double timerReadSeconds(hw_timer_t *timer);
uint16_t timerGetDivider(hw_timer_t *timer);
bool timerGetCountUp(hw_timer_t *timer);
bool timerGetAutoReload(hw_timer_t *timer);
void timerAlarmEnable(hw_timer_t *timer); //定时器报警使能
void timerAlarmDisable(hw_timer_t *timer);
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload);
//参数:
//*timer : 目标定时器 ( 计时器结构体指针 hw_timer_t * )
//alarm_value : 计数上限值 就是自动重装载值ARR
//autoreload : 是否重装载.
bool timerAlarmEnabled(hw_timer_t *timer); //判断定时器报警是否开启
uint64_t timerAlarmRead(hw_timer_t *timer);
uint64_t timerAlarmReadMicros(hw_timer_t *timer);
double timerAlarmReadSeconds(hw_timer_t *timer);
1.2 定时器中断流程
hw_timer_t *tim1 = NULL; //先定义个结构体指针
tim1 = timerBegin(0, 80, true); //定时器开启 通过时钟那一章可以知道 定时器的时钟信号为APB 所以为80MHz
timerAttachInterrupt(tim1, tim1Interrupt, true); //将定时器绑到中断上
timerAlarmWrite(tim1, 100000, true); //设置ARR 以及 是否重装载
timerAlarmEnable(tim1); //定时器报警使能
esp32-hal-timer.c中有这两句注释
// NOTE: (in IDF 5.0 there wont be need to know groups/numbers
// timer_init() will list thru all timers and return free timer handle)
2 LED PWM控制器
此外设本质上也是定时器实现的 所以放在这一章
ESP32在Arduino开发环境中,如需使用PWM功能,需要通过LEDC的功能来实现,替代了analogWrite(pin, value) 方法。
ESP32 的 LEDC 总共有16个路通道(0 ~ 15),分为高低速两组,高速通道(0 ~ 7)由80MHz时钟驱动,低速通道(8 ~ 15)由 1MHz 时钟驱动。
2.1 相关API
//channel 0-15 resolution 1-16bits freq limits depend on resolution
uint32_t ledcSetup(uint8_t channel, uint32_t freq, uint8_t resolution_bits);
//参数
//channel为通道号,取值0 ~ 15;
//freq,设置频率;
//resolution_bits计数位数,取值0 ~ 20(该值决定后面ledcWrite方法中占空比的最大值,如该值写10,则占空比最大可写2^10-1=1023 ;
//通道最终频率 = 时钟频率 / ( 分频系数 * ( 2^计数位数 ) );(分频系数最大为1024)
void ledcWrite(uint8_t channel, uint32_t duty);
uint32_t ledcWriteTone(uint8_t channel, uint32_t freq);
uint32_t ledcWriteNote(uint8_t channel, note_t note, uint8_t octave);
uint32_t ledcRead(uint8_t channel);
uint32_t ledcReadFreq(uint8_t channel);
void ledcAttachPin(uint8_t pin, uint8_t channel);
void ledcDetachPin(uint8_t pin);
uint32_t ledcChangeFrequency(uint8_t channel, uint32_t freq, uint8_t resolution_bits);
2.2 PWM产生流程
// configure LED PWM functionalitites
ledcSetup(ledChannel, freq, resolution);
// attach the channel to the GPIO to be controlled
ledcAttachPin(ledPin, ledChannel);//将 LEDC 通道绑定到指定 IO 口上以实现输出
// changing the LED brightness with PWM
ledcWrite(ledChannel, dutyCycle);//指定通道输出一定占空比波形
3 电机控制脉宽调制器 (PWM)
持续更新ing