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波!!!!!!

相关推荐
一个不知名程序员www1 小时前
算法学习入门 --- 哈希表和unordered_map、unordered_set(C++)
c++·算法
Sarvartha2 小时前
C++ STL 栈的便捷使用
c++·算法
夏鹏今天学习了吗3 小时前
【LeetCode热题100(92/100)】多数元素
算法·leetcode·职场和发展
飞Link3 小时前
深度解析 MSER 最大稳定极值区域算法
人工智能·opencv·算法·计算机视觉
bubiyoushang8883 小时前
基于CLEAN算法的杂波抑制Matlab仿真实现
数据结构·算法·matlab
2401_894828124 小时前
从原理到实战:随机森林算法全解析(附 Python 完整代码)
开发语言·python·算法·随机森林
Remember_9934 小时前
【LeetCode精选算法】前缀和专题二
算法·哈希算法·散列表
源代码•宸4 小时前
Leetcode—509. 斐波那契数【简单】
经验分享·算法·leetcode·面试·golang·记忆化搜索·动规
博大世界5 小时前
matlab结构体数组定义
数据结构·算法
Loo国昌5 小时前
【LangChain1.0】第九阶段:文档处理工程 (LlamaIndex)
人工智能·后端·python·算法·langchain