论坛» 活动中心» 板卡试用

【换取手持数字示波器】+【NUCLEO-U5A5ZJ-Q测评】PWM使用

菜鸟
2024-04-26 10:37 1楼

使用PWM来个呼吸灯.先来点理论知识:

什么是PWM 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。PWM工作原理SMT32F1系列共有8个定时器:高级定时器(TIM1、TIM8);通用定时器(TIM2、TIM3、TIM4、TIM5);基本定时器(TIM6、TIM7)。SMT32F4系列共有15个定时器:高级定时器(TIM1、TIM8);通用定时器(TIM2、TIM3、TIM4、TIM5、TIM9~TIM14);基本定时器(TIM6、TIM7)。STM32的每个通用定时器都有独立的4个通道可以用来作为:输入捕获、输出比较、PWM输出、单脉冲模式输出等。STM32的定时器除了TIM6和TIM7(基本定时器)之外,其他的定时器都可以产生PWM输出。其中,高级定时器TIM1、TIM8可以同时产生7路PWM输出。


PWM的工作模式: PWM模式1(向上计数) :计数器从0计数加到自动重装载值(TIMx_ARR),然后重新从0开始计数,并且产生一个计数器溢出事件 PWM模式2(向下计数) :计数器从自动重装载值(TIMx_ARR)减到0,然后重新从重装载值(TIMx_ARR)开始递减,并且产生一个计数器溢出事件 设置寄存器TIMx_CCMR1的OC1M[2:0]位来确定PWM的输出模式: PWM模式1:在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。 PWM模式2:在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为有效电平,否则为无效电平。

参加示例:

while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ while (pwmVal< 500) { pwmVal++; __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, pwmVal); //修改比较值,修改占空比 // TIM3->CCR1 = pwmVal; 与上方相同 HAL_Delay(1); } while (pwmVal) { pwmVal--; __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, pwmVal); //修改比较值,修改占空比 // TIM3->CCR1 = pwmVal; 与上方相同 HAL_Delay(1); } HAL_Delay(200); /* USER CODE END 3 */ }

LED的简单GPIO驱动改成PWM方式的呼吸灯。

选择PC7驱动的GREEN绿色LED。

blob.png

CUBE配置:

定时器3

下面是自己写的代码:

// 循环,当pwmVal小于500时执行 while (pwmVal < 500) { // pwmVal递增 pwmVal++; // 使用HAL库函数设置TIM3的PWM比较值,从而改变PWM占空比 __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, pwmVal); // 注释掉的代码与上一行功能相同,直接操作CCR1寄存器来设置比较值 // TIM3->CCR1 = pwmVal; // 与上方相同 // 延时1毫秒 HAL_Delay(1); } // 循环,当pwmVal大于0时执行 while (pwmVal) { // pwmVal递减 pwmVal--; // 使用HAL库函数设置TIM3的PWM比较值,从而改变PWM占空比 __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, pwmVal); // 注释掉的代码与上一行功能相同,直接操作CCR1寄存器来设置比较值 // TIM3->CCR1 = pwmVal; // 与上方相同 // 延时1毫秒 HAL_Delay(1); } // USER CODE END 3 标志结束 /* USER CODE END 3 */ // 定义TIM_MasterConfigTypeDef结构体变量,用于TIM主从模式配置 TIM_MasterConfigTypeDef sMasterConfig = {0}; // 定义TIM_OC_InitTypeDef结构体变量,用于PWM输出通道配置 TIM_OC_InitTypeDef sConfigOC = {0}; // USER CODE BEGIN TIM3_Init 1 标志开始 /* USER CODE BEGIN TIM3_Init 1 */ // USER CODE END TIM3_Init 1 标志结束 /* USER CODE END TIM3_Init 1 */ // 初始化htim3结构体,设置TIM3的参数 htim3.Instance = TIM3; htim3.Init.Prescaler = PRESCALER_VALUE; // 设置预分频值 htim3.Init.CounterMode = TIM_COUNTERMODE_UP; // 设置计数器模式为向上计数 htim3.Init.Period = PERIOD_VALUE; // 设置自动重装载寄存器周期的值 htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // 设置时钟分频因子 htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; // 设置是否允许在运行时更改自动重载寄存器的值 // 调用HAL_TIM_PWM_Init函数初始化TIM3的PWM功能 if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) { // 如果初始化失败,调用错误处理函数 Error_Handler(); } // 配置TIM3的主输出触发源和主从模式 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; // 调用HAL_TIMEx_MasterConfigSynchronization函数配置TIM3的主从同步 if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { // 如果配置失败,调用错误处理函数 Error_Handler(); } // 配置TIM3的PWM通道2 sConfigOC.OCMode = TIM_OCMODE_PWM1; // 设置PWM模式 sConfigOC.Pulse = PULSE_VALUE; // 设置PWM脉冲宽度 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // 设置PWM输出极性为高 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; // 设置PWM快速模式为禁用 // 调用HAL_TIM_PWM_ConfigChannel函数配置TIM3的PWM通道2 if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { // 如果配置失败,调用错误处理函数 Error_Handler(); } // USER CODE BEGIN TIM3_Init 2 标志开始 /* USER CODE BEGIN TIM3_Init 2 */ // USER CODE END TIM3_Init 2 标志结束 /* USER CODE END TIM3_Init 2 */ // 调用HAL库提供的函数完成TIM3的Msp层初始化 HAL_TIM_MspPostInit(&htim3);

逻辑分析仪采样:

blob.png



高工
2024-04-26 13:31 2楼

谢谢分享

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]