测试说明一下 CH58x 芯片 PWM 输出功能 ...... 矜辰所致 ...... 增加补充说明 2026/4/16前言
今天轻松一下,来测试一个基础的 PWM 输出功能,在 CH58x 芯片上,除了定时器可以产生 PWM 输出,芯片还提供了单独的 PWM 控制器。
本文我们主要来测试说明一下定时器和 PWM 控制器如何输出 PWM 波。
相关文章:
沁恒微 RISC-V 蓝牙 CH5xx GPIO使用说明
.
系列文章目录:
【导航】沁恒微 RISC-V 蓝牙 入门教程目录 【快速跳转】
.
我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!
目录
- 前言
- 一、 基础介绍
- 二、 定时器 PWM 输出
- 2.1 示例说明
- 2.2 CH585 定时器 PWM 最大频率
- 2.3 定时器使用 DMA 输出 PWM
- 三、PWM 控制器输出
- 四、补充说明
- 4.1 引脚对应
- 4.2 两种方式区别
- 结语
一、 基础介绍
PWM 波(Pulse Width Modulation,脉冲宽度调制)。
基础的东西不过多赘述,对于应用而言,我们需要关注的是 PWM 的两个重要的参数:
- 占空比
- 周期
这两个指标关系到我们程序中需要指定修改的参数,当然还有其他比如分辨率,在下文介绍 PWM 控制器会有说明 。
另外提一下 PWM 波的典型应用 — “模拟” 模拟量,利用惯性系统(电机、人眼、电容)的积分效应:
- 电机:电感电流不能突变 → 平均电压 ∝ 占空比
- 人眼:视觉暂留 → 亮度 ∝ 占空比
- 电容:RC 滤波 → 直流电压 ∝ 占空比
二、 定时器 PWM 输出
关于通用定时器芯片手册有如下说明:
芯片提供了4 个26 位定时器,TMR0、TMR1、TMR2 和TMR3,最长定时时间为2^26 个时钟周期。它适用于多种场合,包括测量输入信号脉冲长度(输入捕捉)或者产生输出波形(PWM),支持 DMA 功能。每个定时器都是完全独立的,可以一起同步操作。
CH585 的4个定时器都可以输出 PWM 波。
2.1 示例说明
在官方 EVT 中,提供了定时器使用的示例TMR:
里面关于 PWM 输出的代码示例为:
#defineg_10us(FREQ_SYS/100000)...#if1/* 定时器3,PWM输出 */GPIOB_ResetBits(GPIO_Pin_22);// 配置PWM口 PB22GPIOB_ModeCfg(GPIO_Pin_22,GPIO_ModeOut_PP_5mA);TMR3_PWMInit(High_Level,PWM_Times_1);TMR3_PWMCycleCfg(g_10us*10);// 周期 100us 最大67108864TMR3_PWMActDataWidth(g_10us/2*10);// 占空比 50%, 修改占空比必须暂时关闭定时器TMR3_PWMEnable();TMR3_Enable();#endif测试效果如下:
我们在应用中,直接按照示例格式使用即可,其中我们要修改的地方就是控制 周期 和 占空比 的两句代码。
周期设置是TMR3_PWMCycleCfg函数中的参数 :
周期= 参数 / 系统主频 (秒)
占空比是TMR3_PWMActDataWidth函数中的参数:
占空比 = 参数 / 周期
只要会设置这两个参数就可以根据需求设置自己想要的 PWM了。
2.2 CH585 定时器 PWM 最大频率
在CH585 上,可以达到 25MHz:
设置如下:
SetSysClock(CLK_SOURCE_HSE_PLL_78MHz);TMR3_PWMCycleCfg(3);// 周期 125us 最大67108864TMR3_PWMActDataWidth(1);// 占空比 20%, 修改占空比必须暂时关闭定时器2.3 定时器使用 DMA 输出 PWM
此小节博主自己没有测试,推荐博文连接如下:
https://www.cnblogs.com/gscw/p/17679057.html
三、PWM 控制器输出
关于 PWM 控制器 ,官方手册有如下说明 :
除了定时器提供的4路26位PWM输出之外,系统还提供了8路 8 位PWM输出(PWM4~PWM11)或 6 路16位 PWM输出(PWM4~PWM9),占空比可调,PWM 周期固定可选8种周期,操作简单。
在官方 EVT 中,提供了定时器使用的示例PWMX:
使用起来也是及其简单,我们只测试一路,示例如下:
GPIOB_ModeCfg(GPIO_Pin_0,GPIO_ModeOut_PP_5mA);// PB0 - PWM6PWMX_CLKCfg(4);// cycle = 4/FsysPWMX_CycleCfg(PWMX_Cycle_64);// 周期 = 64*cyclePWMX_ACTOUT(CH_PWM6,64/4,Low_Level,ENABLE);// 25% 占空比测试结果:
同样的,我们可以看一下周期和占空比如何设置,看看上面这个周期和占空比是怎么来的:
周期设置是PWMX_CLKCfg和PWMX_CycleCfg同时设置的:
首先通过
PWMX_CLKCfg设置通道基准时钟:
基准时钟 = 参数 / 系统主频
然后通过PWMX_CycleCfg设置 PWM 周期:
周期 = 参数 * 基准时钟 (秒)
在使用 8 位 PWM 的时候,PWMX_CycleCfg只能选择如下几种:
typedef enum
{
PWMX_Cycle_256 = 0, // 256 个PWMX周期
PWMX_Cycle_255, // 255 个PWMX周期
PWMX_Cycle_128, // 128 个PWMX周期
PWMX_Cycle_127, // 127 个PWMX周期
PWMX_Cycle_64, // 64 个PWMX周期
PWMX_Cycle_63, // 63 个PWMX周期
} PWMX_CycleTypeDef;
.
我们可以算一下上面 4.11 us 的由来,周期计算如下:
64 * 4 * (1/62400000)s ≈ 4.102 us
占空比是PWMX_ACTOUT函数中的第二个参数:
占空比 = 第二个参数 / 周期
同样,只要会设置这两个参数就可以根据需求设置自己想要的 PWM了。
但是因为 PWM 控制器的分辨率有限,所以有些波形并不能完全对应上,会有误差,比如说我们实现一个 8KHZ 的PWM 波形,我们可以知道我们需要把周期定义位 125us 。
我们近似可以如下设置:
为了进一步的设置准确的周期,我们可以使用 16 位的 PWM ,使用示例如下:
与 8 位 PWM 相比,只是有2个设置的函数不一样,周期设置的参数不再局限固定的几个值,可以自行在 16 位范围内设置,周期和占空比设置的计算方式都是一样的:
PWMX_16bit_CycleCfg(60-1);// 16位数据宽度Ncyc=RB_PWM_CYC_VALUE+1PWMX_16bit_ACTOUT(CH_PWM6,12,Low_Level,ENABLE);// 20% 占空比 60/5四、补充说明
4.1 引脚对应
目前只列举 CH585/CH584,其他型号自行查看手册
定时器 PWM 输出 IO:
| PWM 引脚 | 功能 |
|---|---|
| PA9 | 定时器0 捕捉输入0 / PWM 输出通道0 |
| PA10 | 定时器1 捕捉输入1 / PWM 输出通道1 |
| PA11 | 定时器2 捕捉输入2 / PWM 输出通道2 |
| PB22 | 定时器3 捕捉输入3 / PWM 输出通道3 |
PWM 控制器输出 IO (映射引脚没有标明,实在需要用到自行查看手册):
| PWM 引脚 | 功能 |
|---|---|
| PA12 | PWM4:脉宽调制输出通道4 |
| PA13 | PWM5:脉宽调制输出通道5 |
| PB0 | PWM6:脉宽调制输出通道6 |
| PB4 | PWM7:脉宽调制输出通道7 |
| PB6 | PWM8:脉宽调制输出通道8 |
| PB7 | PWM9:脉宽调制输出通道9 |
| PB14 | PWM10:脉宽调制输出通道10 |
| PB23 | PWM11:脉宽调制输出通道11 (复用为外部复位脚,需关闭复位功能才能使用 ) |
4.2 两种方式区别
概括来说:
定时器 PWM 灵活精细,适合通用控制;
PWM 控制器是专用工具,频率和分辨率受限,但部分场景有优势,比如某些电机电源控制场景。
定时器 PWM 是 26位 PWM ,频率高,可任意分频,更加灵活,适合通用、精细控制。
PWM 控制器是 8 位/16 位的,评论低,频率固定 / 粗分频,档位有限, 硬件自带互补输出,也方便多路同步,适合电源,电机等特定场景。
结语
本文我们了解了 CH58x 芯片如何输出 PWM 波,整体来说是很简单的,只需要知道如何计算 周期 和占空比,就可以实现自己想要的输出。
好了,本文就到这里。谢谢大家!