初窥门径32系列07--PWM输出

定时器编程实战2:通用定时器PWM输出

硬件设计

本实验用到的硬件资源有:
1) 5V直流电机
2)L298N电机驱动模块
3) 定时器 TIM9
TIM9_CH1 可以通过 PA2 输出 PWM,TIM9_CH2 可以通过 PA3 输出 PWM,利用两个PWM控制电机不同速度的正反转。
4)硬件连接方式:
在这里插入图片描述

通用定时器输出PWM原理

假设为递增计数模式
ARR:自动重装载寄存器的值
CCRx:捕获/比较寄存器x的值
当CNT < CCRx,GPIO输出0
当CNT >= CCRx,GPIO输出1
在这里插入图片描述

CubeMX配置

定时器时钟源频率和上篇一样的配置方法。
在 Pinout->TIM9 配置项中,配置 Channel1 的值为 PWM generation CH1,Channel1 的值为 PWM generation CH1,然后勾选 Internal Clock。如下图
在这里插入图片描述
在弹出的界面中点击 Parameter Settings 选项卡,Counter Settings 配置栏下面的四个选项就是用来配置定时器的预分频系数,自动装载值,计数模式以及时钟分频因子。在界面的 PWM Generation Channel1和2 配置栏配置 PWM 模式,比较值,极性等参数,如下图
在这里插入图片描述
这里没有使用到中断,所以我们不需要使能中断和配置 NVIC,进行完上面的操作之后,接下来我们便是生成工程代码。

通用定时器PWM输出实验配置步骤

1.配置定时器基础工作参数

这里的代码为CubeMX配置。

//tim.c文件
TIM_HandleTypeDef htim9;	//在tim.h文件中定义为extren类型

void MX_TIM9_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};	//时钟源配置结构体
  TIM_OC_InitTypeDef sConfigOC = {0};				//输出比较配置结构体

  htim9.Instance = TIM9;
  htim9.Init.Prescaler = 959;					//PSC分频系数
  htim9.Init.CounterMode = TIM_COUNTERMODE_UP;	//加法计数模式
  htim9.Init.Period = 4999;  					//ARR自动装载值
  htim9.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;				//时钟分频系数
  htim9.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;	//自动预装载
  if (HAL_TIM_Base_Init(&htim9) != HAL_OK)		//定时器基础初始化
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;·		//内部时钟源
  if (HAL_TIM_ConfigClockSource(&htim9, &sClockSourceConfig) != HAL_OK)	//定时器时钟源配置
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim9) != HAL_OK)	//定时器PWM初始化
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;			//输出比较模式PWM1
  sConfigOC.Pulse = 0;							//比较值
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;	//输出极性高
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;	//快速模式关
  if (HAL_TIM_PWM_ConfigChannel(&htim9, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)	//定时器PWM配置通道1
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim9, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)	//定时器PWM配置通道2
  {
    Error_Handler();
  }
  HAL_TIM_MspPostInit(&htim9);
}

2.定时器PWM输出MSP初始化

这里的代码为CubeMX配置。

//tim.c
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(timHandle->Instance==TIM9)
  {
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**TIM9 GPIO Configuration
    PA2     ------> TIM9_CH1
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;	//PA2为PWM通道1,PA3为通道2
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF3_TIM9;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  }
}

3.使能输出并启动计数器

//tim.c
void MX_TIM9_Init(void)
{
  /* MX CODE BEGIN */
  //。。。。。。。。。
  /* MX CODE BEGIN */
  
  /* USER CODE BEGIN */
    //PWM通道使能
   HAL_TIM_PWM_Start(&htim9, TIM_CHANNEL_2);
   HAL_TIM_PWM_Start(&htim9, TIM_CHANNEL_1);
  /* USER CODE END */
  }

4.应用层:main.c

//main.c
int main(void)
{
  /* USER CODE BEGIN */
  uint8_t dir = 1;		//方向
  uint8_t duty = 2000; 	//占空比
  /* USER CODE END */
  
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM9_Init();
  while (1)
  {
  /* USER CODE BEGIN */
    HAL_Delay(10);
    
    if(dir) duty += 10;
    else    duty -= 10;
    
    if(duty >= 4000)  dir = 0;
    if(duty == 0)     dir = 1;
    
    if(dir)
    {  
      HAL_TIM_PWM_Start(&htim9, TIM_CHANNEL_1);				//使能PWM通道1
      __HAL_TIM_SET_COMPARE(&htim9, TIM_CHANNEL_1, duty);	//设置通道1的比较值(占空比)
      HAL_TIM_PWM_Stop(&htim9, TIM_CHANNEL_2);				//失能PWM通道2
    }
    else
    {
      HAL_TIM_PWM_Start(&htim9, TIM_CHANNEL_2);
      __HAL_TIM_SET_COMPARE(&htim9, TIM_CHANNEL_2, duty);
      HAL_TIM_PWM_Stop(&htim9, TIM_CHANNEL_1);
    }
    /* USER CODE END */
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值