【STM32CubeMX】使用STM32F103C8T6输出PWM波形实现呼吸灯

一、关于PWM

1.关于PWM
含义
  PWM(Pulse Width Modulation)即脉冲宽度调制,简称脉宽调制。它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术;它是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。
基本原理
  PWM就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。也可以这样理解,PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。只要带宽足够,任何模拟值都可以使用 PWM 进行编码。
优点及应用范围
  由于其控制简单、灵活和动态响应好等优点而成为电力电子技术应用最广泛的控制方式,其应用领域包括测量,通信, 功率控制与变换,电动机控制、伺服控制、调光、开关电源,甚至某些音频放大器,因此学习PWM具有十分重要的现实意义。
2.STM32上的PWM
PWM产生

  STM32的定时器除了TIM6和7,其他的定时器都可以用来产生PWM输出。其中高级定时器TIM1和TIM8可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出,这样,STM32 最多可以同时产生 30 路 PWM 输出。
  脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。通用定时器产生PWM 的定时器框图如下:(其他定时器框图类似)请添加图片描述

PWM相关寄存器
包含三个寄存器:

捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)。
设置TIMx_CCMRx寄存器OCxPE位以使能相应的预装载寄存器,最后还要设置TIMx_CR1寄存器的ARPE位,(在向上计数或中心对称模式中)使能自动重装载的预装载寄存器。在TIMx_CCMRx寄存器中的OCxM位写入110(PWM模式1)或111(PWM模式2),能够独立地设置每个OCx输出通道产生一路PWM。

捕获/比较模式寄存器(TIMx_CCMRx)
下图为TIMx_CCMR1寄存器的各位描述:

请添加图片描述

这里需要使用的是模式设置位OCxM,总共有两种PWM模式,这两种PWM 模式的区别就是输出电平的极性相反。
110:PWM模式1。在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。

111:PWM模式2。 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。

捕获/比较使能寄存器(TIMx_CCER)
下图为TIMx_CCER寄存器的各位描述:

请添加图片描述

该寄存器控制着各个输入输出通道的开关。这里只用到了CC2E位,该位是输入/捕获 2 输出使能位,要想PWM 从 I/O 口输出,这个位必须设置为 1。
捕获/比较寄存器(TIMx_CCRx)
下图为TIMx_CCR1寄存器的各位描述:

请添加图片描述

在输出模式下,该寄存器的值与 CNT 的值比较,根据比较结果在OC1端口上产生输出信号。利用这点,我们通过修改这个寄存器的值实现控制 PWM 的输出脉宽。

二、Cube MX创建工程

参考以往Cube MX常规设置,本教程只讲解特殊之处,也可跳转查看详细步骤STM32CUBEMX_基于PWM的呼吸灯
在这里插入图片描述
时钟配置
在这里插入图片描述
生成代码

三、修改代码

将以下代码加入main.c


#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */
   HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);				//¿ªÆôtim1ͨµÀ1¼ÆʱÆ÷
   
   HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_4);				//¿ªÆôtim1ͨµÀ4¼ÆʱÆ÷
  /* USER CODE END 2 */
	int i=0,flag=0;
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
	
	 if(flag==0)
	 {
		 i+=10;
		 if(i>400)
			flag=1;
	 }
	 else
	 {
		i-=10;
		if(i<5)
			flag=0;
	 }
	 //PAB2×ÜÏßʱÖÓΪ72Mhz£¬¾­¹ý72·ÖƵºóΪ1Mhz£¬¼ÆÊýÖÜÆÚRCCΪ65535
	  __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1,i);				  //LED1ÁÁ¶ÈÖð½¥Ôö¼Ó
	  __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_4,420-i);			//LED2ÁÁ¶ÈÖð½¥½µµÍ
//	  HAL_Delay(20);
	 
//	  __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_4,400-i);
//	  HAL_Delay(20);
//	  __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 200);
//	  HAL_Delay(100);
//	  __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 300);
//	  HAL_Delay(100);
//	  __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 400);
//	  HAL_Delay(100);
//	  __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 300);
//	  HAL_Delay(100);	  
//	  __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 200);
//	  HAL_Delay(100);
//	  __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 100);
	  HAL_Delay(100);

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

四、效果展示

6f4c8d52c22ad6

五、总结

此次实验主要是学习了PWM的有关知识,认识和了解了PWM,并且尝试应用在了此次实验中,当然在本次实验中也遇到了一些问题,这些问提也深化了对PWM的认识。

六、参考与代码下载

参考:使用STM32输出PWM波形
工程下载
提取码:8520

猜你喜欢

转载自blog.csdn.net/qq_52201641/article/details/127581116