2016-06-23 01:55 AM
Hi Guys,
I am currently working on a PWM signal of f = 5kHz (T= 200us) with the 32-bit general purposte timer 2. While testing my implementation I am observing a strange behaviour. At the moment I am not sure if I pushed the boundaries of timer 2 to much or it is an implementation problem.
The issue is that the high signal becomes a low signal if I make my duty cycle to small, in this my, when I go below 1us or 1/200 of T.
My code looks as follows:
TIM2_TE_ERR TIM2_Init(
void
){
//=== local vars ==============================================================
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*** power supply timer configuration {SIG_T2CH4_VLTG_LVL_TO} == ***/
SYSC_ClockEnable(CNFG_GPIO_SIG_T2CH4_VLTG_LVL_TO_PORT);
GPIO_InitStruct.Pin = CNFG_GPIO_SIG_T2CH4_VLTG_LVL_TO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
/* set to output */
GPIO_InitStruct.Pull = GPIO_GetPull(CNFG_GPIO_SIG_T2CH4_VLTG_LVL_TO_LOGIC, CNFG_GPIO_SIG_T2CH4_VLTG_LVL_TO_DEFLVL);
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = CNFG_GPIO_SIG_T2CH4_VLTG_LVL_TO_AF;
(
void
)GPIO_InitPin(CNFG_GPIO_SIG_T2CH4_VLTG_LVL_TO_PORT, &GPIO_InitStruct, GPIO_TYPE_TIM, TRUE
/*force*/
);
/* === code === */
/*** initialize module control structure ***/
if
(TRUE == _this.bIsInitialized) {
_DeInit();
}
/* </ (TRUE == _this.bIsInitialized) > */
/* === configuration of the PWM-timer === */
/* enable clock of PWM timer */
TIM2_TIMER_FORCE_RESET;
TIM2_TIMER_RELEASE_RESET;
TIM2_TIMER_CLK_ENABLE;
/* Set TIMx instance */
_this.hTimer.Instance = _TIM;
/* Master configuration: TIM3 */
_this.hTimer.Init.Prescaler = 0;
_this.hTimer.Init.Period = 16800 - 1;
/* refresh rate ~5kHz */
_this.hTimer.Init.ClockDivision = 0;
_this.hTimer.Init.RepetitionCounter = 0;
_this.hTimer.Init.CounterMode = TIM_COUNTERMODE_UP;
/* Initialize timer */
if
(HAL_TIM_PWM_Init(&_this.hTimer) != HAL_OK){
/* error - initialization failed */
_DeInit();
/* set error status */
_this.Error = _TE_ERR_FAILURE;
return
_this.Error;
}
else
{
/* no error - nothing to do */
}
/* </ if (HAL_TIM_PWM_Init() != HAL_OK) > */
/* Configure the PWM_channel_1 */
_this.sConfig.OCMode = TIM_OCMODE_PWM1;
_this.sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
_this.sConfig.OCNPolarity = TIM_OCNPOLARITY_LOW;
_this.sConfig.OCFastMode = TIM_OCFAST_ENABLE;
_this.sConfig.OCIdleState = TIM_OCIDLESTATE_SET;
_this.sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
/* set the pulse value for channel 4 */
_this.sConfig.Pulse = (16800/100);
/* 1% PWM default */
if
(HAL_TIM_PWM_ConfigChannel(&_this.hTimer, &_this.sConfig, _OUT_CHANNEL) != HAL_OK){
/* set error status */
_this.Error = _TE_ERR_FAILURE;
return
_this.Error;
}
else
{
/* no error - nothing to do */
}
/* </ if (HAL_TIM_PWM_ConfigChannel() != HAL_OK) > */
/* set state to initialized */
_this.State = _TE_STATE_INIT;
/* finalize initialization */
_this.bIsInitialized = TRUE;
/* successful - set error status */
_this.Error = _TE_ERR_NONE;
return
_this.Error;
}
What gets me totally confused is the fact that a configuration of 50kHz on the 16-bit timer11 is working with a much smaller high time.
Has anybody a idea? Is this a hardware restiction?
Thank you
#solved #stm32f4 #timer #pwm2016-06-23 04:42 AM
Hi life_augmented.st,
It does not make a sense that it didn't work with TIM2. Try to make a test with a higher duty cycle (i.e 50%) and tell me if that works or not. -Hannibal-2016-06-23 05:17 AM
Hi Hannibal,
It works for duty cycles bigger than 0.5% (~1us). As I said before, I cant wrap my head around the problem at the moment. I will try to make an minimal example for two chips that I have access to F429 and F427. This is not the only issue at the moment but I will investigate more. In the meantime, if somebody has an idea I would be more than happy to get a hint.Regards2016-06-23 06:16 AM
I can't say I've had issues with 32-bit timers, I suspect your issues are on the software side than the hardware.
2016-06-23 06:43 PM
I suggest that you debug the build and inspect the TIM2 registers (with reference to the relevant section of the reference manual), both before the fault occurs and after it has occurred. If the registers contain the values that you expect and the fault still occurs, then it's probably hardware (although my experience is that the STM32 timer hardware works very well, so I doubt it's this); if the registers don't contain the expected values when it faults then it's probably software, i.e. the HAL.
2016-06-24 02:55 AM
Hi life_augmented.st,
I suggest that you run a PWM example in STM32CubeF4 after modifying it according to your conditions. Compare the code to your code. -Hannibal-2016-06-24 04:08 AM
Not sure if its your problem but just more of a general comment:
I have had problems before where I neglected to initialize all of the members of one of these init structs, which later caused a problem as the members had random uninitialized values which then got OR-ed into the registers.Not sure which hal you have, but e.g I have TIM_OnePulse_InitTypeDef with 9 members, I see you have initialized 7 of them, are you sure the other two are 0?2016-06-27 05:05 AM
After further investigation of my problem, I found the issue.
I was measuring the PWM after an inverter, which is not fast enough. The inverter causes problems below 1us. Measuring at the PIN's of the stm32f4x9 controller has the proper output.Thank you for all your suggestions and help.