在进行PWM输出时,碰到的一个问题(关于PWM暂停现象的)
一、问题描述
定时器的配置:
void MX_TIM14_Init(void)
{
TIM_OC_InitTypeDef sConfigOC;
htim14.Instance = TIM14;
htim14.Init.Prescaler = 15-1;
htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
htim14.Init.Period = 64000-1;
htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim14) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if (HAL_TIM_OC_Init(&htim14) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_OC_ConfigChannel(&htim14, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_TIM_MspPostInit(&htim14);
}
当我按键按下的时候,写flash,这个时候PWM输出的波形为20ms低电平,20ms高电平;然后我想让在写flash的时候,PWM输出的一直为低,百度也找了下,说是控制占空比,但是我试了下,效果不是很好,
[图1是不控制比较值,下面是写flash时候的代码]
// __HAL_TIM_SET_COMPARE(&htim14, TIM_CHANNEL_1, 64000);
__disable_irq();
Write_Flash_Buf(FLASH_RF_PIN_MODE_ADR,(uint8_t *) modebuff, sizeof(modebuff));
Write_Flash_Buf(FLASH_RF_PIN_DATA_ADR, Slave_re_Pindata_temp, sizeof(Slave_re_Pindata_temp));
__enable_irq();
当我将上面屏蔽的 // __HAL_TIM_SET_COMPARE(&htim14, TIM_CHANNEL_1, 64000); 打开时, 采集到的现象是图2
在图2中的1,这个时候写flash前是低电平的, __HAL_TIM_SET_COMPARE(&htim14, TIM_CHANNEL_1, 64000); 设置这个比较值,然后在写flash的时候电平一直是低电平的;
但是图2中的2,flash前正好是高电平,设置这个比较值,然后在写flash的时候电平一直是高电平的;
我想达到的目的就是在写flash前,将其电平一直为低
【图1】
【图2】
二、处理方法
我目前的做法
主要是等待到他电平为低,在让他保持当前值
方法一:由于我在写flash的时候,将中断关闭了,而修改定时器比较值又是在定时器中断执行的,所以我关闭中断前,要将PWM输出低电平
主要修改了两个地方
1.定时器中断中,当我按键产生的标志,那么会执行下面这些,当高电平进入中断,则保持他之前输出的高电平时间,低电平的话,就让他保持当前状态
if(HAL_GPIO_ReadPin(timch->GPIOx, timch->GPIO_Pin) == GPIO_PIN_SET)//读取该定时器对应引脚电平 高电平
{
timch->count =__HAL_TIM_GET_COMPARE(&timch->htim, timch->channel) + (4864+Buf[rps[timch->rpspin].mode]-2048);
timch->count = (timch->count>TIM_PERIOD) ? (timch->count-TIM_PERIOD) : (timch->count);//比较值大于重装载值 减去重装载值
__HAL_TIM_SET_COMPARE(&timch->htim, timch->channel, timch->count); //设置比较值
}
else //低电平
{
__HAL_TIM_SET_COMPARE(&timch->htim, timch->channel,64000); //保持当前电平
}
2.在写flash前,等待电平为低,再输出64000(100%)保持当前电平
while(HAL_GPIO_ReadPin(TIMCH_Buff[i].GPIOx, TIMCH_Buff[i].GPIO_Pin) != GPIO_PIN_RESET){ }
__HAL_TIM_SET_COMPARE(&TIMCH_Buff[i].htim, TIMCH_Buff[i].channel, 64000);
__disable_irq();
Write_Flash_Buf(FLASH_RF_PIN_MODE_ADR,(uint8_t *) modebuff, sizeof(modebuff));
Write_Flash_Buf(FLASH_RF_PIN_DATA_ADR, Slave_re_Pindata_temp, sizeof(Slave_re_Pindata_temp));
__enable_irq();
方法二:当写flash前后没有对中断进行开关
那么可以直接在写flash前等待他为低电平,然后对定时器输出进行关闭,写完之后再开启
while(HAL_GPIO_ReadPin(TIMCH_Buff[i].GPIOx, TIMCH_Buff[i].GPIO_Pin) != GPIO_PIN_RESET){ }
HAL_TIM_OC_Stop_IT(&TIMCH_Buff[i].htim, TIMCH_Buff[i].channel);
Write_Flash_Buf(FLASH_RF_PIN_MODE_ADR,(uint8_t *) modebuff, sizeof(modebuff));
Write_Flash_Buf(FLASH_RF_PIN_DATA_ADR, Slave_re_Pindata_temp, sizeof(Slave_re_Pindata_temp));
HAL_TIM_OC_Start_IT(&TIMCH_Buff[i].htim, TIMCH_Buff[i].channel);
此次记录,主要是因为PWM输出到舵机时,当我按键按下后,在进行写flash的时候,舵机出现抖动,通过逻辑分析仪采集到PWM输出波形会出现20ms高电平,20ms低电平(因为关闭中断了,而修改比较值是在定时器中断中),现在通过上述方法,在写flash时,舵机不会出现抖动,逻辑分析仪采集的现象在写flash的时候,PWM波形是低电平。
文章如有问题,欢迎大家进行指正!