2023-11-13 06:36 AM
/* USER CODE BEGIN 2 */
if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1) != HAL_OK)
Error_Handler();
if (HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1) != HAL_OK) // turn on complementary channel
Error_Handler();
if (HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_2) != HAL_OK)
Error_Handler();
if (HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1) != HAL_OK)
Error_Handler();
if (HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_1) != HAL_OK) // turn on complementary channel
Error_Handler();
if (HAL_TIM_OC_Start(&htim8, TIM_CHANNEL_2) != HAL_OK)
Error_Handler();
if (HAL_TIM_PWM_Start(&htim20, TIM_CHANNEL_1) != HAL_OK)
Error_Handler();
if (HAL_TIMEx_PWMN_Start(&htim20, TIM_CHANNEL_1) != HAL_OK) // turn on complementary channel
Error_Handler();
/* USER CODE END 2 */
Solved! Go to Solution.
2023-11-14 08:13 AM
Oh, I forget to post the solution for the problem:
/* USER CODE BEGIN 2 */
htim20.Instance->CCER |= (TIM_CCx_ENABLE << TIM_CHANNEL_1);
htim20.Instance->CCER |= (TIM_CCx_ENABLE << 0x02); // complementary channel
htim20.Instance->BDTR |= (TIM_BDTR_MOE); // set outputs
htim20.Instance->CR1 &= ~(TIM_CR1_CEN); // disable timer
htim20.Instance->CNT = 0; // reset timer
htim8.Instance->CCER |= (TIM_CCx_ENABLE << TIM_CHANNEL_1);
htim8.Instance->CCER |= (TIM_CCx_ENABLE << 0x02); // complementary channel
htim8.Instance->CCER |= (TIM_CCx_ENABLE << 0x04); // Compare on Channel 2 output
htim8.Instance->BDTR |= (TIM_BDTR_MOE); // set outputs
htim8.Instance->CR1 &= ~(TIM_CR1_CEN); // disable timer
htim8.Instance->CNT = 0; // reset timer
htim1.Instance->CCER |= (TIM_CCx_ENABLE << TIM_CHANNEL_1);
htim1.Instance->CCER |= (TIM_CCx_ENABLE << 0x02); // complementary channel
htim1.Instance->CCER |= (TIM_CCx_ENABLE << 0x04); // Compare on Channel 2 output
htim1.Instance->BDTR |= (TIM_BDTR_MOE); // set outputs
htim1.Instance->CR1 &= ~(TIM_CR1_CEN); // disable timer
htim1.Instance->CNT = 0; // reset timer
htim1.Instance->CR1 |= (TIM_CR1_CEN); // enable timer
/* USER CODE END 2 */
2023-11-13 10:56 AM
Hello @Jony404 ,
If your main point is to drive only one motor with three phases, you need only one timer. The 3 sine waves are generated thanks to the variation of the duty cycles of the channels CH1/CH1N, CH2/CH2N, CH3/CH3N. Those duty cycles are configured with the respective Capture and Compare registers respectively CCR1,CCR2,CCR3.
Now the question, I would ask is what kind of AC motor do you use ? Synchronous or Asynchronous ?
The best advice I can give you is to download the MCSDK and generate a motor control project based on STM32G4. MCSDK fully supports Synchronous ( PMSM ) motors and provides example for Asynchronous motor. In any case, the MCSDK will generate for you the complete source code of your project and also a cubeMX IOC file. It will be a very good starting point for learning the basics of STM32 configuration for motor control application.
Hope it helps.
Cedric
2023-11-13 11:41 PM
Hello @cedric H ,
Wow, I didn't assume that such an advanced tool is available, I am really impressed, nice job!
I dowloaded it, and trying to configure what I would like to achieve, and I will come back with the result.
Many thank!
Zsolt
2023-11-14 12:04 AM
The original question's problem usually lies in incorrectly started slave timers. The point of slave-mode controller in Trigger mode is, that when trigger arrives, the TIMx_CR1.CEN bit is set, that's all. In other words, you are not supposed to set that bit "manually", and you are also not supposed to enable the master timer (set its TIMx_CR.CEN) before all slave timers are set up. A good way to check if this all is fulfilled is to set up everything except setting master timer's TIMx_CR.CEN, and at that point read out and check all timer's registers if they are set as expected.
When it comes to something which can't be get working simply by clicking in CubeMX, Cube usually gets more into way than helps, as the various Cube/HAL functions have intertwined behaviour and consequences of calling each function may not be fully inferred just from that function's name, and they don't map directly to functionality described in the RM.
You may want to explore the path Cedric outlined above, but IMO even then having an understanding how the hardware works makes life easier. Such understanding is achieved by writing a bunch of simple experimental programs working at the register level, or even just experimenting with the timers' registers in debugger, and observing the resulting behaviour.
JW
2023-11-14 08:11 AM
@cedric H and @waclawek.jan thank you for your suggestions!
I finally solved it with a help of this thread, and with your suggestions.
Thank you very much.
2023-11-14 08:13 AM
Oh, I forget to post the solution for the problem:
/* USER CODE BEGIN 2 */
htim20.Instance->CCER |= (TIM_CCx_ENABLE << TIM_CHANNEL_1);
htim20.Instance->CCER |= (TIM_CCx_ENABLE << 0x02); // complementary channel
htim20.Instance->BDTR |= (TIM_BDTR_MOE); // set outputs
htim20.Instance->CR1 &= ~(TIM_CR1_CEN); // disable timer
htim20.Instance->CNT = 0; // reset timer
htim8.Instance->CCER |= (TIM_CCx_ENABLE << TIM_CHANNEL_1);
htim8.Instance->CCER |= (TIM_CCx_ENABLE << 0x02); // complementary channel
htim8.Instance->CCER |= (TIM_CCx_ENABLE << 0x04); // Compare on Channel 2 output
htim8.Instance->BDTR |= (TIM_BDTR_MOE); // set outputs
htim8.Instance->CR1 &= ~(TIM_CR1_CEN); // disable timer
htim8.Instance->CNT = 0; // reset timer
htim1.Instance->CCER |= (TIM_CCx_ENABLE << TIM_CHANNEL_1);
htim1.Instance->CCER |= (TIM_CCx_ENABLE << 0x02); // complementary channel
htim1.Instance->CCER |= (TIM_CCx_ENABLE << 0x04); // Compare on Channel 2 output
htim1.Instance->BDTR |= (TIM_BDTR_MOE); // set outputs
htim1.Instance->CR1 &= ~(TIM_CR1_CEN); // disable timer
htim1.Instance->CNT = 0; // reset timer
htim1.Instance->CR1 |= (TIM_CR1_CEN); // enable timer
/* USER CODE END 2 */
2024-04-20 01:59 PM
Hi mate, i have a question.
I used mcsdk, i want to drive my pmsm motor 200v. I used stm32g431 and coustem board. So after rectifier Ac 220v i will get 310v DC but my motor only suport 200v, so how to reduce duty cycle to around 55-60%MAX?? So i will get avarage not more than 200v. This use by pulse value??
Because some people tell me used __weak PWMC_setphasavoltage sir.
Can u help me?? Still stuck on this configuration