Skip to main content
Graduate
August 21, 2025
Solved

unexpected PWM is observed at output side.

  • August 21, 2025
  • 2 replies
  • 506 views

Hi All,

I am writing a code to generate an PWM at output. I want to drive an H-bridge outside.All initializations I have done.

I am using TIM1 (advanced timer) for this purpose. I am using STM32F Discovery Board (Microcontroller is STM32F407) and STM32CubeIDE 1.19.0 

 

The issue I am facing is whenever I get an interrupt i tried to load value from the LUT but its not working and generate unexpected PWM at output but when I load any fix value then PWM is generated at the output.

I am wondering why it is not generating the PWM from LUT.

below is my code. kindly tell me what I am doing wrong

 

volatile uint16_t sineIndex = 0;
#define SINE_TABLE_SIZE 10
uint16_t sineTable[SINE_TABLE_SIZE] = {400, 657, 794, 746, 537, 263, 54, 6, 143, 400};

int main(){
	HAL_Init();
	System_Clock_Source();
	UART2_Init();
	MX_GPIO_Init();
	MX_TIM1_Init();	// Here all the settings are done related to PWM timings
	MX_TIM2_Init();

	SPWM_Start();
}

void MX_GPIO_Init(void) {
 GPIO_InitTypeDef GPIO_InitStruct = {0};

 // Enable GPIO clocks
 __HAL_RCC_GPIOE_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();

 // Configure TIM1 PWM outputs (PA8=CH1, PA9=CH1N, PB0=CH2N, PB1=CH2)
 GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

 // For Debugging purpose
 GPIO_InitStruct.Pin = GPIO_PIN_15;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

 // For Debugging purpose
 GPIO_InitStruct.Pin = GPIO_PIN_14;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}

void MX_TIM1_Init(void) {
 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 TIM_OC_InitTypeDef sConfigOC = {0};
 TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

 htim1.Instance = TIM1;
 htim1.Init.Prescaler = 9;
 htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
 htim1.Init.Period = 800 - 1;
 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim1.Init.RepetitionCounter = 0;
 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
 HAL_TIM_PWM_Init(&htim1);

 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig);

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);

 sConfigOC.OCMode = TIM_OCMODE_PWM1;
 sConfigOC.Pulse = sineTable[0];
 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;
 HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
 HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2);

 sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
 sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
 sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
 sBreakDeadTimeConfig.DeadTime = 10;
 sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
 sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
 sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
 HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig);
}

void MX_TIM2_Init(void) {
 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
 TIM_MasterConfigTypeDef sMasterConfig = {0};

 htim2.Instance = TIM2;
 htim2.Init.Prescaler = 80; // 50Hz
 htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim2.Init.Period = 1000 - 1;
 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
 HAL_TIM_Base_Init(&htim2);
}

void SPWM_Start(void) {
 // Start PWM generation
 HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
 HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
 HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
	HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
 // Start synchronization timer (50Hz)
 HAL_TIM_Base_Start_IT(&htim2);

 // Start SPWM update timer (10kHz)
 HAL_TIM_Base_Start_IT(&htim1);
}

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim){
	if(htim->Instance == TIM1){
		// 1. Enable the Clock for TIMER1
		__HAL_RCC_TIM1_CLK_ENABLE();

		// 3. Enable the IRQ and set the Priority (NVIC Settings)
		HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
		HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0);
	}
}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base){
	if(htim_base->Instance == TIM2){
		// Enable clock for TIMER2
		__HAL_RCC_TIM2_CLK_ENABLE();

		// Enable TIM2 interrupts
		HAL_NVIC_EnableIRQ(TIM2_IRQn);
		HAL_NVIC_SetPriority(TIM2_IRQn, 10, 0);
	}
}

void TIM1_UP_TIM10_IRQHandler(void) {
 HAL_TIM_IRQHandler(&htim1);
}

// 50Hz interrupt handler
void TIM2_IRQHandler(void) {
 HAL_TIM_IRQHandler(&htim2);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
	if (htim->Instance == TIM1) {
		HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);
		__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, sineTable[0]);
//		sineIndex = (sineIndex + 1) % SINE_TABLE_SIZE;
	}
	else if (htim->Instance == TIM2) {
	 HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
	}
}

 now in the HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) when i do like sineTable[0], then value at 0 location is updated and generate 50% duty cycle continuously as expected but when i do like sineTable[sineIndex] and uncomment sineIndex = (sineIndex + 1) % SINE_TABLE_SIZE then the problem arises.

Kindly guide me what I am missing 

    This topic has been closed for replies.
    Best answer by AHayee

    @Saket_Om Thanks for your reply. 

    Actually I am confused my code is working now but why it was not working before. 

    I am getting the actual output as I required.

    I am working more on this and adding other functionalities. If find any issue then I will get back to you

    Thanks again for your help

    2 replies

    Technical Moderator
    August 21, 2025

    Hello @AHayee 

    Please add a debug print or toggle to check the value of  sineIndex and the value being written.

    HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);
    uint16_t value = sineTable[sineIndex];
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, value);
    sineIndex = (sineIndex + 1) % SINE_TABLE_SIZE;
    AHayeeAuthorAnswer
    Graduate
    August 22, 2025

    @Saket_Om Thanks for your reply. 

    Actually I am confused my code is working now but why it was not working before. 

    I am getting the actual output as I required.

    I am working more on this and adding other functionalities. If find any issue then I will get back to you

    Thanks again for your help