В чем проблема калибровки ESC?
Когда я включаю питание к 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
Источник: Stack Overflow на русском