Top.Mail.Ru
Уведомления
Очистить все

[Решено] Трехфазный синусоидальный ШИМ с помощью STM32

(@banan_net)
Level 1

Всем привет! Я только учусь работать с микроконтроллером и нужна помощь:) Работаю с микроконтроллером STM32G431, в программе CubeIDE. В самом коде совмещаю HAL и CMSIS. Вот мой код:
При компиляции кода ошибок никаких не возникает, при нажатии кнопки PB0 таймер запускается, проблем никаких нет. Но при нажатии кнопки PC5 происходит просто ничего:( на выходах мк нет синусоидального ШИМа. Да и частота соответственно не меняется. В чем может быть ошибка и куда мне двигаться? 
* Сразу прошу прощение за это "извращение" 
** Я пытался работать с DMA, но в ровным счетом ситуация такая же, на выходе всегда ШИМ с постоянной скважностью.

#include "main.h" 
#include "tim.h"
 #include "usart.h" 
#include "gpio.h" 
#include <math.h>
 #define BUFFER_SIZE 2000
 double pi = 3.14159;
 uint32_t sine_wave[BUFFER_SIZE] = {0}; 
uint32_t frequency = 50;
 bool increasing = true; 
float pwm_number; 
float pwm_coef; 
uint16_t i;
 float a; 
float q; 
float z; 
void generate_sine_wave();
 void configure_timer_pwm(); 
void configure_button_interrupts(); 
void EXTI0_IRQHandler(); 
void EXTI9_5_IRQHandler();
 extern TIM_HandleTypeDef htim1; 
void SystemClock_Config(void); 
void generate_sine_wave() 
{ 
if (frequency != 0)
 { 
// Число периодов ШИМ для частоты поля
 pwm_number = (10 * 16000) / frequency;
 // Коэффициент скалярного управления
 pwm_coef = (float)7; 
z = 630 / 2; 
a = (float)2.0 * (1.0 / pwm_number); 
q = 0; 
for (i = 0; i < pwm_number; i++) 
{ 
q = z + (z * sin(pi * i * a)); 
sine_wave[i] = q * pwm_coef;
 }
 }
 } 
void configure_timer_pwm()
 { RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; 
TIM1->PSC = 0; 
TIM1->ARR = 4799; 
TIM1->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // CH1 TIM1->CCMR1 |= TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1; 
TIM1->CCMR2 |= TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1; 
 TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC1NE; // CH1 инверсии 
TIM1->CCER |= TIM_CCER_CC2E | TIM_CCER_CC2NE; // CH2 инверсии 
TIM1->CCER |= TIM_CCER_CC3E | TIM_CCER_CC3NE; // CH3 инверсии 
TIM1->BDTR |= TIM_BDTR_MOE; TIM1->CR1 |= TIM_CR1_CEN;
 }
 void configure_button_interrupts()
 { RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
 SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR1_EXTI0_Msk; 
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PB;
 EXTI->RTSR1 |= EXTI_RTSR1_RT0; 
EXTI->IMR1 |= EXTI_IMR1_IM0;
 NVIC_EnableIRQ(EXTI0_IRQn); 
SYSCFG->EXTICR[1] &= ~SYSCFG_EXTICR2_EXTI5_Msk; 
SYSCFG->EXTICR[1] |= SYSCFG_EXTICR2_EXTI5_PC; 
EXTI->RTSR1 |= EXTI_RTSR1_RT5; 
EXTI->IMR1 |= EXTI_IMR1_IM5; 
NVIC_EnableIRQ(EXTI9_5_IRQn);
 } 
void EXTI0_IRQHandler()
 {
 if ((EXTI->PR1 & EXTI_PR1_PIF0) != 0)
 {
 EXTI->PR1 |= EXTI_PR1_PIF0; 
if (TIM1->CR1 & TIM_CR1_CEN)
 { TIM1->CR1 &= ~TIM_CR1_CEN; 
} 
else 
{
 configure_timer_pwm();
 }
 }
 }
 void EXTI9_5_IRQHandler() 
{
 if ((EXTI->PR1 & EXTI_PR1_PIF5) != 0)
 { 
EXTI->PR1 |= EXTI_PR1_PIF5; 
if (increasing)
 {
 frequency += 1; 
if (frequency > 400) 
{ 
frequency = 400; 
increasing = false; 
}
 }
 else {
 frequency -= 1;
 if (frequency < 50) { 
frequency = 50;
 increasing = true; }
 } 
generate_sine_wave();
 }
 }
 int main(void)
 { HAL_Init();
 SystemClock_Config();
 HAL_TIM_Base_Start_IT(&htim1); 
MX_GPIO_Init(); 
MX_TIM1_Init(); 
MX_USART2_UART_Init(); 
HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1); HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2); HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2); HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_3); HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3); 
generate_sine_wave(); 
configure_timer_pwm(); 
configure_button_interrupts(); 
while (1)
 {
 if (i >= pwm_number)
 { i = 0; } 
if (htim1.Instance == TIM1) 
{ TIM1->CCR1 = sine_wave[i]; 
TIM1->CCR2 = sine_wave[i + (int)(pwm_number / 3)]; 
TIM1->CCR3 = sine_wave[i + (int)(2*pwm_number / 3)]; i++; } } }


Цитата
Создатель темы Размещено : 02.11.2023 12:03
Aveal
(@aveal)
Top level Admin

Привет! Надо под отладчиком посмотреть поэтапно, попадает ли в обработчик нажатия PC5, затем, какие значения непосредственно в CCRx записываются и что в массиве sine_wave[] генерируется в итоге, какие значения.

ОтветитьЦитата
Размещено : 02.11.2023 12:22
(@banan_net)
Level 1

@aveal обработчик попадает, но такое ощущение, что он записывает только 1 число в массива, скважность 1 раз изменилась и все. как заставить, чтобы он постоянно считывал значения с массива не понимаю. 🙁

ОтветитьЦитата
Создатель темы Размещено : 02.11.2023 12:26
Aveal
(@aveal)
Top level Admin

@banan_net а в sine_wave[] разные значения, адекватные?

ОтветитьЦитата
Размещено : 02.11.2023 12:39
Aveal
(@aveal)
Top level Admin

Кстати в основном цикле, там где:

TIM1->CCR1 = sine_wave[i];

надо какую-то задержку как минимум, потому что в CCR значение обновляется на каждом цикле, таймер не успевает новый сигнал физически сгенерировать.

ОтветитьЦитата
Размещено : 02.11.2023 12:40
(@banan_net)
Level 1

@aveal да, значения разные, адекватный
попробую добавить задержку с CCR, спасибо!

ОтветитьЦитата
Создатель темы Размещено : 02.11.2023 13:33
(@eduard)
Level 4 Moderator

Вот пример.

  Я по нему делал. Работало.

ОтветитьЦитата
Размещено : 03.11.2023 19:00
(@banan_net)
Level 1

@eduard спасибо!

ОтветитьЦитата
Создатель темы Размещено : 07.11.2023 07:59
Поделиться: