cancel
Showing results for 
Search instead for 
Did you mean: 

Frequency_Modulation

PRAKKU12
Associate

Hii, 

I am using STM32H503RBT6 controller. I have a requirement of frequency modulation in my project.

Based on a GPIO state i try to switch between the frequencies of 200k and 300k.

in my configuration, by default i configured for 300k and after shifting to 200k by GPIO state, there is some small glitch of PWM pulse. Again when i try to shift to my old frequency based on the gpio state, the PWM duty is mismatching. It is not either 300k or 200k.

this is my timer initialization.

void TIM3_IRQHandler(void)

{

/* USER CODE BEGIN TIM3_IRQn 0 */

if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_2) == 1)

{

switch_off_cntr = 0;

switch_on_cntr++;

if(switch_on_cntr == 1000)

{

while((htim1.Instance->CR1 & TIM_CR1_DIR) == 0);

while((htim1.Instance->CR1 & TIM_CR1_DIR) != 0);

TIM1->CR1 &= ~TIM_CR1_ARPE;

TIM1->PSC = 2;

TIM1->CR1 |= TIM_CR1_ARPE;



TIM1->CCMR1 &= ~TIM_CCMR1_OC1PE;

TIM1->CCR1 = 104;

TIM1->CCMR1 |= TIM_CCMR1_OC1PE;

TIM1->EGR |= TIM_EGR_UG;

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, 1);



switch_on_cntr = 0;

}

}

else

{



switch_on_cntr = 0;

switch_off_cntr++;

if(switch_off_cntr == 1000)

{

TIM1->CR2 = (1<<0);

while((htim1.Instance->CR1 & TIM_CR1_DIR) == 0);

while((htim1.Instance->CR1 & TIM_CR1_DIR) != 0);





TIM1->CR1 &= ~TIM_CR1_ARPE;

TIM1->PSC = 1;

TIM1->ARR = 208;

TIM1->CR1 |= TIM_CR1_ARPE;



TIM1->CCMR1 &= ~TIM_CCMR1_OC1PE;

TIM1->CCR1 = 104;

// TIM1->CCMR1 |= TIM_CCMR1_OC1PE;

TIM1->EGR |= TIM_EGR_UG;

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, 0);



switch_off_cntr = 0;

}

}

/* USER CODE END TIM3_IRQn 0 */

HAL_TIM_IRQHandler(&htim3);

/* USER CODE BEGIN TIM3_IRQn 1 */



/* USER CODE END TIM3_IRQn 1 */

}



/* USER CODE BEGIN 1 */



This is my code which i have written in interrupt.there is no other interrupt.

static void MX_TIM1_Init(void)

{



/* USER CODE BEGIN TIM1_Init 0 */



/* USER CODE END TIM1_Init 0 */



TIM_ClockConfigTypeDef sClockSourceConfig = {0};

TIM_MasterConfigTypeDef sMasterConfig = {0};

TIM_OC_InitTypeDef sConfigOC = {0};

TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};



/* USER CODE BEGIN TIM1_Init 1 */



/* USER CODE END TIM1_Init 1 */

htim1.Instance = TIM1;

htim1.Init.Prescaler = 1;

htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;

htim1.Init.Period = 208;

htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim1.Init.RepetitionCounter = 0;

htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

if (HAL_TIM_Base_Init(&htim1) != HAL_OK)

{

Error_Handler();

}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)

{

Error_Handler();

}

if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

{

Error_Handler();

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)

{

Error_Handler();

}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 104;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

{

Error_Handler();

}

sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;

sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;

sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

sBreakDeadTimeConfig.DeadTime = 49;

sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

sBreakDeadTimeConfig.BreakFilter = 0;

sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT;

sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;

sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;

sBreakDeadTimeConfig.Break2Filter = 0;

sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT;

sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;

if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN TIM1_Init 2 */



/* USER CODE END TIM1_Init 2 */

HAL_TIM_MspPostInit(&htim1);



} 

for any solution thanks in advance

1 REPLY 1
Sarra.S
ST Employee

Hello @PRAKKU12, thank you for the interesting question

When you change PSC/ ARR, you should synchronize with the timer's update event to avoid glitches 

I suggest using the double buffering, I can see from your code you're enabling the the auto-reload preload after changing PSC/ARR:

 

TIM1->CR1 &= ~TIM_CR1_ARPE;

TIM1->PSC = 1;

TIM1->ARR = 208;

TIM1->CR1 |= TIM_CR1_ARPE;

 

Ideally, you want to enable the ARPE bit before changing the PSC and ARR values to ensure that the changes are double-buffered and only applied at the next update event

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.