cancel
Showing results for 
Search instead for 
Did you mean: 

Changing a PWM complementary pins to GPIO functionality and then back to PWM at runtime

Ricko
Senior

Hi,

I am running TMR1 CH1 and CH1N in complementary mode (so they are the opposite of each other).

 

Using a HAL function, how do I change each (separately) from PWM to GPIO and back to PWM?

 

Just so to explain what I am trying to do... I am driving a H-bridge, I want to be able to:

- run the PWM in complementary mode (i.e. biphase/bipolar bridge)

- fix one half of the bridge to high or low while the other side still runs in PWM

- switch both to either high or low

- go back to full PWM complementary

 

Thank you

6 REPLIES 6
TDK
Guru

Use HAL_GPIO_Init to initialize them as GPIO_MODE_OUTPUT_PP, and control their states with HAL_GPIO_WritePin.

When you want to switch back to PWM mode, call HAL_GPIO_Init again and set them up in alternate function TIM mode. If you've set the timer up in PWM mode in CubeMX, the initialization calls to set the pins in PWM mode are in HAL_TIM_MspInit, call that again or call it within your own code.

If you feel a post has answered your question, please click "Accept as Solution".

Thank you @TDK,

 

I also just came across HAL_TIM_PWM_DeInit(). Do I need to use it or is it better not to?

 

In the documentation it just says that it deinitialises the timer and I am not sure what that means exactly... it is not clear which functionality is actually reset.

This is the API document I am looking at, is there a more comprehensive one perhaps?

 

Thank you 🙂

 

> I also just came across HAL_TIM_PWM_DeInit(). Do I need to use it or is it better not to?

I wouldn't. You can change the pins and keep the timer going in the background. That seems easiest for your use case.

> This is the API document I am looking at, is there a more comprehensive one perhaps?

The reference manual will detail exactly how the timers work. If you want the intimate details, that is the reference to look at.

If you feel a post has answered your question, please click "Accept as Solution".

Thank you @TDK 

I just tried implementing what you suggested i.e. calling HAL_TIM_MspInit() but there is no sign of it in the generated code anywhere in the project. There are other MspInit() functions as you can see from the screenshot here but not that one.

 

Ricko_3-1722822788563.png

 

The only functions generated by CubeMX are these:

 

Ricko_4-1722822815619.png

 

I am new to STM32 so I am wondering if it could be because I am using CH1 and CH1N with TMR1 configured like in the screenshot below? The generated complementary PWM outputs are correct on the oscilloscope but perhaps I configured it incorrectly or in a less than ideal manner (although )? Maybe using different settings would generate the HAL_TIM_MspInit() you are referring to?  Or perhaps I need to #include some header?

 

Ricko_0-1722822285588.png

 

Thank you again! 🙂

TDK
Guru

HAL_TIM_PWM_MspInit probably. Or maybe HAL_TIM_Base_MspInit

Whatever function the pins are initialized in.

If you feel a post has answered your question, please click "Accept as Solution".

Thank you @TDK 

 

I have been looking at all those functions, but unless I am missing something, it does not appear the pins are initialised in any of them. Below is the code from the three functions: HAL_TIM_Base_MspInit(), HAL_TIM_PWM_MspInit() and MX_GPIO_Init().

 

I can see all other pins but not the PWM pins.

 

The PWM pin names are OUTPUT_PWM_2 and OUTPUT_PWM_1 on PA7 and PA8. But I don't see them addressed anywhere in any of the project files.

 

How do I find out where the initialisation is done and be sure whichever function that is, it is the correct one to call to revert to PWM setup by MX?

 

static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, EXT_FLASH_CS_Pin|LED1_Pin|LED_POWER_Pin|LED3_Pin, GPIO_PIN_RESET);

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, LED2_Pin|STPR_ENABLE_Pin|STPR_RESET_Pin|STPR_SLEEP_Pin
|STPR_DIR_Pin|uSD_CS_Pin, GPIO_PIN_RESET);

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, ENZYME_SNS_RST_Pin|LED_BATT_LOW_Pin|LED_CARTRIDGE_Pin|LED_TEMP_Pin, GPIO_PIN_RESET);

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LED_ENZYME_LOW_GPIO_Port, LED_ENZYME_LOW_Pin, GPIO_PIN_SET);

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(OUTPUT_EN_1_GPIO_Port, OUTPUT_EN_1_Pin, GPIO_PIN_SET);

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(OUTPUT_EN_2_GPIO_Port, OUTPUT_EN_2_Pin, GPIO_PIN_SET);

/*Configure GPIO pins : USER_BTN_1_Pin KEYPAD_I2C_INT_AN_Pin ENZYME_SNS_OUT_2_Pin ENZYME_SNS_OUT_1_Pin
USER_BTN_2_Pin */
GPIO_InitStruct.Pin = USER_BTN_1_Pin|KEYPAD_I2C_INT_AN_Pin|ENZYME_SNS_OUT_2_Pin|ENZYME_SNS_OUT_1_Pin
|USER_BTN_2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/*Configure GPIO pins : EXT_FLASH_CS_Pin LED1_Pin LED_POWER_Pin LED3_Pin */
GPIO_InitStruct.Pin = EXT_FLASH_CS_Pin|LED1_Pin|LED_POWER_Pin|LED3_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/*Configure GPIO pins : FLOW_SW_Pin CARTRIDGE_SW_Pin INT_TEMP_ALRM_Pin uSD_CD_Pin */
GPIO_InitStruct.Pin = FLOW_SW_Pin|CARTRIDGE_SW_Pin|INT_TEMP_ALRM_Pin|uSD_CD_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/*Configure GPIO pins : LED2_Pin STPR_ENABLE_Pin STPR_RESET_Pin STPR_SLEEP_Pin
STPR_DIR_Pin OUTPUT_EN_2_Pin uSD_CS_Pin */
GPIO_InitStruct.Pin = LED2_Pin|STPR_ENABLE_Pin|STPR_RESET_Pin|STPR_SLEEP_Pin
|STPR_DIR_Pin|OUTPUT_EN_2_Pin|uSD_CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/*Configure GPIO pins : ENZYME_SNS_RST_Pin LED_BATT_LOW_Pin LED_ENZYME_LOW_Pin LED_CARTRIDGE_Pin
LED_TEMP_Pin */
GPIO_InitStruct.Pin = ENZYME_SNS_RST_Pin|LED_BATT_LOW_Pin|LED_ENZYME_LOW_Pin|LED_CARTRIDGE_Pin
|LED_TEMP_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/*Configure GPIO pin : OUTPUT_EN_1_Pin */
GPIO_InitStruct.Pin = OUTPUT_EN_1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(OUTPUT_EN_1_GPIO_Port, &GPIO_InitStruct);

/*Configure GPIO pin : PB4 */
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/*Configure GPIO pin : uC_BOOT0_Pin */
GPIO_InitStruct.Pin = uC_BOOT0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(uC_BOOT0_GPIO_Port, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

 

 

Ricko_0-1722826616372.png

Ricko_1-1722826639629.png

 

Thank you 🙂