I used STCube to generate my code in order to get a different duty cycle on two different pins of the same timer on my Nucleo F446ZE board. It works for the most part, both pins have the same frequency but they both have the same duty cycle as well, the duty cycle I set up as PULSE1_VALUE. I've tried several things including trying to replicate the example code for PWM outputs that came with the F446Ze board but I can't seem to get my TIM_CHANNEL_2 pin to toggle at a different duty cycle. Here's the relevant code:
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim2;
/* Private typedef -----------------------------------------------------------*/
#define PERIOD_VALUE (uint32_t)(661-1) /* Period Value */ counter clock of 15MHz and period of 660 gives a frequency of 22.7kHz
#define PULSE1_VALUE (uint32_t)(PERIOD_VALUE*12.5/100) /* Capture Compare 1 Value 12.5% duty */
#define PULSE2_VALUE (uint32_t)(PERIOD_VALUE*1/100) /* Capture Compare 2 Value 1%duty*/
TIM2 init function
static void MX_TIM2_Init(void)
{
uhPrescalerValue = (uint32_t)((SystemCoreClock/2)/15000000)-1; //this gives a counter frequency of 15MHz. SystemCoreClock is 180MHz
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_SlaveConfigTypeDef sSlaveConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_OC_InitTypeDef sConfigOC;
memset(&sConfigOC, 0, sizeof(sConfigOC));
htim2.Instance = TIM2;
htim2.Init.Prescaler = uhPrescalerValue;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = PERIOD_VALUE; //660 in this case
htim2.Init.ClockDivision = 0;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_DISABLE;
sSlaveConfig.InputTrigger = TIM_TS_ITR0;
if (HAL_TIM_SlaveConfigSynchronization(&htim2, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;//TIM_OCFAST_DISABLE;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
//sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
sConfigOC.OCIdleState = TIM_OCNIDLESTATE_SET;//TIM_OCIDLESTATE_RESET;
sConfigOC.Pulse = PULSE1_VALUE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sConfigOC.Pulse = PULSE2_VALUE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
HAL_TIM_MspPostInit(&htim2);
//HAL_TIM_Base_Start(&htim2);
/*##-3- Start PWM signals generation #######################################*/
/* Start channel 1 */
if (HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1) != HAL_OK)
{
/* PWM Generation Error */
Error_Handler();
}
/* Start channel 2 */
if (HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2) != HAL_OK)
{
/* PWM Generation Error */
Error_Handler();
}
}
I'm thinking it could be something with the way I'm setting up the GPIO for the two pins I want to control in the stm32f4xx_hal_msp.c file but I've seen other people set it up the exact same way on other sites: https://visualgdb.com/tutorials/arm/stm32/pwm/
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(htim->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspPostInit 0 */
/* TIMx Peripheral clock enable */
//TIMx_CLK_ENABLE();
/* USER CODE END TIM2_MspPostInit 0 */
/**TIM2 GPIO Configuration
PA0-WKUP ------> TIM2_CH1
PA1 ------> TIM2_CH2
*/
GPIO_InitStruct.Pin = ext_LED_1_Pin|ext_LED_2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN TIM2_MspPostInit 1 */
/* USER CODE END TIM2_MspPostInit 1 */
}
}