STM--32PWM动态输出

Cubemx 配置

代码书写

复制代码
  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);  //启用PWM
	  uint16_t a = 100;
  /* USER CODE END 2 */

  /* USER CODE BEGIN WHILE */
  while (1)
  {
		

 
      HAL_Delay(10);
      a += 5;
      if(a > 1000){
        a = 100;
      }
      //通过这个宏改变占空比
      __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, a); 
    /* USER CODE END WHILE */

小灯正极连接到TIM2_CH1负极连接GND, 观察到小灯由暗到亮的过程实验成功

波形显示

复制代码
/* USER CODE BEGIN Includes */
#include <stdint.h>
#include "stdio.h"
#include <string.h>
/* USER CODE END Includes */

/* USER CODE BEGIN 0 */

typedef unsigned char uint8_t_custom;

void Ano_SendPwmData(uint16_t duty, uint8_t_custom gpio_level) {
    uint8_t_custom arr[12] = {0};  // 总长度12字节
    
    // 帧头
    arr[0] = 0xAB;      // 帧头
    // 设备地址
    arr[1] = 0x01;      // 源地址(自定义)
    // 目标地址
    arr[2] = 0x02;      // 目标地址(匿名助手)
    // 功能码
    arr[3] = 0xF1;      // 功能码(灵活数据帧)
    // 数据长度(2字节,低字节在前)
    uint8_t_custom flen = 4;   // 4字节数据
    arr[4] = flen;      // 数据长度低字节
    arr[5] = 0x00;      // 数据长度高字节
    // 数据部分(4字节)
    arr[6] = duty & 0xFF;        // PWM占空比低字节
    arr[7] = (duty >> 8) & 0xFF; // PWM占空比高字节
    arr[8] = gpio_level;         // GPIO电平
    arr[9] = 0x00;               // 预留字节
    
    // 计算校验和
    uint8_t_custom sumcheck = 0;
    uint8_t_custom addcheck = 0;
    for(uint8_t_custom i = 0; i < (flen + 6); i++) {
        sumcheck += arr[i];
        addcheck += sumcheck;
    }
    // 填充校验和
    arr[10] = sumcheck;
    arr[11] = addcheck;
    
    // 发送数据到串口
    HAL_UART_Transmit(&huart1, arr, 12, HAL_MAX_DELAY);
}

/* USER CODE END 0 */

int main(void)
{
  /* USER CODE BEGIN 1 */
  uint8_t_custom ctrl_level = 0; // 电机/呼吸灯控制引脚电平
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/
  HAL_Init();
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // 启动PWM输出
  uint16_t duty = 0;  // 占空比比较值(0~999对应0%~100%)
  uint8_t dir = 1;    // 占空比变化方向:1=增大,0=减小
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    // 1. 动态设置PWM占空比
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, duty);
    
    // 2. 获取控制引脚电平(也可直接用PWM引脚控制电机/呼吸灯)
    ctrl_level = HAL_GPIO_ReadPin(CTRL_PORT, CTRL_PIN);
    
    // 3. 保留原格式发送PWM占空比+控制电平(不修改发送格式)
    Ano_SendPwmData(duty, ctrl_level);
    
    // 4. 占空比渐变逻辑(实现呼吸/电机转速变化)
    if (dir) {
      duty += 10; // 占空比+1%
      if (duty >= 999) dir = 0;
    } else {
      duty -= 10; // 占空比-1%
      if (duty <= 0) dir = 1;
    }
    
    HAL_Delay(20); // 控制渐变速度
    /* USER CODE END WHILE */

这段代码产生的是占空比渐变的"三角波效果" (对应电机/呼吸灯的平滑变化),而非固定占空比的方波,核心原因是代码中实现了占空比的连续渐变逻辑,具体解析如下:

  1. 方波的本质是「固定占空比/突变占空比」

方波的特征是:PWM的占空比保持固定值 (如50%占空比,高低电平时间相等),或在两个固定值之间快速突变(如0%和100%切换),波形表现为"高低电平交替、占空比无渐变"。

  1. 这段代码的逻辑是「占空比平滑渐变」

代码中通过 duty(占空比比较值)的逐步增减+方向切换,实现了占空比的连续变化,最终呈现"三角波形状"的占空比曲线:

复制代码
uint16_t duty = 0;  // 占空比比较值(0~999对应0%~100%)
uint8_t dir = 1;    // 方向:1=增大,0=减小

// 占空比渐变逻辑
if (dir) {
  duty += 10; // 占空比+1%(逐步增大)
  if (duty >= 999) dir = 0; // 到最大值后切换方向
} else {
  duty -= 10; // 占空比-1%(逐步减小)
  if (duty <= 0) dir = 1; // 到最小值后切换方向
}
  • duty 从0→999→0循环变化,占空比随之从0%→100%→0%平滑渐变;

  • 结合 HAL_Delay(20) 的延时,占空比的变化是缓慢且连续的,最终表现为"三角波效果"(对应电机转速/呼吸灯亮度的平滑变化)。

  1. 底层PWM仍是方波,但"宏观效果是三角波"

要明确两个层面的波形:

  • 硬件层PWM :TIM2输出的是高频方波(周期固定,由TIM的ARR值决定);

  • 功能层效果 :由于占空比在连续渐变,方波的"平均电压"(或设备响应)会呈现三角波形状(比如呼吸灯的亮度从暗→亮→暗的平滑过渡)。

总结

这段代码的核心逻辑是占空比的连续渐变 ,而非固定/突变占空比,因此呈现的是"三角波效果";若要实现方波,只需让占空比在两个固定值之间突变 (比如直接切换 duty=0duty=999)即可。

遗留问题:怎么生成动态改变的PWM波!!!!!!

相关推荐
季明洵4 小时前
C语言实现单链表
c语言·开发语言·数据结构·算法·链表
shandianchengzi4 小时前
【小白向】错位排列|图文解释公考常见题目错位排列的递推式Dn=(n-1)(Dn-2+Dn-1)推导方式
笔记·算法·公考·递推·排列·考公
I_LPL4 小时前
day26 代码随想录算法训练营 回溯专题5
算法·回溯·hot100·求职面试·n皇后·解数独
Yeats_Liao4 小时前
评估体系构建:基于自动化指标与人工打分的双重验证
运维·人工智能·深度学习·算法·机器学习·自动化
cpp_25014 小时前
P9586 「MXOI Round 2」游戏
数据结构·c++·算法·题解·洛谷
浅念-4 小时前
C语言编译与链接全流程:从源码到可执行程序的幕后之旅
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
有时间要学习4 小时前
面试150——第五周
算法·深度优先
晚霞的不甘5 小时前
Flutter for OpenHarmony 可视化教学:A* 寻路算法的交互式演示
人工智能·算法·flutter·架构·开源·音视频
望舒5135 小时前
代码随想录day25,回溯算法part4
java·数据结构·算法·leetcode
C++ 老炮儿的技术栈6 小时前
Qt 编写 TcpClient 程序 详细步骤
c语言·开发语言·数据库·c++·qt·算法