ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

STM32C5A3R输出PWM完整开发流程:定时器配置、频率与占空比在线调整

STM32C5A3R输出PWM完整开发流程:定时器配置、频率与占空比在线调整 这次我们来看 STM32C5A3R 输出 PWM 的完整开发流程。很多初学者拿到一款新 MCU第一步就是点灯第二步往往就是输出 PWM。PWM 这个东西在嵌入式里太常用了电机调速、舵机控制、LED 调光、蜂鸣器发声、DAC 波形拟合、PWM 触发 ADC 采样全都靠它。STM32C5A3R 作为 ST 新一代 Cortex-M33 内核 MCU定时器资源丰富输出 PWM 的方式和传统 STM32 系列基本一致但时钟树、CubeMX 配置界面、部分 HAL 库细节有差异值得单独写一篇。这篇教程默认你已经会使用 STM32CubeMX 创建工程重点会覆盖三件事第一怎么用定时器输出 PWM第二怎么修改 PWM 频率第三怎么在线修改占空比。同时会把 CubeMX 的配置步骤、HAL 库代码、运行时动态修改参数的几种写法、以及常见踩坑点全部过一遍。文章末尾还会给出 PWM 触发 ADC 采样、与 DMA 配合、电机控制等扩展方向方便你做项目时直接参考。1. 核心能力速览能力项说明项目类型STM32 嵌入式外设开发教程主控芯片STM32C5A3RCortex-M33 内核主频 250MHz开发方式STM32CubeMX 图形化配置 HAL 库编程核心功能定时器 PWM 输出、在线修改频率、在线修改占空比主要接口定时器通道 GPIO 输出可扩展至多通道互补 PWM调试工具ST-Link / J-Link串口打印辅助验证验证手段示波器、逻辑分析仪、LED 亮度变化、蜂鸣器音调变化批量任务支持可通过修改数组/查表方式批量输出不同频率和占空比扩展能力PWM 触发 ADC、DMA 搬运、电机控制、舵机控制、软件模拟 DAC适合场景电机驱动、电源控制、信号发生、音频提示、PWM 采样触发从材料看STM32C5A3R 的开发流程和传统 STM32 类似核心是通过 CubeMX 配置定时器生成初始化代码后调用 HAL 库函数启动 PWM 输出。实际代码量不大关键是理解PSC预分频器、ARR自动重载值、CCR比较值这三个寄存器的关系。2. 适用场景与使用边界PWM 输出在嵌入式项目里属于基础外设能力几乎每个用 MCU 的项目都会涉及。具体到 STM32C5A3R适合以下几类场景电机调速直流电机、无刷电机、步进电机驱动中PWM 是核心控制信号。通过修改占空比可以控制电机转速通过调整频率可以匹配驱动器的开关特性。舵机控制舵机需要 50Hz 左右的周期信号通过修改脉宽即占空比的变化量控制舵机角度。这种情况下我们更关心的是脉宽时间而不是占空比百分比。LED 调光与呼吸灯用 PWM 控制 LED 亮度人眼对高频闪烁不敏感通常 1kHz 以上就感觉不到闪烁。蜂鸣器发声通过修改 PWM 频率可以控制蜂鸣器音调产生不同频率的提示音甚至可以播放简单旋律。DAC 波形拟合MCU 内部没有 DAC 时可以用 PWM 加 RC 低通滤波器输出模拟电压。频率越高纹波越小但分辨率会随之降低需要根据项目需求权衡。PWM 触发 ADC 采样热词中专门提到了pwm触发adc采样。在电机控制和开关电源场景中需要让 ADC 在 PWM 周期的特定时刻采样避免采样到开关噪声。可以利用定时器触发 ADC 的方式实现和 PWM 同步的采样。不适用或者要谨慎使用的场景包括高精度音频输出PWM 直出音频会有量化噪声需要高阶滤波、微秒级精度的信号发生中断响应延迟会影响抖动、以及对电磁干扰要求极高的工业现场PWM 开关噪声需要外部滤波和屏蔽设计。另外一个必须强调的边界如果你用 PWM 控制电机、加热器、激光器等大功率设备一定要做好驱动隔离和功率保护电路不要直接用 MCU 引脚驱动大负载。涉及商用产品或发布开源项目时也要确认硬件设计符合相关安全规范。3. 环境准备与前置条件开始之前确认你的开发环境已经具备以下条件。硬件准备STM32C5A3R 开发板或者自制的最小系统板。注意确认板上晶振频率和供电方式CubeMX 配置时钟树时需要知道外部高速晶振 HSE 的频率。ST-Link V2 或 J-Link 调试器用于下载和调试程序。示波器或逻辑分析仪。没有示波器的话也可以先用 LED 观察亮度变化、用蜂鸣器听音调变化但测不了实际频率值。杜邦线和面包板用于连接外部器件。软件准备STM32CubeMX建议使用比较新的版本。新版本对 STM32C5 系列的支持更完整。STM32CubeIDE或者你习惯的 Keil MDK / IAR。STM32CubeMX 生成的工程可以直接导入 STM32CubeIDE。STM32C5 系列的固件包。CubeMX 第一次选择 STM32C5 芯片时如果提示缺少固件包需要在 Help 菜单中安装或者从 ST 官网下载后手动导入。串口调试助手用于接收 printf 打印信息。通用检查清单CubeMX 能识别你的芯片型号搜索STM32C5A3R能找到对应型号。调试器驱动安装正常在设备管理器里能看到 ST-Link 或 J-Link 设备。开发板的 BOOT 引脚配置正确能进入正常启动模式。开发板供电正常Core 电压和 IO 电压满足芯片要求。4. 创建 CubeMX 工程并配置定时器 PWM下面正式操作。以 STM32CubeMX 为例新建工程并配置定时器输出 PWM。4.1 新建工程并选择芯片打开 STM32CubeMX点击New Project在搜索框输入STM32C5A3R选择对应芯片后双击新建工程。如果固件包缺失按提示安装。4.2 配置时钟树进入System Core RCC将 HSE 设置为Crystal/Ceramic Resonator外部晶振也就是BYPass相关选项要根据你的板子设计来选。一般开发板会板载 8MHz 或 25MHz 晶振以实际原理图为准。然后进入Clock Configuration页面配置系统时钟。STM32C5 系列主频可以跑到 250MHz。配置方法通常是为 AHB 总线和 APB 总线选择合适的预分频让定时器时钟达到目标值。这里要注意定时器的时钟源不一定等于系统主频很多 STM32 系列中 APB1 定时器时钟是 APB1 的两倍。具体到 STM32C5以 CubeMX 的时钟树页面提示为准。PWM 频率的计算公式为PWM频率 定时器时钟 / ((PSC 1) * (ARR 1))所以在配置时钟树时先确定定时器时钟是多少后面配置 PSC 和 ARR 就有依据了。4.3 配置定时器以 TIM1 为例它属于高级定时器可以输出互补 PWM适合电机控制。如果只是做简单的 PWM 输出用通用定时器 TIM2/TIM3/TIM4 都可以。在左侧Timers中选择 TIM1进入配置页面Clock Source选择Internal Clock。Channel1选择PWM Generation CH1。如果你需要通道 2也可以把Channel2打开。在Parameter Settings中设置Prescaler预分频值、Counter Period自动重载值 ARR、Pulse比较值 CCR、Auto-reload preload建议使能这样修改 ARR 时会等当前计数周期结束后才生效避免波形撕裂。Pulse的初始值可以随便设后续在代码里修改。具体参数计算示例假设定时器时钟为 250MHz想要输出 1kHz 的 PWM设置 PSC 为 249那么定时器计数频率就是 1MHz再设置 ARR 为 999最终 PWM 频率就是 1kHz。占空比如果要 50%就把 Pulse 设为 500。PSC 249 ARR 999 Pulse 500 PWM频率 250MHz / ((249 1) * (999 1)) 1kHz 占空比 500 / (999 1) * 100% 50%如果你的应用需要 20kHz 的 PWM 频率比如电机驱动常用的频率可以保持 PSC 为 0 或很小ARR 设小一点。这个公式很重要后面改频率和占空比全靠它。4.4 配置 GPIO 引脚定时器通道对应的 GPIO 会在 CubeMX 中自动分配。以 TIM1_CH1 为例引脚会自动映射到某个 PA 或 PB 引脚具体要看芯片型号和封装。建议进入System Core GPIO确认引脚模式是否为Alternate Function Push Pull同时可以设置初始输出电平和 GPIO 速度。注意一个问题同一个引脚可能会有多个定时器通道复用选项CubeMX 自动分配的不一定是你想要的。如果引脚冲突可以手动在芯片图上点击引脚重新选择复用功能。4.5 生成工程代码时钟、定时器、GPIO 都配置好后在Project Manager中设置工程名称、保存路径、IDE 类型STM32CubeIDE 或 MDK-ARM然后点击Generate Code。生成完成后打开工程。5. HAL 库代码启动 PWM 与修改频率占空比5.1 启动 PWM 输出CubeMX 生成的代码中MX_TIM1_Init()已经完成了定时器初始化。要输出 PWM还需要在主函数中调用HAL_TIM_PWM_Start()。int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM1_Init(); // 启动 TIM1 通道1 PWM 输出 HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_1); while (1) { // 主循环 } }如果是高级定时器 TIM1/TIM8并且需要输出互补 PWM还需要额外调用HAL_TIMEx_PWMN_Start()启动互补通道。// 启动互补通道输出 HAL_TIMEx_PWMN_Start(htim1, TIM_CHANNEL_1);这时用示波器测量对应引脚应该能看到 PWM 波形。频率和占空比就是 CubeMX 中设置的初始值。5.2 在运行时修改占空比项目里很少有用固定占空比的更多是动态调整。设置占空比的核心操作是修改定时器的比较寄存器 CCRHAL 库提供了底层的宏// 设置 TIM1 通道1 的比较值为 300 __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, 300);假如 ARR 为 999比较值设为 300占空比就是 30.03%。比较值从 0 到 ARR 线性变化占空比从 0% 到 100%。对于呼吸灯这种渐变效果可以在主循环里让比较值逐步增加再逐步减小uint16_t pulse 0; uint8_t direction 1; while (1) { __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, pulse); if (direction) { pulse 5; if (pulse 999) direction 0; } else { pulse - 5; if (pulse 0) direction 1; } HAL_Delay(5); }这样灯就会逐渐变亮再逐渐变暗形成呼吸效果。注意pulse不要超过 ARR 值否则占空比会到 100% 后饱和。5.3 在运行时修改 PWM 频率修改频率比修改占空比稍微麻烦一些需要同时调整预分频器 PSC 或自动重载值 ARR。方法一固定 PSC修改 ARR。这种方式适合小范围调频。保持 PSC 不变只改 ARR频率随之变化但要注意 ARR 变化会导致最大占空比的分母变化所以如果同时要保持占空比需要同步修改 CCR。// 修改 ARR 为 1999频率变为之前的一半 __HAL_TIM_SET_AUTORELOAD(htim1, 1999); // 同步修改比较值保持占空比 30% __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, 600);方法二固定 ARR修改 PSC。这种方式适合分辨率要求不高的场景。因为修改 PSC 会立即改变计数频率如果 ARR 不变占空比的百分比不会变CCR 也没变但实际脉宽时间会变化。// 修改 PSC 为 499计数器频率变为原来的 1/2 __HAL_TIM_SET_PRESCALER(htim1, 499); // 此时不需要修改 CCR占空比百分比保持不变方法三同时修改 PSC 和 ARR。这种方式最灵活适合需要任意频率输出的场景。先确定目标频率再根据公式反推参数。void set_pwm_frequency(TIM_HandleTypeDef *htim, uint32_t channel, uint32_t freq_hz, uint32_t duty_percent) { uint32_t timer_clock HAL_RCC_GetPCLK1Freq(); // 实际需要根据定时器所在总线调整 uint32_t psc, arr, ccr; // 先设 PSC让计数频率在合理范围然后计算 ARR psc 1; // 这里简化处理实际项目中需要先确定分辨率再计算 arr timer_clock / ((psc 1) * freq_hz) - 1; ccr (arr 1) * duty_percent / 100; __HAL_TIM_SET_PRESCALER(htim, psc); __HAL_TIM_SET_AUTORELOAD(htim, arr); __HAL_TIM_SET_COMPARE(htim, channel, ccr); }需要注意的是修改 PSC 或 ARR 时如果Auto-reload preload已经使能修改会等当前计数周期结束才生效这样可以避免输出脉冲宽度不一致的情况。这对于电机控制等场景很重要否则可能产生一个异常宽的脉冲导致电机抖动。5.4 离线计算 查表方式如果应用需要输出一组固定的频率点比如播放旋律可以用查表法。提前算好每个音符对应的 PSC/ARR 值存放在数组中。程序里按顺序加载这些值并延时播放就可以实现简单的音乐播放功能。这种方法对 CPU 占用极小适合与其它实时任务并发执行。typedef struct { uint16_t psc; uint16_t arr; uint16_t duration_ms; } note_t; const note_t melody[] { {1, 1136, 300}, // 约 110Hz {1, 758, 300}, // 约 165Hz {1, 568, 300}, // 约 220Hz }; void play_melody(void) { for (int i 0; i sizeof(melody) / sizeof(melody[0]); i) { __HAL_TIM_SET_PRESCALER(htim1, melody[i].psc); __HAL_TIM_SET_AUTORELOAD(htim1, melody[i].arr); HAL_Delay(melody[i].duration_ms); } }查表法还可以用于电机加速曲线、PWM 渐变调光等场景把计算的复杂度前置到编译期运行时代码更简单、更稳定。6. 模块化封装把 PWM 控制做成通用接口实际项目中PWM 控制很少只在一个文件里用。建议把频率设置和占空比设置封装成独立函数放到单独的pwm_control.c/pwm_control.h中。这样主循环、定时器中断、串口命令处理、或者 RTOS 任务都可以复用。下面是一个简单的封装示例/* pwm_control.h */ #ifndef PWM_CONTROL_H #define PWM_CONTROL_H #include main.h void pwm_init(TIM_HandleTypeDef *htim, uint32_t channel); void pwm_set_duty(TIM_HandleTypeDef *htim, uint32_t channel, uint8_t percent); void pwm_set_freq(TIM_HandleTypeDef *htim, uint32_t channel, uint32_t freq_hz, uint8_t percent); #endif/* pwm_control.c */ #include pwm_control.h void pwm_init(TIM_HandleTypeDef *htim, uint32_t channel) { HAL_TIM_PWM_Start(htim, channel); } void pwm_set_duty(TIM_HandleTypeDef *htim, uint32_t channel, uint8_t percent) { uint32_t arr __HAL_TIM_GET_AUTORELOAD(htim); uint32_t ccr arr * percent / 100; __HAL_TIM_SET_COMPARE(htim, channel, ccr); } void pwm_set_freq(TIM_HandleTypeDef *htim, uint32_t channel, uint32_t freq_hz, uint8_t percent) { // 简化示例以 1MHz 计数频率为基准PSC 固定为某个值 #define TIMER_COUNT_CLOCK (1000000U) // 1MHz uint32_t arr TIMER_COUNT_CLOCK / freq_hz - 1; uint32_t ccr (arr 1) * percent / 100; __HAL_TIM_SET_AUTORELOAD(htim, arr); __HAL_TIM_SET_COMPARE(htim, channel, ccr); }这个封装方式的核心思想是外部只关心“频率是多少 Hz、占空比是多少 %”不需要关心寄存器怎么算。如果后续换芯片只需要改底层实现上层调用不变。这种分层方式在项目代码维护中非常实用。当然上面代码里的TIMER_COUNT_CLOCK只是一个简化的假设实际项目中应该根据定时器时钟和分频情况计算。更稳妥的做法是在初始化时固定 PSC后续只调整 ARR 和 CCR这样计算量更小、行为更可控。如果做串口命令控制可以把串口接收到的数据解析成频率值和占空比值然后调用上述封装函数实现一个简单的上位机调参工具。这种方案在调试电机参数时非常有用比每次改代码重新烧录效率高得多。7. PWM 频率与占空比的精度和性能观察7.1 分辨率与频率的关系PWM 输出有一个不可忽视的权衡频率越高占空比分辨率越低。以 250MHz 定时器时钟为例PWM 频率ARR 值占空比分辨率1kHz2499990.0004%10kHz249990.004%100kHz24990.04%1MHz2490.4%从表格可以看出1kHz 时占空比步进非常精细适合高精度调光或模拟输出。但 1MHz 时只有 250 级可调对精度要求高的场景就不够用了。所以在设计时需要先确定频率再评估分辨率是否满足要求。如果分辨率和频率无法同时满足可以考虑使用定时器更高的工作时钟或者采用更高时钟频率的 MCU 型号再或者用多个定时器并联的方式扩展分辨率。7.2 修改频率时的波形连续性动态修改 ARR 时如果关闭了预装载新的 ARR 值会立即生效可能导致当前正在输出的脉冲宽度异常。在电机控制中这会产生额外的噪声和转矩脉动。推荐在整个项目周期内保持Auto-reload preload使能让 ARR 更新发生在计数周期边界。同样修改 PSC 时也要注意PSC 也有预装载机制。HAL 库的__HAL_TIM_SET_PRESCALER()宏会处理预装载寄存器的写入实际生效时间取决于硬件配置。7.3 CPU 占用与中断开销PWM 输出本身不需要 CPU 干预硬件定时器独立运行这也是 PWM 适合做实时控制的原因。但如果需要在 PWM 周期基础上做逻辑处理比如每个周期更新一次占空比可以用定时器更新中断或比较中断。使用中断时要注意中断频率不能太高。假设 PWM 频率为 20kHz开启更新中断后每 50 微秒进入一次中断在 250MHz 主频下可以做很多事但如果中断处理函数里执行了复杂的浮点运算或者 HAL_Delay就会拖慢主循环甚至导致中断溢出。更低开销的做法是使用 DMA 更新比较值。比如预先生成一个比较值数组用定时器更新事件触发 DMA把数组里的值逐个搬运到 CCR 寄存器实现波形序列输出。这在电机控制的 SVPWM 算法中很常见。如果项目里使用 STM32C5 的 CORDIC 或数学加速单元配合 DMA 可以进一步降低 CPU 负载。7.4 资源占用观察从工程角度看多路 PWM 输出会占用多个定时器和多个引脚。STM32C5A3R 的定时器资源比较丰富但每个定时器的通道数量有限如果项目需要同时输出很多路 PWM就要提前规划好定时器分配避免后期引脚冲突。另外PWM 的 GPIO 速度设置会影响波形上升沿和下降沿的陡峭程度。对高速 PWM可以设置 GPIO 速度为Very High但更高的翻转速率会带来更多的电磁干扰。对低速 PWM比如舵机 50Hz 信号默认速度就足够了。8. PWM 触发 ADC 采样与进阶应用热词里反复出现pwm触发adc采样这个场景值得单独展开。在电机控制、开关电源等应用中PWM 输出信号和 ADC 采样时序必须严格同步。如果 ADC 在 PWM 开关瞬间采样很容易采到尖峰噪声导致电流环、电压环控制不稳定。解决方案是在 PWM 的特定时刻触发 ADC。STM32 定时器支持把更新事件、比较事件等作为 ADC 触发源。CubeMX 中配置方式如下在 ADC 配置页面的Trigger中选择Timer 1 Trigger Out event。在定时器配置页面中将Trigger Output (TRGO)设置为Update Event或Enable pulse。配置 ADC 为单次转换或连续转换转换完成后通过中断或 DMA 读取结果。这样每个 PWM 周期ADC 都会在定时器更新事件发生的时刻开始采样采样点和 PWM 波形保持固定相位关系。通过调节定时器的比较值可以调整采样点的具体位置避开开关噪声。PWM 应用场景采样点选择建议电机相电流采样在 PWM 中心处采样避开上下管开关瞬间开关电源输出电压采样在 PWM 周期末端采样此时纹波较小功率因数校正在 PWM 正弦波峰值附近采样计算输入电流如果项目中需要这个功能建议直接用 CubeMX 的 timer trigger 配置不需要自己操作寄存器生成代码后只需要在回调函数中读取 ADC 转换结果。9. 常见问题与排查方法这部分整理一些在做 PWM 输出时经常遇到的问题按现象和排查思路列出方便出问题时对照。问题现象可能原因排查方式解决方案引脚没有波形输出定时器未启动或通道错误检查HAL_TIM_PWM_Start是否调用通道是否匹配确认启动函数和 CubeMX 中使能的通道一致波形频率和预期不符PSC 或 ARR 计算错误或定时器时钟不是预期的值打印定时器时钟频率重新计算 PSC/ARR用示波器测量实际频率反推时钟修改频率后波形异常ARR 预装载未开启检查 CubeMX 中Auto-reload preload是否使能使能预装载等待周期结束再生效占空比到不了 100%CCR 值小于 ARR检查寄存器值将 CCR 设为 ARR 1 可以输出常高引脚复用冲突多个外设争用同一引脚检查 CubeMX 的引脚分配和引脚冲突提示换用其它定时器通道或调整引脚使用高级定时器无输出没有使能主输出 MOE检查是否调用HAL_TIM_PWM_Start高级定时器需要额外配置确认使用了 HAL_TIM_PWM_Start 而非仅初始化输出波形抖动GPIO 翻转速度设置不当、外部干扰示波器查看波形边沿调整 GPIO 速度增加滤波电容修改频率后 PWM 停止输出ARR 被设为 0检查计算逻辑避免除零或减一溢出增加边界保护ARR 最小值为 1中断频率过高导致主循环卡死更新中断过于频繁查看中断频率测算 CPU 负载降低中断频率或改用 DMA其中ARR 被设为 0这个问题很隐蔽。如果代码里对频率取整后减 1当目标频率大于定时器时钟时ARR可能小于 1会导致定时器行为异常。建议在所有修改 ARR 的地方增加限幅逻辑。10. 最佳实践与使用建议最后整理几条工程建议这些内容在实际项目中比“PWM 能不能输出”更影响整体稳定性。第一先固定 PSC再调整 ARR 和 CCR。这种模式下频率和占空比的计算互相独立不容易出错。如果同时任意修改 PSC 和 ARR程序要考虑的边界条件会成倍增加。第二所有动态修改频率和占空比的入口建议统一收敛到少数几个函数中。不要在中断、主循环、串口回调里各写一套寄存器操作否则后期维护时很难排查是谁改乱了参数。第三批量输出场景使用数组和查表法。无论是呼吸灯的多级亮度、蜂鸣器的一段旋律还是电机加速曲线预先计算好参数存放在 Flash 里运行时只需要循环读取CPU 开销极低也方便调整参数。第四使用示波器验证实际波形。示波器测频率和占空比是最直接的手段。没有示波器时可以用一个 LED 串联限流电阻接到 PWM 引脚观察亮度变化来粗调占空比用蜂鸣器听音调变化来粗调频率。但正式项目调试时还是建议至少有一台基础示波器。第五保持工程模块化。CubeMX 生成代码后把定时器相关的用户代码放到定时器中断回调中而不是直接改stm32c5xx_it.c这样重新生成代码时不容易被覆盖。PWM 控制函数单独建文件主函数只做业务逻辑。第六对于 PWM 触发 ADC 采样的项目先单独验证 PWM 波形再单独验证 ADC 采样最后再把两者联动。联动时用示波器同时观察 PWM 引脚和 ADC 采样触发信号确保相位符合预期。11. 总结与下一步STM32C5A3R 输出 PWM 并不复杂核心就是理解PSC / ARR / CCR三个寄存器与频率、占空比的数学关系然后在 CubeMX 中完成定时器和 GPIO 配置最后通过 HAL 库函数启动输出。真正花时间的是后续的动态调整、精度权衡、多通道分配和 PWM 与 ADC 的联动控制。拿到这篇文章后建议第一步先在开发板上用示波器验证 1kHz、50% 占空比的 PWM 波形确认环境没问题第二步尝试在主循环里修改占空比观察 LED 呼吸效果第三步尝试修改 ARR 和 PSC观察频率变化同时注意 ARR 改变后占空比的百分比是否维持最后如果有电机控制需求再研究 PWM 触发 ADC 采样和互补 PWM 输出。最容易踩的坑有三个一是忘记调用HAL_TIM_PWM_Start只做了初始化二是高级定时器 TIM1/TIM8 没有正确使能主输出导致引脚无波形三是动态修改 ARR 时把 ARR 减到 0 以下导致定时器行为异常。如果你后续要做电机控制建议优先研究高级定时器的互补 PWM 和刹车功能如果做信号发生器可以考虑用 DMA 连续修改 CCR 输出任意波形如果做低功耗设备要评估 PWM 空闲时关闭定时器时钟减少功耗。这几个方向都能把 STM32C5A3R 的 PWM 能力进一步发挥出来。
返回列表