Всем привет! Я только учусь работать с микроконтроллером и нужна помощь:) Работаю с микроконтроллером 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++; } } }
Привет! Надо под отладчиком посмотреть поэтапно, попадает ли в обработчик нажатия PC5, затем, какие значения непосредственно в CCRx записываются и что в массиве sine_wave[] генерируется в итоге, какие значения.
@aveal обработчик попадает, но такое ощущение, что он записывает только 1 число в массива, скважность 1 раз изменилась и все. как заставить, чтобы он постоянно считывал значения с массива не понимаю. 🙁
Кстати в основном цикле, там где:
TIM1->CCR1 = sine_wave[i];
надо какую-то задержку как минимум, потому что в CCR значение обновляется на каждом цикле, таймер не успевает новый сигнал физически сгенерировать.
@aveal да, значения разные, адекватный
попробую добавить задержку с CCR, спасибо!
