cancel
Showing results for 
Search instead for 
Did you mean: 

unexpected PWM is observed at output side.

AHayee
Associate II

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 

1 REPLY 1
Saket_Om
ST Employee

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;
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.
Saket_Om