提示:启明智显专为智能产品提供一站式彩屏显示+连接+云端服务+APP软件开发、维护等解决方案,帮厂商快速实现硬件的智能化。作为启明云端旗下方案公司,我们用心整理了开发小伙伴在开发过程中可能会遇到的问题以及快速上手的简明教程,同时也用心整理了连接+显示应用的新方案!希望你能第一时间了解并快速用上好的方案和产品!
参考文献 https://xuhong.blog.csdn.net/article/details/80417430 https://blog.csdn.net/weixin_43677266/article/details/121694652
PWM叫脉冲宽度调制,通过编程控制输出方波的频率和占空比(高电平的比例),广泛应用在测量,通信,功率控制与变换等各种领域(呼吸灯,电机)。
PWM其实就是模拟方式稳定输出,通过调节PWM的占空比和周期来调节电压电流大小
占空比:就是输出的PWM中,高电平保持的时间与该PWM的时钟周期的时间之比。如一个PWM的频率是1000 Hz,那么它的时钟周期就是1000 us,如果高电平出现的时间是200 us,那么低电平的时间肯定是800 us,那么PWM的占空比就是200 : 1000,也就是1 : 5
分辨率:就是占空比最小能达到多少。如8位的PWM,理论的分辨率就是1:255(单斜率),16位的的PWM理论就是1 : 65535(单斜率)。可见,双斜率的计数时间多了一倍,所以输出的PWM频率就慢了一半,但是分辨率却是1:(80+80) =1 :160,就是提高了一倍。
双斜率/单斜率:假设一个PWM从0计数到80,之后又从0计数到80,这个就是单斜率;一个PWM从0计数到80,之后从80计数到0,这个就是双斜率
PWM由定时器驱动,定时器的周期就是PWM的周期,为了控制高低电平的比例,会在定时器的基础上加上一个比较寄存器,同时需要和GPIO口集合输出PWM波
PWM波的高低电平的顺序是由极性,PWM模式和计数模式共同决定。极性决定有效电平(默认电平),PWM模式指的是一个周期内有效电平和无效电平的顺序。
LED PWM控制器
LED_PWM 主要用于控制 LED 的亮度和颜色,也可以产生 PWM 信号用于其他用途。LED_PWM 有16路通道, 即8路高速通道和8路低速通道。PWM 控制器还能够自动逐渐增加或减少占空比,LED_PWM 还支持小数分频。
下面是LED_PWM基本架构图 高速通道和低速通道各有4个时钟模块,可以从中任选一个 h/l_timerx
低速通道的分频器相对于高速通道的分频器来说有以下 2 点区别
- 高速定位器的时钟源采用了 REF_TICK 或 APB_CLK,低速定位器采用了 REF_TICK 或 SLOW_CLOCK。(置位 LEDC_APB_CLK_SEL 寄存器, SLOW_CLOCK 的频率为 80 MHz,否则为 8 MHz。)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e8FFtNar-1647928339609)(C:\Users\SNKjxn\AppData\Roaming\Typora\typora-user-images\image-20220106165924752.png)]
- 当修改了高速通道计数器的最大值或分频系数时,输出信号的更新将会在下一次溢出中断之后生效。而低速通道在置位 LEDC_LSTIMERx_PARA_UP之后,立刻更新计数器的计数范围参数和分频器的分频系数。
常用配置频率及精度
主要函数
ledc_channel_config()
LEDC 通道配置
esp_err_t ledc_channel_config (const ledc_channel_config_t* ledc_conf)
ledc_channel_config_t typedef struct{
int gpio_num;
ledc_mode_t speed_mode; //速度
ledc_channel_t channel; //通道
ledc_intr_type_t intr_type; //中断使能
ledc_timer_t timer_sel; //定时器通道
uint32_t duty; //占空比
}ledc_channel_config_t;
ledc_fade_func_install()
安装 LEDC 淡入淡出功能
esp_err_t ledc_fade_func_install(int intr_alloc_flags)
/*
intr_alloc_flags: 用于分配中断的标志
*/
ledc_set_fade_with_time()
有时间限制的设置LEDC淡入淡出功能
esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int max_fade_time_ms)
/*
speed_mode: 选择指定速度模式的 LEDC 通道组
channel: LEDC 通道号,从 ledc_channel_t 中选择
target_duty: 衰落的目标占空比
max_fade_time_ms:衰落的最大时间(毫秒)
*/
ledc_fade_start()
开始LED渐变
esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_fade_mode_t fade_mode)
/*
speed_mode: 选择指定速度模式的 LEDC 通道组
channel: LEDC 通道号
fade_mode: 是否阻塞直到淡入淡出完成
*/
LED呼吸灯代码
//定义配置PWM的结构体
ledc_channel_config_t ledc_channel_R, ledc_channel_G, ledc_channel_B;
void LEDC_Init(void)
{
//定时器配置结构体
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_13_BIT, // PWM占空比分辨率(1~15)
.freq_hz = 5000, // PWM信号频率
.speed_mode = LEDC_HS_MODE, // 定时器模式(速度模式)
.timer_num = LEDC_HS_TIMER // 定时器序号(LEDC_TIMER_0)
};
ledc_timer_config(&ledc_timer); // 设置定时器 PWM 模式
//配置ledc_channel_R
ledc_channel_R.channel = LEDC_HS_CH0_CHANNEL; // PWM 通道0
ledc_channel_R.duty = 0; // 占空比为0
ledc_channel_R.gpio_num = LEDC_HS_CH0_GPIO; // IO 映射(GPIO18)
ledc_channel_R.speed_mode = LEDC_HS_MODE; // 定时器模式(速度模式)
ledc_channel_R.timer_sel = LEDC_HS_TIMER; // 定时器序号(LEDC_TIMER_0)
ledc_channel_config(&ledc_channel_R); //配置 PWM
//配置ledc_channel_G
ledc_channel_G.channel = LEDC_HS_CH1_CHANNEL; // PWM 通道0
ledc_channel_G.duty = 0; // 占空比为0
ledc_channel_G.gpio_num = LEDC_HS_CH1_GPIO; // IO 映射(GPIO18)
ledc_channel_G.speed_mode = LEDC_HS_MODE; // 定时器模式(速度模式)
ledc_channel_G.timer_sel = LEDC_HS_TIMER; // 定时器序号(LEDC_TIMER_0)
ledc_channel_config(&ledc_channel_G); //配置 PWM
//配置ledc_channel_B
ledc_channel_B.channel = LEDC_HS_CH2_CHANNEL; // PWM 通道0
ledc_channel_B.duty = 0; // 占空比为0
ledc_channel_B.gpio_num = LEDC_HS_CH2_GPIO; // IO 映射(GPIO18)
ledc_channel_B.speed_mode = LEDC_HS_MODE; // 定时器模式(速度模式)
ledc_channel_B.timer_sel = LEDC_HS_TIMER; // 定时器序号(LEDC_TIMER_0)
ledc_channel_config(&ledc_channel_B); //配置 PWM
// 使能 ledc 渐变
ledc_fade_func_install(0);
}
void app_main()
{
LEDC_Init();
while (1)
{
printf("1. PWM逐渐变大的周期目标 = %d\n", LEDC_TEST_DUTY);
// ledc 渐变至 100%,时间 LEDC_TEST_FADE_TIME
ledc_set_fade_with_time(ledc_channel_R.speed_mode, ledc_channel_R.channel,
LEDC_TEST_DUTY,
LEDC_TEST_FADE_TIME);
ledc_fade_start(ledc_channel_R.speed_mode,
ledc_channel_R.channel,
LEDC_FADE_NO_WAIT);
vTaskDelay(LEDC_TEST_FADE_TIME / portTICK_PERIOD_MS); //延时3秒
// ledc 渐变至 100%,时间 LEDC_TEST_FADE_TIME
ledc_set_fade_with_time(ledc_channel_G.speed_mode,
ledc_channel_G.channel,
LEDC_TEST_DUTY,
LEDC_TEST_FADE_TIME);
ledc_fade_start(ledc_channel_G.speed_mode,
ledc_channel_G.channel,
LEDC_FADE_NO_WAIT);
vTaskDelay(LEDC_TEST_FADE_TIME / portTICK_PERIOD_MS); //延时3秒
// ledc 渐变至 100%,时间 LEDC_TEST_FADE_TIME
ledc_set_fade_with_time(ledc_channel_B.speed_mode,
ledc_channel_B.channel,
LEDC_TEST_DUTY,
LEDC_TEST_FADE_TIME);
ledc_fade_start(ledc_channel_B.speed_mode,
ledc_channel_B.channel,
LEDC_FADE_NO_WAIT);
vTaskDelay(LEDC_TEST_FADE_TIME / portTICK_PERIOD_MS); //延时3秒
printf("2. PWM逐渐变小的周期目标 = 0\n");
// ledc 渐变至 0%,时间 LEDC_TEST_FADE_TIME
ledc_set_fade_with_time(ledc_channel_R.speed_mode,
ledc_channel_R.channel,
0,
LEDC_TEST_FADE_TIME);
ledc_fade_start(ledc_channel_R.speed_mode,
ledc_channel_R.channel,
LEDC_FADE_NO_WAIT);
vTaskDelay(LEDC_TEST_FADE_TIME / portTICK_PERIOD_MS); //延时3秒
// ledc 渐变至 0%,时间 LEDC_TEST_FADE_TIME
ledc_set_fade_with_time(ledc_channel_G.speed_mode,
ledc_channel_G.channel,
0,
LEDC_TEST_FADE_TIME);
ledc_fade_start(ledc_channel_G.speed_mode,
ledc_channel_G.channel,
LEDC_FADE_NO_WAIT);
vTaskDelay(LEDC_TEST_FADE_TIME / portTICK_PERIOD_MS); //延时3秒
// ledc 渐变至 0%,时间 LEDC_TEST_FADE_TIME
ledc_set_fade_with_time(ledc_channel_B.speed_mode,
ledc_channel_B.channel,
0,
LEDC_TEST_FADE_TIME);
ledc_fade_start(ledc_channel_B.speed_mode,
ledc_channel_B.channel,
LEDC_FADE_NO_WAIT);
vTaskDelay(LEDC_TEST_FADE_TIME / portTICK_PERIOD_MS); //延时3秒
}
}
MCPWM篇(电机控制PWM)
ESP32 有两个 MCPWM 单元,可用于控制不同类型的电机。每个单元具有三对 PWM 输出。
下面是MCPWM的详细框图,每个 A/B 对可由三个定时器 Timer 0、1 和 2 中的任何一个提供时钟。同一个定时器可用于为一对以上的 PWM 输出提供时钟。每个单元还能够收集输入,例如检测电机过电流或过电压
|