Звезда не активнаЗвезда не активнаЗвезда не активнаЗвезда не активнаЗвезда не активна
 
#include "stm32f4xx.h"
#include <math.h>

#define PWM_FREQ 400000   // Base frequency of the PWM output
#define PWM_PERIOD_US 100 // Period of the PWM output in microseconds

#define NUM_SAMPLES 100   // Number of samples per PWM period
#define PI 3.14159265358979323846

uint16_t duty_cycles[NUM_SAMPLES]; // Array of duty cycles for each sample
uint16_t current_sample = 0;       // Index of current sample in the duty_cycles array

void TIM2_IRQHandler(void) {
    if (TIM2->SR & TIM_SR_UIF) { // Check if the update interrupt flag is set
        TIM2->SR &= ~TIM_SR_UIF; // Clear the update interrupt flag

        // Set the duty cycle for the current sample
        TIM2->CCR1 = duty_cycles[current_sample];

        // Increment the sample index, wrapping around if necessary
        current_sample = (current_sample + 1) % NUM_SAMPLES;
    }
}

int main(void) {
    // Enable clock for GPIOA and TIM2
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;

    // Configure GPIOA pin 0 as alternate function mode
    GPIOA->MODER &= ~GPIO_MODER_MODE0;
    GPIOA->MODER |= GPIO_MODER_MODE0_1;
    GPIOA->AFR[0] |= GPIO_AFRL_AFRL0_1; // Set alternate function to TIM2_CH1

    // Generate duty cycle values for a sinusoidal waveform
    for (uint16_t i = 0; i < NUM_SAMPLES; i++) {
        float phase = 2.0 * PI * i / NUM_SAMPLES;
        duty_cycles[i] = (uint16_t)((1.0 + sin(phase)) * 0.5 * 65535.0);
    }

    // Configure TIM2 for one-shot PWM output on CH1
    TIM2->PSC = 0; // Set prescaler to 1
    TIM2->ARR = PWM_PERIOD_US * (SystemCoreClock / 1000000) - 1; // Set auto-reload value for PWM period
    TIM2->CCR1 = 0; // Set initial duty cycle to 0%
    TIM2->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // Set PWM mode to mode 1
    TIM2->CCER |= TIM_CCER_CC1E; // Enable capture/compare channel 1 output
    TIM2->DIER |= TIM_DIER_UIE; // Enable update interrupt
    NVIC_EnableIRQ(TIM2_IRQn); // Enable TIM2 interrupt in NVIC
    TIM2->CR1 |= TIM_CR1_CEN;   // Start the timer

    while (1) {
        // Wait for interrupt to update duty cycle
    }
}
using HAL:
#include "main.h"
#include "stm32f4xx_hal.h"
#include <math.h>

#define PWM_FREQ 400000   // Base frequency of the PWM output
#define PWM_PERIOD_US 100 // Period of the PWM output in microseconds

#define NUM_SAMPLES 100   // Number of samples per PWM period
#define PI 3.14159265358979323846

TIM_HandleTypeDef htim2;
uint16_t duty_cycles[NUM_SAMPLES]; // Array of duty cycles for each sample
uint16_t current_sample = 0;       // Index of current sample in the duty_cycles array

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if (htim->Instance == TIM2) {
        // Set the duty cycle for the current sample
        TIM2->Instance->CCR1 = duty_cycles[current_sample];

        // Increment the sample index, wrapping around if necessary
        current_sample = (current_sample + 1) % NUM_SAMPLES;
    }
}

int main(void) {
    // Initialize HAL
    HAL_Init();

    // Enable clock for GPIOA and TIM2
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_TIM2_CLK_ENABLE();

    // Configure GPIOA pin 0 as alternate function mode
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // Generate duty cycle values for a sinusoidal waveform
    for (uint16_t i = 0; i < NUM_SAMPLES; i++) {
        float phase = 2.0 * PI * i / NUM_SAMPLES;
        duty_cycles[i] = (uint16_t)((1.0 + sin(phase)) * 0.5 * 65535.0);
    }

    // Configure TIM2 for one-shot PWM output on CH1
    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 0;
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = PWM_PERIOD_US * (SystemCoreClock / 1000000) - 1;
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim2.Init.RepetitionCounter = 0;
    HAL_TIM_PWM_Init(&htim2);

    TIM_OC_InitTypeDef sConfigOC = {0};
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);

    HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_1);

    while (1) {
        // Wait for interrupt to update duty cycle
    }
}