You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32(Wokwi仿真)LEDC模块定时器始终返回0问题排查

ESP32 LEDC定时器未计数问题排查(裸寄存器开发)

问题背景

  • 开发环境:Wokwi仿真,C语言直接操作ESP32寄存器(不使用SDK,首次接触C语言)
  • 已实现功能:普通LED开关控制、按键输入
  • 当前问题:配置LEDC定时器、通道及GPIO(引脚26,外设71)后无任何反应;读取LEDC定时器计数值始终返回0,预期应看到计数递增至溢出后循环重置

已尝试的配置

  • 参考ESP32技术参考手册(GPIO寄存器第69页、LEDC寄存器第399页)
  • 配置参数:8位分辨率、分频系数1,尝试开启REF_TICK时钟源,均未解决问题

测试代码

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#define GPIO_CFG_BASE 0x3FF44530;
#define LEDC_CONF_REG 0x3FF59190; //bit 1 to choose clk
#define LEDC_HSCH0_CONF0_REG 0x3FF59000;
#define LEDC_HSCH0_HPOINT_REG 0x3FF59004;
#define GPIO_ENABLE_W1TS 0x3FF44024;
#define LEDC_HSCH0_DUTY_REG 0x3FF59008;
#define LEDC_HSCH0_CONF1_REG 0x3FF5900C;
#define LEDC_HSTIMER0_CONF_REG 0x3FF59140;
#define LEDC_HSTIMER0_VALUE_REG 0x3FF59144;
#define LEDC_HSCH0_DUTY_R_REG 0x3FF59010;
#define LEDC_INT_RAW_REG 0x3FF59180;
#define LEDC_INT_ENA_REG 0x3FF59188;

void app_main() {

  volatile uint32_t* interrupts_enable = LEDC_INT_ENA_REG;
  *interrupts_enable |= (0b10001);

  volatile uint32_t* timer_cfg = LEDC_HSTIMER0_CONF_REG;
  *timer_cfg |= 8;
  *timer_cfg |= 1<<13;
  *timer_cfg |= 1<<25;
  volatile uint32_t* reader_timer = LEDC_HSTIMER0_VALUE_REG;
  volatile uint32_t* interrupt_reader = LEDC_INT_RAW_REG;
  //printf("%" PRIX32 "\n", *timer_cfg);
  volatile uint32_t* ls_cfg = 0x3FF59160;
  *ls_cfg |= 8;
  *ls_cfg |= 1<<13;
  *ls_cfg |= 3<<25;

  volatile uint32_t* reader_slow = 0x3FF59164;
  
  while (true) {
    printf("%" PRIu32 "timer\n",*reader_timer);
    printf("%" PRIu32 "timer SLOW\n",*reader_slow);
    printf("%" PRIu32 "interrupt\n",*interrupt_reader);
    vTaskDelay(20 / portTICK_PERIOD_MS);
  } 
}

问题分析与修复建议

1. 未配置LEDC全局时钟源

代码中定义了LEDC_CONF_REG但未初始化,LEDC模块的时钟源需要先通过该寄存器配置。高速定时器的时钟源由LEDC_CONF_REG的HCLK_SEL(bit[1:0])决定:

  • 00: APB_CLK(默认80MHz)
  • 01: REF_TICK(1MHz)
  • 10: FOSC(40MHz)

添加以下代码初始化时钟源:

volatile uint32_t* ledc_conf = LEDC_CONF_REG;
*ledc_conf &= ~0b11; // 清除原有配置
*ledc_conf |= 0b00;  // 选择APB_CLK作为高速定时器时钟源

2. 定时器分辨率配置错误

根据ESP32技术手册,LEDC_HSTIMER0_CONF_REG的DUTY_NUM(bit[3:0])字段设置的是分辨率位数-1。要实现8位分辨率,应设置为7而非8。

3. 无效的位操作

代码中*timer_cfg |= 1<<25属于无效操作,LEDC_HSTIMER0_CONF_REG的bit[25]是保留位,对高速定时器无作用。高速定时器的时钟源由全局LEDC_CONF_REG控制,无需在此处设置。

4. 分频系数未正确配置

定时器分频系数由LEDC_HSTIMER0_CONF_REG的DIV_NUM(bit[19:14])字段决定,分频系数为DIV_NUM + 1。要设置分频系数1,需将该字段设为0。

修正后的定时器配置代码

volatile uint32_t* timer_cfg = LEDC_HSTIMER0_CONF_REG;
*timer_cfg = 0; // 先清零寄存器,避免原有默认值干扰
*timer_cfg |= 7;                // 8位分辨率(7+1)
*timer_cfg |= (0 << 14);        // 分频系数1(0+1)
*timer_cfg |= (1 << 13);        // 使能高速定时器0

5. Wokwi仿真验证

部分ESP32外设细节在Wokwi仿真中可能存在限制,若修正配置后仍无反应,建议在真实ESP32硬件上测试,排除仿真环境的影响。

内容的提问来源于stack exchange,提问作者Michele Del Grosso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 22:56:02