2020-04-17 06:02 AM
Hello,
i am using the STM32F103C6 MCU and i would like to produce 3 different Center Aligned PWM signals with 16KHz frequency and Duty Cycle 1 to 99%. I would like to change the duty cycle on fly using the CCR registers.
I am configuring the 3 of TIM1's channels as Output Compare:
Then i choose the Center Aligned_3 mode and setting the frequency on 16KHz (frequency is correct):
Finally, every channel has the same settings as below:
With CubeMX's default code, i am just starting the OC and setting the desired pulse:
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM1_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_3);
TIM1->CCR1 = 400; //Channel_1 ~ 82% Duty Cycle
TIM1->CCR2 = 1125; //Channel_2 ~ 50% Duty Cycle
TIM1->CCR3 = 2200; //Channel_3 ~ 2% Duty Cycle
And on simulator everything is correct:
If we change the CCR1 to lower value:
TIM1->CCR1 = 100; //Channel_1 95% Duty Cycle
Seems like Channel 1 is not aligned with the others, like it is shifted:
2020-04-17 06:32 AM
Firstly you can directly use the "PWM Generation CHx" option from the CubeMx dropdown for each channel. This will readily give you the PWM depending on the pulse and period values. I used the same to generate 3 output PWMs for my motor project.
Thanks
2020-04-17 06:51 AM
Yeah, its about motor project and SVM.
I will try your suggestion.
2020-04-17 08:16 AM
Now i am using the "PWM Generation CHx" option but i am still facing issues with the alignment.
With the below settings:
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 = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3;
htim1.Init.Period = 2250-1;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
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.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 100;
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();
}
sConfigOC.Pulse = 500;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
sConfigOC.Pulse = 700;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
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);
}
The output looks like this:
2020-04-18 05:06 AM
I have done similar projects with 8bit MCU from other manufacturer, as i remember there were some limitations on duty cycle on center aligned PWM (could not go to 0% or 100% - you had to select).
So there is the same issue here, a cube bug or what? Could someone help?
2020-04-18 01:40 PM
Try on real hardware.
JW
2020-04-18 01:45 PM
Due to quarantine, i have not access to oscilloscope. That's why i am using simulator.
I don't think the problem is Proteus-Simulator.