STM32CubeMX+HAL+Keil5 PWM呼吸灯

张开发
2026/4/13 16:47:21 15 分钟阅读

分享文章

STM32CubeMX+HAL+Keil5 PWM呼吸灯
文章目录1 准备材料2 知识讲解2.1 PWM 是什么2.2 STM32 定时器产生 PWM 需要的四个关键参数2.3 必记公式2.4 CNT 与 CCR 比较时的输出电平规则3 实验3.1 低频 PWM 闪烁观察3.2 PWM控制呼吸灯3.2.1 为PWM选择合适引脚第一步查看数据手册中的引脚定义表第二步理解命名规则第三步确认定时器时钟来源3.2.2 CubeMX 配置3.2.3 编写代码3.2.4 硬件连接1 准备材料开发板STM32F103C8T6STM32CubeMX软件Version 6.15.0ST-LINK/V2 驱动keil µVision5 IDEMDK-Arm2 知识讲解2.1 PWM 是什么PWM脉冲宽度调制是一种通过快速开关信号并用每个周期内高电平的时间比例来控制平均输出电压或亮度、速度等的技术。核心思想开关速度快到人眼/负载反应不过来只能感受到平均值。两个关键参数频率每秒开关的次数单位 Hz。频率越高波动越小。频率Hz 1 / 周期秒例如 1000 Hz → 周期 1/1000 秒 1 ms。例如 1 Hz → 周期 1 秒 1000 ms。占空比一个周期内高电平时间占整个周期的百分比。举个 LED 例子频率 1000 Hz每秒开关 1000 次对应周期为1ms占空比 50% → 每个周期内亮 0.5 ms、灭 0.5 ms人眼看到半亮。占空比越大LED 越亮。2.2 STM32 定时器产生 PWM 需要的四个关键参数在 STM32 的通用定时器如 TIM3中要产生 PWM 波形需要配置4 个数值参数全称作用补充说明PSCPrescaler预分频器控制每数一步的时间计数时钟频率PSC 越大每步时间越长频率越低ARRAuto Reload Register自动重装载值一个 PWM 周期内计数多少步步数 ARR1决定占空比分母CCRCapture/Compare Register捕获/比较寄存器决定占空比与 CNT 比较决定输出有效电平的步数极性 High 时有效电平为高电平占空比Duty Cycle实际效果高电平时间 / 周期时间CCR / (ARR1)注意ARR 和 CCR 都是寄存器通过 CubeMX 设置 ARR通过__HAL_TIM_SET_COMPARE设置 CCR。2.3 必记公式PWM 频率 定时器时钟源频率 ÷ ( 预分频器 PSC 1) ÷ ( 自动重装载值 ARR 1)占空比 CCR ÷ (ARR 1)2.4 CNT 与 CCR 比较时的输出电平规则在 STM32 定时器的 PWM 模式中极性仅仅反转有效电平的定义CNT为定时器计数器值极性设置CNT CCRCNT ≥ CCRHigh高电平有效输出高电平输出低电平Low低电平有效输出低电平输出高电平本次实验中使用极性 High因此 CCR 越大高电平时间越长LED 越亮。3 实验3.1 低频 PWM 闪烁观察目的把 PWM 频率降低到人眼能分辨的范围 10 Hz亲眼看到LED 在一个周期内“先亮后灭”或“先灭后亮”的完整过程从而直观理解占空比 亮的时间 / 周期的含义。本次以1Hz为例PWM 频率 定时器时钟源频率 ÷ ( 预分频器 PSC 1) ÷ ( 自动重装载值 ARR 1)PSC 35999 → PSC1 36000ARR 1999 → ARR1 2000频率 72,000,000 ÷ 36000 ÷ 2000 1 Hz周期 1 秒 1000 毫秒系统时钟定时器时钟源72MHz1M 1000千PSC35999ARR1999占空比 CCR ÷ (ARR 1)__HAL_TIM_SET_COMPARE(htim3, TIM_CHANNEL_1, 1000);这个函数的作用是设置定时器 TIM3 的通道 1 的比较值也就是占空比的控制值为 1000其中占空比比例为 1000 /ARR11000 / 19991 50%即可以肉眼观察到led亮0.5s灭0.5s的过程可以尝试修改 CCR 为 50025% 占空比或 150075% 占空比观察亮灭时间的变化。3.2 PWM控制呼吸灯3.2.1 为PWM选择合适引脚第一步查看数据手册中的引脚定义表关键点在 “默认复用功能” 列中如果某个引脚标注了TIMx_CHy比如 TIM3_CH1就表示它可以作为定时器 TIM3 的通道 y 输出 PWM。第二步理解命名规则TIMx定时器编号如 TIM1、TIM2、TIM3、TIM4 等。CHy通道编号每个定时器通常有 1~4 个通道CH1~CH4。例如TIM3_CH1表示定时器 3 的通道 1。第三步确认定时器时钟来源不同的定时器挂在不同的总线上TIM2、TIM3、TIM4 挂在 APB1 总线上TIM1、TIM8 挂在 APB2 总线上本次我们使用引脚PA6演示3.2.2 CubeMX 配置新建工程打开 STM32CubeMX选择你的 MCU 型号如 STM32F103C8T6配置调试接口进入 Pinout Configuration 视图点击 SYSDebug 选择 Serial Wire避免 JTAG 引脚冲突影响调试配置时钟源点击 RCCHigh Speed Clock (HSE) 选择 Crystal/Ceramic Resonator配置时钟树将 HCLK 设为 72MHzSTM32F103 最高主频系统会自动计算各总线分频配置 TIM3 PWM 输出在 Pinout 视图中找到 PA6 引脚点击选择 TIM3_CH1点击 TIM3勾选 Channel 1 为 PWM Generation CH1Clock Source 选择 Internal ClockParameter Settings 中配置Prescaler71预分频值Counter ModeUp向上计数Counter Period999自动重装载值 ARRAuto-reload preloadEnablePWM Generation Channel 1 中配置ModePWM mode 1Pulse0初始占空比CH PolarityHigh高电平有效PWM 频率计算公式频率 72MHz / (Prescaler1) / (Counter Period1) 72000000 / 72 / 1000 1000Hz配置 GPIOCubeMX 会自动将 PA6 设为复用推挽输出模式无需手动调整生成代码Project Manager 中设置工程名、保存路径、Toolchain/IDE如 MDK-ARM勾选 “Generate peripheral initialization as a pair of ‘.c/.h’ files”点击 GENERATE CODE3.2.3 编写代码在生成的工程中找到 main.c在/* USER CODE BEGIN */和/* USER CODE END */注释块之间添加代码注意不要写在注释块外面否则重新生成代码时会被覆盖。/* USER CODE BEGIN 0 */uint16_tdutyCycle0;// 占空比变量uint8_tdirection1;// 1渐亮, 0渐暗/* USER CODE END 0 *//* USER CODE BEGIN 2 */// 启动 TIM3 通道 1 的 PWM 输出HAL_TIM_PWM_Start(htim3,TIM_CHANNEL_1);/* USER CODE END 2 *//* USER CODE BEGIN 3 */while(1){// 逐渐改变占空比实现呼吸效果if(direction1)// 渐亮{dutyCycle5;if(dutyCycle990)// 到达最亮后切换方向{dutyCycle990;direction0;}}else// 渐暗{dutyCycle-5;if(dutyCycle10)// 到达最暗后切换方向{dutyCycle10;direction1;}}// 设置比较寄存器值改变占空比__HAL_TIM_SET_COMPARE(htim3,TIM_CHANNEL_1,dutyCycle);HAL_Delay(7);// 控制呼吸速度}/* USER CODE END 3 */代码说明定时器的自动重装载值 ARR 设置为 999因此 dutyCycle 取值范围为 0 到 999对应占空比 0% 到 100%。这里设置 dutyCycle 范围为 10 到 990保留一定的亮暗余量避免 LED 完全熄灭或过亮。3.2.4 硬件连接组件连接点STM32 PA6 引脚限流电阻一端限流电阻220Ω~1kΩ另一端LED 正极阳极LED 负极阴极GND最终效果如下组件连接点STM32 PA6 引脚限流电阻一端限流电阻220Ω~1kΩ另一端LED 正极阳极LED 负极阴极GND最终效果如下

更多文章