STM32 TIM定时器 输出比较模式遇到的坑

这两天在学习STM32 TIM定时器输出比较模式,按照网上的教程也能实现PWM波的输出,占空比和频率都符合预期。但是当波形时间拉长以后,就会出现ARR周期的高电平或者低电平,定位了好久。

 现象:

现象

出现问题的原因很简单:比较寄存器超出ARR设定的值了;

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 107;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 60000;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

 此时ARR设定的值是6000

void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
	uint32_t OC_Count = 0;
	OC_Count = __HAL_TIM_GET_COUNTER(htim);	/* 读取定时器的当前计数值,就是读取TIM1_CNT寄存器的值 */
	if(htim->Instance == TIM3){			    /* 判断是否是定时器1 */
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){	
//      unsigned short i = OC_Count + OC_Channel1_Pulse - OC_Channel1_Duty * OC_Channel1_Pulse/100;
//      if(i>= 60000)
//      i = 0;
//      unsigned short j = OC_Count + OC_Channel1_Duty * OC_Channel1_Pulse/100;
//      if(j>= 60000)
//      j = 0;
      /* 判断是否是通道1 */
			if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6)){ /* 判断此时的电平是否为低电平 */        
				//__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,i);/* 设置比较寄存器CCR的值--0.3ms的低电平 */
				__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,OC_Count + OC_Channel1_Pulse - OC_Channel1_Duty * OC_Channel1_Pulse/100);/* 设置比较寄存器CCR的值--0.3ms的低电平 */
			}else{
				//__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,j);/* 设置比较寄存器CCR的值--0.7ms的高电平 */
				__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,OC_Count + OC_Channel1_Duty * OC_Channel1_Pulse/100);/* 设置比较寄存器CCR的值--0.7ms的高电平 */
			}
		}else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2){ /* 判断是否是通道2 */
			if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7)){
				__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,OC_Count + OC_Channel2_Pulse - OC_Channel2_Duty * OC_Channel2_Pulse/100);
			}else{
				__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,OC_Count + OC_Channel2_Duty * OC_Channel2_Pulse/100);
			}
		}
	}
}

图中红框CCR的值超过ARR的值了,目前用注释掉的代码测试,现象是没了,但是长时间运行会不会有问题不确定。

更新:

uint32_t OC_Channel1_Pulse = 100; /* TIM1通道1的脉冲宽度 */
uint32_t OC_Channel1_Duty = 70;    /* TIM1通道1的占空比 */
uint32_t OC_Channel2_Pulse = 200; /* TIM1通道2的脉冲宽度 */
uint32_t OC_Channel2_Duty = 20;    /* TIM1通道2的占空比 */

void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
  uint32_t OC_Count = 0;
  OC_Count = __HAL_TIM_GET_COUNTER(htim); /* 读取定时器的当前计数值,就是读取TIM1_CNT寄存器的值 */
  //printf("Count= %d \r\n",OC_Count);
  if (htim->Instance == TIM1)
  { /* 判断是否是定时器1 */
    if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
    { /* 判断是否是通道1 */
      if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_9))
      {                                                                                                                          /* 判断此时的电平是否为低电平 */
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, OC_Count + OC_Channel1_Pulse - OC_Channel1_Duty * OC_Channel1_Pulse / 100); /* 设置比较寄存器CCR的值--0.3ms的低电平 */
      }
      else
      {
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, OC_Count + OC_Channel1_Duty * OC_Channel1_Pulse / 100); /* 设置比较寄存器CCR的值--0.7ms的高电平 */
      }
      if(htim->Instance->CCR1 >= htim->Init.Period)htim->Instance->CCR1=0;
    }
    else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
    { /* 判断是否是通道2 */
      if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_11))
      {
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, OC_Count + OC_Channel2_Pulse - OC_Channel2_Duty * OC_Channel2_Pulse / 100);
      }
      else
      {
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, OC_Count + OC_Channel2_Duty * OC_Channel2_Pulse / 100);
      }
      if(htim->Instance->CCR2 >= htim->Init.Period)htim->Instance->CCR2=0;
    }
  }
}

 

添加红框里面的代码,做一个判断,目前没出什么问题。

注:不要再回调(中断)里面打印数据,这样出来的波形不准确!!!切记!!!

参考:

https://blog.csdn.net/phker/article/details/80752691

 https://blog.csdn.net/qq_20222919/article/details/120992583

 STM32 TIM输出比较、PWM波形_输出比较输出pwm波形-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值