2021-07-21 03:10 PM
I am trying this following program :
-run a DC motor (using PWM command) with speed "1" and wait 5 seconds then run with speed "2" and wait for 5 seconds then the motor stops .
The problem is that the motor stays in a loop : starts turning about 1 second and stops .
(It doesn't stay the 5 seconds ).
I am using stm32f4.
motor pin C7 .
I've configured my project with STM32CubeIDE .
#include "main.h"
TIM_HandleTypeDef htim3;
int puls ;
float duty ;
UART_HandleTypeDef huart2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_TIM3_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start(&htim3);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
while (1)
{puls=150 ; // motor with speed 1
duty =(puls*100)/31999;
MX_TIM3_Init();
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
HAL_Delay(5000);
puls=300 ; //motor with speed 2
duty =(puls*100)/31999;
MX_TIM3_Init();
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
HAL_Delay(5000);
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2);
}
}
static void MX_TIM3_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
htim3.Instance = TIM3;
htim3.Init.Prescaler = 31999;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 65535;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = puls;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_MspPostInit(&htim3);
}
Thanks for help
2021-07-21 06:32 PM
Timer PWM is asynchronous to whatever the cpu is doing. There shouldn't be any reason a delay would interrupt the PWM.
If you debug the code and pause it after the motor stops, but before the 5sec is up, where is it and is the timer still going?
Instead of running a motor, toggle an LED. If that works at the expected toggling rate, you know the delays are working fine.
2021-07-22 07:01 AM
This is (probably) not the cause of your problem (check your HAL_Delay as @TDK mentioned), but... Don't re-initialize the timer just to change speeds. Call MX_TIM3_Init() once, followed by HAL_TIM_Base_Start() and HAL_TIM_PWM_Start(). If you change your
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
to
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
or in CubeMX set the "auto-reload preload" to "enable". Then, once you start your PWM, to change motor speeds just write to the new PWM value to the CCR2 register.
htim3.Instance->CCR2 = puls;