【STM32+HAL库】---- 高级定时器利用重复计数器输出指定个数PWM

硬件开发板:STM32G0B1RET6
软件平台:cubemax+keil+VScode

1 新建cubemax工程

1.1 配置系统时钟RCC

image

1.2 配置定时器

选择高级定时器TIM1,使用内部时钟源,通道1输出,预分频系数为64000-1,重装载值为1000-1,此时PWM信号周期为1s,占空比为500(50%)),对应的芯片引脚是PA8
image
使能中断
image

2 代码

2.1 定义变量

/* USER CODE BEGIN PV */
uint16_t RCR_num;    //写入重复计数器RCR的计数值
/* USER CODE END PV */

2.2 PWM指定个数输出函数

/* USER CODE BEGIN 0 */
/*设置PWM输出个数*/
void PWM_num_Set(uint16_t pwm_num)
{
  __HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);    /*使能定时器更新中断*/
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);    /*开启PWM输出*/

  if(pwm_num == 0)
    return;    //返回
  else
  {
    RCR_num = pwm_num;    //赋值给重复计数器
    HAL_TIM_GenerateEvent(&htim1, TIM_EVENTSOURCE_UPDATE);          //通过软件启动更新事件
    __HAL_TIM_ENABLE(&htim1);                                       //启动计数器
  }
}
/* USER CODE END 0 */

2.3 回调函数

重复定时器工作原理
计数器每次溢出都能使重复计数器减一,减到0时,再发生溢出就会产生更新事件

/* USER CODE BEGIN 4 */
/*更新中断回调函数*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim == &htim1)
    {
        if(RCR_num)    //判断设置的pwm数量
        {
            TIM1->RCR = RCR_num-1;     //要想产生N个pwm将N-1放入RCR寄存器中
            HAL_TIM_GenerateEvent(&htim1, TIM_EVENTSOURCE_UPDATE);     //通过软件启动更新中断将设定值放入影子寄存器中
            __HAL_TIM_ENABLE(&htim1);     //使能计数器产生进行PWM输出
            RCR_num = 0;    //清零;若不清零,会持续输出PWM
        }
        else
        {
          TIM1->CR1 &= ~(1 << 0);  //关闭计数器
        }
    }
}

/* USER CODE END 4 */

关闭计数器的注意事项

之所以通过寄存器操作TIM1->CR1 &= ~(1 << 0);来关闭计数器,而不使用__HAL_TIM_DISABLE(&htim1);,是因为__HAL_TIM_DISABLE(&htim1);需要判断输出通道TIM_CCER_CCxE_MASK互补输出通道TIM_CCER_CCxNE_MASK是否关闭,只有两个通道关闭后才能正常关闭计数器,代码如下:
image
故直接寄存器操作关闭计数器更方便

2.4 main函数

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 */ 
  PWM_num_Set(3);    /*设置输出3个PWM*/
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

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

3 实验现象

用杜邦线连接PA8pa5,就可以利用输出的PWM驱动LED,根据LED亮灭情况,可判断PWM的输出情况

posted @ 2024-01-17 23:51  晚风也温柔  阅读(232)  评论(0编辑  收藏  举报