В чем проблема калибровки ESC?

Рейтинг: 0Ответов: 0Опубликовано: 13.08.2025

Когда я включаю питание к esc он издает один пик и молчание. Никаких других звуков. Если отключаю или отсоеденяю стм он начинает пикать что ждет калибровку. Почему мой код не калибрует корректно,все нейросети обошел и полный ноль

#define USE_FULL_LL_DRIVER

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32h7xx_ll_rcc.h"
#include "stm32h7xx_ll_bus.h"
#include "stm32h7xx_ll_system.h"
#include "stm32h7xx_ll_exti.h"
#include "stm32h7xx_ll_cortex.h"
#include "stm32h7xx_ll_utils.h"
#include "stm32h7xx_ll_pwr.h"
#include "stm32h7xx_ll_tim.h"
#include "stm32h7xx_ll_gpio.h"

/* Private typedef -----------------------------------------------------------*/
typedef struct {
    uint16_t min_pulse;
    uint16_t max_pulse;
    uint16_t neutral_pulse;
} ESC_CalibrationParams;

typedef enum {
    CALIBRATION_IDLE,
    CALIBRATION_MIN,
    CALIBRATION_MAX,
    CALIBRATION_NEUTRAL,
    CALIBRATION_COMPLETE
} CalibrationState;

/* Private define ------------------------------------------------------------*/
#define ESC_MIN_PULSE     1000  // мкс
#define ESC_MAX_PULSE     2000  // мкс
#define ESC_NEUTRAL_PULSE 1500  // мкс
#define PWM_FREQUENCY     50    // Гц

/* Private variables ---------------------------------------------------------*/
ESC_CalibrationParams esc_calibration = {
    .min_pulse = ESC_MIN_PULSE,
    .max_pulse = ESC_MAX_PULSE,
    .neutral_pulse = ESC_NEUTRAL_PULSE
};

CalibrationState current_state = CALIBRATION_IDLE;
uint32_t calibration_timestamp = 0;

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void GPIO_Init(void);
void TIM1_PWM_Init(void);
void ESC_Calibration_Process(void);
void ESC_Set_Pulse_Width(uint16_t pulse_width);
void Delay_Ms(uint32_t ms);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    GPIO_Init();
    TIM1_PWM_Init();
    ESC_Calibration_Process();

    while (1) {
        ESC_Set_Pulse_Width(1100);  // Очень медленное вращение
        Delay_Ms(100);  // Небольшая задержка в цикле
    }
}

void SystemClock_Config(void)
{
    LL_RCC_HSI_Enable();
    while(LL_RCC_HSI_IsReady() != 1) {}

    LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1);
    LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_1);
    LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
    LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
    LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_1);
    LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_1);

    LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
    while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {}

    SystemCoreClockUpdate();
}

void GPIO_Init(void)
{
    LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA);

    LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_9, LL_GPIO_MODE_ALTERNATE);
    LL_GPIO_SetAFPin_8_15(GPIOA, LL_GPIO_PIN_9, LL_GPIO_AF_1);

    LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_9, LL_GPIO_SPEED_FREQ_HIGH);
    LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_9, LL_GPIO_OUTPUT_PUSHPULL);
    LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_9, LL_GPIO_PULL_NO);
}

void TIM1_PWM_Init(void)
{
    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);

    // Для 50 Гц нужно: 64MHz / (prescaler * ARR) = 50 Hz
    // 64000000 / (64 * 20000) = 50 Hz
    LL_TIM_SetPrescaler(TIM1, 63);        // Делитель 64 (63+1)
    LL_TIM_SetAutoReload(TIM1, 19999);    // Период 20000 тиков = 20мс

    /* Настройка канала CH1 */
    LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_PWM1);
    LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCPOLARITY_HIGH);
    LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1);
    LL_TIM_OC_SetCompareCH1(TIM1, 1500);  // Начальное значение 1.5мс


    LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1);


    LL_TIM_SetBreakInputSourcePolarity(TIM1, LL_TIM_BREAK_INPUT_BKIN,
                                        LL_TIM_BKIN_SOURCE_BKIN, LL_TIM_BKIN_POLARITY_LOW);
    LL_TIM_DisableBRK(TIM1);
    LL_TIM_EnableAllOutputs(TIM1);
    LL_TIM_GenerateEvent_UPDATE(TIM1);
    LL_TIM_EnableCounter(TIM1);
}


void ESC_Calibration_Process() {
    ESC_Set_Pulse_Width(esc_calibration.min_pulse);
    Delay_Ms(3000);  // Дождаться звуковых сигналов ESC
    ESC_Set_Pulse_Width(esc_calibration.max_pulse);
    Delay_Ms(3000);
}
void ESC_Set_Pulse_Width(uint16_t pulse_width_us) {
    if (pulse_width_us < 1000) pulse_width_us = 1000;
    if (pulse_width_us > 2000) pulse_width_us = 2000;

    LL_TIM_OC_SetCompareCH1(TIM1, pulse_width_us);
}

void Delay_Ms(uint32_t ms) {
    uint32_t tickstart = HAL_GetTick();
    uint32_t wait = ms;

    /* Ожидание пока не пройдет заданное время */
    while((HAL_GetTick() - tickstart) < wait) {
        // Можно добавить __NOP() для оптимизации
    }
}



void Error_Handler(void)
{
    __disable_irq();
    while (1)
    {
    }
}

#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
    /* USER can add his own implementation to report the file name and line number */
}
#endif

Ответы

Ответов пока нет.