这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【换取手持数字示波器】+【NUCLEO-U5A5ZJ-Q测评】PWM使用

共2条 1/1 1 跳转至

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

菜鸟
2024-04-26 10:32:07     打赏

NUCLEO-U5A5ZJ-Q开发板使用PWM(脉宽调制)功能时,可以实现对电机、LED等设备的精确控制。以下是一些关于在NUCLEO-U5A5ZJ-Q上使用PWM的测评和建议:

  1. PWM原理:PWM是一种模拟控制技术,它利用数字信号来模拟生成一个可以变化的模拟信号。通过改变数字信号的占空比(即高电平时间占整个周期的比例),可以控制模拟信号的强度。

  2. PWM配置

    • 选择PWM通道:首先,需要确定使用哪个PWM通道。NUCLEO-U5A5ZJ-Q上的STM32U5微控制器通常具有多个PWM通道,可以根据具体需求选择。

    • 配置PWM参数:接下来,需要配置PWM的参数,如频率、占空比等。这些参数可以通过软件编程进行设置。

    • 编写代码:使用HAL库或标准外设库中的PWM函数,编写代码来初始化PWM通道并设置参数。

  3. PWM应用

    • LED亮度控制:通过PWM控制LED的亮度。通过改变PWM信号的占空比,可以控制LED的亮度变化。

    • 电机控制:PWM也可以用于控制电机的转速和方向。例如,对于SG90舵机,可以通过PWM信号来控制其转动的角度和速度。通常,PWM信号的占空比与舵机的角度呈线性关系。


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

参考程序的方向:

  • 在主程序中,编写代码来控制PWM的占空比,以实现呼吸灯效果。这通常涉及到在定时器中断服务例程中更新PWM的占空比。

  • 为了实现呼吸效果,可以设定一个变量(如pwm_value)来表示PWM的占空比,并在每个定时器中断周期中增加或减少该变量的值。当pwm_value达到最大值或最小值时,改变增加或减少的方向。

  • 使用HAL库中的函数(如__HAL_TIM_SET_COMPARE)来设置TIM3_CH2的占空比。


参考示例:

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 */
}


详细的代码示例:

#include "stm32u5xx_hal.h"  
  
// 假设你已经使用STM32CubeMX配置了一个PWM通道(例如TIM2_CH1)  
TIM_HandleTypeDef htim2; // 假设这是你的PWM定时器句柄  
uint16_t pwm_value = 0;  // PWM占空比初始值  
int8_t direction = 1;    // 控制PWM值增加或减少的方向  
  
// 定时器中断服务例程(ISR)  
void TIM2_IRQHandler(void)  
{  
    HAL_TIM_IRQHandler(&htim2);  
}  
  
// 定时器周期结束回调  
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)  
{  
    if (htim->Instance == TIM2)  
    {  
        // 更新PWM值以实现呼吸效果  
        pwm_value += direction;  
        if (pwm_value == 0 || pwm_value == htim2.Init.Period)  
        {  
            direction = -direction; // 改变方向  
        }  
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pwm_value); // 更新PWM通道1的占空比  
    }  
}  
  
// 主函数或其他初始化函数中的代码  
int main(void)  
{  
    // HAL库初始化等代码...  
  
    // 初始化PWM定时器  
    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);  
  
    // 启动定时器中断  
    HAL_TIM_Base_Start_IT(&htim2);  
  
    // 主循环或其他逻辑...  
  
    // 无限循环  
    while (1)  
    {  
        // 你的主循环代码...  
    }  
}




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



选择PC7驱动的GREEN绿色LED。

blob.png

CUBE配置:

 

 blob.png

blob.png

blob.png

  

定时器3

 引脚定义:

blob.png

下面是自己写的代码:

// 循环,当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);
  • 使用STM32 HAL库来配置TIM3的PWM输出,以及如何通过递增和递减PWM值来模拟呼吸灯效果。

    blob.png


逻辑分析仪采样:

blob.png


总结:

功能总结

  1. 初始化

    • 定义了PWM占空比的初始值pwmVal为0。

    • 定义了控制PWM值增加或减少的方向变量direction为1(表示初始时PWM值将增加)。

    • 初始化了一个定时器(假设为TIM3),并设置了相关的参数,如预分频值、计数模式、周期值等。

    • 配置了TIM3的中断,包括设置中断优先级和使能中断。

    • 启动了定时器的中断功能(HAL_TIM_Base_Start_IT)和PWM通道(HAL_TIM_PWM_Start)。

  2. 定时器中断服务例程

    • 当TIM3的更新中断被触发时,执行TIM3_IRQHandler中断服务例程。

    • 在中断服务例程中,首先通过HAL库函数处理TIM3的中断。

    • 检查TIM3的更新中断标志位是否被设置。

    • 如果更新中断标志位被设置,则清除该标志位,并更新PWM占空比的值。

    • 更新PWM占空比时,根据direction变量的值增加或减少pwmVal的值。

    • 当pwmVal达到预设的最大值(PERIOD_VALUE)或最小值(0)时,切换direction变量的值以改变PWM值的增减方向。

    • 通过HAL库函数设置TIM3的通道2的比较值,从而改变PWM的占空比。

  3. 呼吸效果

    • 由于PWM占空比的值在最大值和最小值之间来回变化,并且变化的速率也在改变(由direction变量控制),因此连接到TIM3通道2的PWM输出将产生类似呼吸灯的效果。



高工
2024-04-26 13:31:55     打赏
2楼

谢谢分享


共2条 1/1 1 跳转至

回复

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