我是靠谱客的博主 沉静天空,这篇文章主要介绍启明智显分享| ESP32学习笔记参考--PWM(脉冲宽度调制) 篇,配PWM控制 LED呼吸灯代码示例参考,现在分享给大家,希望可以做个参考。

提示:启明智显专为智能产品提供一站式彩屏显示+连接+云端服务+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 点区别

  1. 高速定位器的时钟源采用了 REF_TICK 或 APB_CLK,低速定位器采用了 REF_TICK 或 SLOW_CLOCK。(置位 LEDC_APB_CLK_SEL 寄存器, SLOW_CLOCK 的频率为 80 MHz,否则为 8 MHz。)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e8FFtNar-1647928339609)(C:UsersSNKjxnAppDataRoamingTyporatypora-user-imagesimage-20220106165924752.png)]
  2. 当修改了高速通道计数器的最大值或分频系数时,输出信号的更新将会在下一次溢出中断之后生效。而低速通道在置位 LEDC_LSTIMERx_PARA_UP之后,立刻更新计数器的计数范围参数和分频器的分频系数。

常用配置频率及精度

在这里插入图片描述

主要函数

ledc_channel_config()

LEDC 通道配置

复制代码
1
2
3
4
5
6
7
8
9
10
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 淡入淡出功能

复制代码
1
2
3
4
5
esp_err_t ledc_fade_func_install(int intr_alloc_flags) /* intr_alloc_flags: 用于分配中断的标志 */

ledc_set_fade_with_time()

有时间限制的设置LEDC淡入淡出功能

复制代码
1
2
3
4
5
6
7
8
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渐变

复制代码
1
2
3
4
5
6
7
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呼吸灯代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/ledc.h" #include "esp_err.h" #define LEDC_HS_TIMER LEDC_TIMER_0 //定时器序号(LEDC_TIMER_0) #define LEDC_HS_MODE LEDC_HIGH_SPEED_MODE // 定时器模式(高速模式) #define LEDC_HS_CH0_GPIO 2 // IO 映射(GPIO2) #define LEDC_HS_CH0_CHANNEL LEDC_CHANNEL_0 // PWM 通道0 #define LEDC_HS_CH1_GPIO 18 // IO 映射(GPIO18) #define LEDC_HS_CH1_CHANNEL LEDC_CHANNEL_1 // PWM 通道1 #define LEDC_HS_CH2_GPIO 19 // IO 映射(GPIO19) #define LEDC_HS_CH2_CHANNEL LEDC_CHANNEL_2 // PWM 通道2 #define LEDC_TEST_DUTY 8000 //渐变变大的最终目标的占空比 #define LEDC_TEST_FADE_TIME 3000 //变化时长3秒 //定义配置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逐渐变大的周期目标 = %dn", 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逐渐变小的周期目标 = 0n"); // 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 输出提供时钟。每个单元还能够收集输入,例如检测电机过电流或过电压

在这里插入图片描述

最后

以上就是沉静天空最近收集整理的关于启明智显分享| ESP32学习笔记参考--PWM(脉冲宽度调制) 篇,配PWM控制 LED呼吸灯代码示例参考的全部内容,更多相关启明智显分享|内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(88)

评论列表共有 0 条评论

立即
投稿
返回
顶部