给位前辈,我在利用STM32同一个定时器比较输出模式产生4路不同的频率方波的实验中,遇到一个问题,请教各位:
思路:使用TIM3的比较输出,设置输出自动翻转,在中断中更新CCR寄存器,
u32 PWM_M[8]; // 高频率PWM输出比较值,用来更新CCR寄存器
现象1:当新的比较值PWM_M[n]=300左右,即输出频率为40KHz后,波形紊乱(会有较长时间的高低电平,同时会夹杂着40KHz的波形)
现象2:修改TIM_TimeBaseStructure.TIM_Prescaler = 2为5后,更改PWM_M[n]=150,发现40KHz波形正确,但是PWM_M[n]继续调小增大波形后,在60KHz左右波形再次紊乱
修改TIM_TimeBaseStructure.TIM_Prescaler = 5为11后,更改PWM_M[n]可以调出60KHz的波形,但是100KHz左右波形再次紊乱。
问题:理论上100khz的中断频率程序处理起来应该没问题,不知道为何我这个程序输出会紊乱;TIM_Prescaler不知道为何对输出有上述影响?请各位不吝赐教。
下面为程序片段
/*******************************************************************************
* Function Name : RCC_Configuration
* Description : Configures the different system clocks.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void RCC_Configuration(void)
{
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div16);
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/* Enable TIM1 clock */
RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable ADC1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_USART1, ENABLE);// 使能需要使用的IO时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
}
/*******************************************************************************
//
// 设置定时器通道的输出比较值 比较输出方式 对应高频率
//
*******************************************************************************/
void PWM_Output_TIMx_Config(TIM_TypeDef* TIMx)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 2; // 24M
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; // channel-1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC1Init(TIMx, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Disable);
TIM_OCInitStructure.TIM_Pulse = 0; // channel-2
TIM_OC2Init(TIMx, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIMx, TIM_OCPreload_Disable);
TIM_OCInitStructure.TIM_Pulse = 0; // channel-3
TIM_OC3Init(TIMx, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIMx, TIM_OCPreload_Disable);
TIM_OCInitStructure.TIM_Pulse = 0; // channel-4
TIM_OC4Init(TIMx, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIMx, TIM_OCPreload_Disable);
TIM_Cmd(TIMx, ENABLE);
}
//==========================
//
// 高速脉冲定时器中断 通道1-4
//
//==========================
void TIM3_IRQHandler(void)
{
u16 capture = 0;
// OS_ENTER_CRITICAL(); // 关中断
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1 );
capture = TIM_GetCapture1(TIM3);
TIM_SetCompare1(TIM3, capture + PWM_M[0]);
}
if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
capture = TIM_GetCapture2(TIM3);
TIM_SetCompare2(TIM3, capture + PWM_M[1]);
}
if (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
capture = TIM_GetCapture3(TIM3);
TIM_SetCompare3(TIM3, capture + PWM_M[2]);
// PWM_OUT2;
}
if (TIM_GetITStatus(TIM3, TIM_IT_CC4) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);
capture = TIM_GetCapture4(TIM3);
TIM_SetCompare4(TIM3, capture + PWM_M[3]);
}
// OS_EXIT_CRITICAL(); // 开中断
}
|