STM32直流无刷电机六拍方波控制器程序

STM32直流无刷电机(BLDC)六拍方波控制程序,包含霍尔传感器检测、PWM驱动、启动控制、速度闭环等功能。

一、系统架构

1.1 硬件连接

复制代码
STM32F103C8T6 (主控)
├── 三相全桥驱动 (6个MOSFET/IGBT)
│   ├── UH → PA8 (TIM1_CH1)  // 上桥U相
│   ├── UL → PA7 (TIM1_CH1N) // 下桥U相
│   ├── VH → PA9 (TIM1_CH2)  // 上桥V相
│   ├── VL → PB0 (TIM1_CH2N) // 下桥V相
│   ├── WH → PA10 (TIM1_CH3) // 上桥W相
│   └── WL → PB1 (TIM1_CH3N) // 下桥W相
├── 霍尔传感器输入
│   ├── HALL_U → PA0 (TIM5_CH1)  // U相霍尔
│   ├── HALL_V → PA1 (TIM5_CH2)  // V相霍尔
│   └── HALL_W → PA2 (TIM5_CH3)  // W相霍尔
├── 电流检测
│   ├── ADC1 → PA3  // 电流检测
│   └── 过流保护 → PA4
├── 编码器接口 (可选)
│   ├── ENC_A → PA6 (TIM3_CH1)
│   └── ENC_B → PA7 (TIM3_CH2)
├── 控制接口
│   ├── 启动/停止 → PB12
│   ├── 方向控制 → PB13
│   └── 速度调节 → PA5 (ADC)
└── 状态指示
    ├── LED_RUN → PC13
    ├── LED_FAULT → PC14
    └── 蜂鸣器 → PC15

1.2 六拍换相顺序

复制代码
电角度    霍尔状态  通电相  功率管导通
0-60°      101      U+ W-    Q1, Q6
60-120°    100      U+ V-    Q1, Q2
120-180°   110      W+ V-    Q5, Q2
180-240°   010      W+ U-    Q5, Q4
240-300°   011      V+ U-    Q3, Q4
300-360°   001      V+ W-    Q3, Q6

二、核心驱动程序

2.1 主程序框架

c 复制代码
/**
 * @file main.c
 * @brief BLDC六拍方波控制器主程序
 */

#include "main.h"
#include "bldc_driver.h"
#include "hall_sensor.h"
#include "pid_controller.h"
#include "fault_handler.h"
#include <stdio.h>
#include <string.h>

/* 全局变量 */
BLDC_Motor motor = {0};
PID_Controller speed_pid = {0};
uint32_t system_tick = 0;
uint8_t system_state = SYS_STOP;

/* 函数声明 */
void SystemClock_Config(void);
void GPIO_Init(void);
void TIM1_PWM_Init(void);
void TIM5_HALL_Init(void);
void ADC_Init(void);
void NVIC_Init(void);
void Motor_Start(void);
void Motor_Stop(void);
void Motor_SetSpeed(uint16_t speed_rpm);
void Motor_SetDirection(uint8_t dir);
void System_Task_10ms(void);
void System_Task_100ms(void);
void System_Task_1000ms(void);

/**
 * @brief 主函数
 */
int main(void)
{
    /* HAL库初始化 */
    HAL_Init();
    
    /* 系统时钟配置 */
    SystemClock_Config();
    
    /* 外设初始化 */
    GPIO_Init();
    TIM1_PWM_Init();
    TIM5_HALL_Init();
    ADC_Init();
    NVIC_Init();
    
    /* 电机初始化 */
    BLDC_Init(&motor);
    
    /* PID初始化 */
    PID_Init(&speed_pid, 0.5, 0.1, 0.01, 1000, 1000);
    
    printf("BLDC Six-Step Controller Ready!\n");
    printf("System Clock: %d Hz\n", SystemCoreClock);
    printf("PWM Frequency: %d Hz\n", PWM_FREQUENCY);
    
    /* 主循环 */
    while(1)
    {
        uint32_t current_tick = HAL_GetTick();
        
        /* 1ms任务 */
        if(current_tick - system_tick >= 1)
        {
            system_tick = current_tick;
            
            static uint16_t ms_counter = 0;
            ms_counter++;
            
            /* 10ms任务 */
            if(ms_counter >= 10)
            {
                ms_counter = 0;
                System_Task_10ms();
            }
            
            /* 100ms任务 */
            if(ms_counter % 10 == 0)
            {
                System_Task_100ms();
            }
            
            /* 1000ms任务 */
            if(ms_counter == 0)
            {
                System_Task_1000ms();
            }
        }
        
        /* 空闲处理 */
        if(system_state == SYS_STOP)
        {
            __WFI();  // 进入低功耗模式
        }
    }
}

/**
 * @brief 10ms任务
 */
void System_Task_10ms(void)
{
    /* 霍尔传感器处理 */
    Hall_Process(&motor);
    
    /* 速度计算 */
    BLDC_CalculateSpeed(&motor);
    
    /* 电流检测 */
    Current_Protection_Check();
    
    /* 温度检测 */
    Temperature_Protection_Check();
}

/**
 * @brief 100ms任务
 */
void System_Task_100ms(void)
{
    static uint8_t led_counter = 0;
    
    /* 状态指示灯闪烁 */
    if(motor.state == MOTOR_RUNNING)
    {
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
    }
    else
    {
        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
    }
    
    /* 按键扫描 */
    static uint32_t last_key_time = 0;
    uint32_t current_time = HAL_GetTick();
    
    if(current_time - last_key_time > 200)  // 200ms去抖
    {
        /* 启动/停止按键 */
        if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == GPIO_PIN_RESET)
        {
            last_key_time = current_time;
            
            if(system_state == SYS_STOP)
            {
                Motor_Start();
            }
            else
            {
                Motor_Stop();
            }
        }
        
        /* 方向控制按键 */
        if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13) == GPIO_PIN_RESET)
        {
            last_key_time = current_time;
            Motor_SetDirection(!motor.direction);
        }
    }
}

/**
 * @brief 1000ms任务
 */
void System_Task_1000ms(void)
{
    /* 状态报告 */
    printf("State: %s, Speed: %d RPM, Duty: %d%%, Current: %.2fA\n",
           (motor.state == MOTOR_RUNNING) ? "RUN" : "STOP",
           motor.speed_rpm,
           motor.pwm_duty * 100 / PWM_MAX_DUTY,
           motor.current);
    
    /* 故障状态检查 */
    if(motor.fault_flags != 0)
    {
        printf("Fault: 0x%02X\n", motor.fault_flags);
    }
}

2.2 BLDC驱动头文件

c 复制代码
/**
 * @file bldc_driver.h
 * @brief BLDC六拍方波驱动
 */

#ifndef __BLDC_DRIVER_H
#define __BLDC_DRIVER_H

#include "stm32f1xx_hal.h"
#include <stdint.h>
#include <stdbool.h>

/* 系统配置 */
#define PWM_FREQUENCY     16000    // PWM频率 16kHz
#define PWM_PERIOD        (SystemCoreClock / PWM_FREQUENCY) - 1
#define PWM_MAX_DUTY      1000     // 最大占空比
#define PWM_DEAD_TIME     72       // 死区时间 (72/72MHz=1us)
#define MIN_DUTY          50       // 最小占空比
#define MAX_DUTY          950      // 最大占空比

/* 系统状态 */
typedef enum {
    SYS_STOP = 0,
    SYS_STARTING,
    SYS_RUNNING,
    SYS_FAULT
} SystemState;

/* 电机状态 */
typedef enum {
    MOTOR_STOP = 0,
    MOTOR_ALIGN,
    MOTOR_START_OPENLOOP,
    MOTOR_RUNNING,
    MOTOR_FAULT
} MotorState;

/* 旋转方向 */
typedef enum {
    DIR_CW = 0,     // 顺时针
    DIR_CCW = 1     // 逆时针
} Direction;

/* 六拍换相表 */
typedef struct {
    uint8_t hall_state;     // 霍尔状态
    uint8_t uh_state;       // U上桥状态
    uint8_t ul_state;       // U下桥状态
    uint8_t vh_state;       // V上桥状态
    uint8_t vl_state;       // V下桥状态
    uint8_t wh_state;       // W上桥状态
    uint8_t wl_state;       // W下桥状态
} CommutationStep;

/* 电机参数结构体 */
typedef struct {
    MotorState state;           // 电机状态
    Direction direction;        // 旋转方向
    uint16_t speed_rpm;         // 当前转速
    uint16_t target_rpm;        // 目标转速
    uint16_t pwm_duty;          // PWM占空比
    uint8_t comm_step;          // 当前换相步
    uint8_t hall_state;         // 霍尔传感器状态
    uint32_t hall_timestamp;    // 霍尔变化时间戳
    uint32_t last_hall_time;    // 上次霍尔变化时间
    uint16_t electrical_angle;  // 电角度
    float current;              // 相电流
    float voltage;              // 母线电压
    float temperature;          // 温度
    uint8_t fault_flags;        // 故障标志
    uint32_t start_time;        // 启动时间
    uint8_t align_counter;      // 对位计数
} BLDC_Motor;

/* 故障标志位 */
#define FAULT_OVERCURRENT   (1 << 0)
#define FAULT_OVERVOLTAGE   (1 << 1)
#define FAULT_OVERTEMP      (1 << 2)
#define FAULT_STALL         (1 << 3)
#define FAULT_HALL_ERROR    (1 << 4)
#define FAULT_UNDERVOLTAGE  (1 << 5)

/* 函数声明 */
void BLDC_Init(BLDC_Motor *motor);
void BLDC_SetCommutation(uint8_t step);
void BLDC_UpdateCommutation(void);
void BLDC_SetPWM(uint16_t duty);
void BLDC_Start(void);
void BLDC_Stop(void);
void BLDC_Brake(void);
void BLDC_SetDirection(Direction dir);
void BLDC_CalculateSpeed(BLDC_Motor *motor);
uint8_t BLDC_GetNextCommStep(uint8_t current_step, Direction dir);
void BLDC_ClearFault(void);
uint8_t BLDC_CheckFault(void);
void BLDC_StartupSequence(void);

/* 外部变量 */
extern BLDC_Motor motor;
extern const CommutationStep comm_table_cw[6];
extern const CommutationStep comm_table_ccw[6];

#endif /* __BLDC_DRIVER_H */

2.3 BLDC驱动实现

c 复制代码
/**
 * @file bldc_driver.c
 * @brief BLDC驱动实现
 */

#include "bldc_driver.h"
#include "hall_sensor.h"

/* 全局变量 */
BLDC_Motor motor = {0};

/* 六拍换相表 (顺时针) */
const CommutationStep comm_table_cw[6] = {
    // 霍尔101: U+ W- (Q1, Q6)
    {0x05, 1, 0, 0, 0, 0, 1},
    // 霍尔100: U+ V- (Q1, Q2)
    {0x04, 1, 0, 0, 1, 0, 0},
    // 霍尔110: W+ V- (Q5, Q2)
    {0x06, 0, 0, 0, 1, 1, 0},
    // 霍尔010: W+ U- (Q5, Q4)
    {0x02, 0, 1, 0, 0, 1, 0},
    // 霍尔011: V+ U- (Q3, Q4)
    {0x03, 0, 1, 1, 0, 0, 0},
    // 霍尔001: V+ W- (Q3, Q6)
    {0x01, 0, 0, 1, 0, 0, 1}
};

/* 六拍换相表 (逆时针) */
const CommutationStep comm_table_ccw[6] = {
    // 霍尔001: V+ W- (Q3, Q6)
    {0x01, 0, 0, 1, 0, 0, 1},
    // 霍尔011: V+ U- (Q3, Q4)
    {0x03, 0, 1, 1, 0, 0, 0},
    // 霍尔010: W+ U- (Q5, Q4)
    {0x02, 0, 1, 0, 0, 1, 0},
    // 霍尔110: W+ V- (Q5, Q2)
    {0x06, 0, 0, 0, 1, 1, 0},
    // 霍尔100: U+ V- (Q1, Q2)
    {0x04, 1, 0, 0, 1, 0, 0},
    // 霍尔101: U+ W- (Q1, Q6)
    {0x05, 1, 0, 0, 0, 0, 1}
};

/**
 * @brief BLDC初始化
 */
void BLDC_Init(BLDC_Motor *motor)
{
    if(motor == NULL) return;
    
    /* 初始化电机参数 */
    memset(motor, 0, sizeof(BLDC_Motor));
    
    motor->state = MOTOR_STOP;
    motor->direction = DIR_CW;
    motor->speed_rpm = 0;
    motor->target_rpm = 1000;  // 默认目标转速1000RPM
    motor->pwm_duty = 0;
    motor->comm_step = 0;
    motor->hall_state = 0;
    motor->fault_flags = 0;
    motor->electrical_angle = 0;
    
    /* 关闭所有PWM输出 */
    BLDC_Stop();
    
    printf("BLDC Motor initialized\n");
}

/**
 * @brief 设置换相步骤
 * @param step 换相步骤 (0-5)
 */
void BLDC_SetCommutation(uint8_t step)
{
    if(step >= 6) return;
    
    const CommutationStep *comm_table = (motor.direction == DIR_CW) ? 
                                        comm_table_cw : comm_table_ccw;
    
    const CommutationStep *comm = &comm_table[step];
    
    /* 设置PWM输出状态 */
    if(comm->uh_state)
    {
        /* U上桥PWM输出 */
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, motor.pwm_duty);
        HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    }
    else
    {
        /* U上桥关闭 */
        HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
    }
    
    if(comm->ul_state)
    {
        /* U下桥PWM输出 */
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1N, motor.pwm_duty);
        HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1N);
    }
    else
    {
        /* U下桥关闭 */
        HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1N);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);
    }
    
    if(comm->vh_state)
    {
        /* V上桥PWM输出 */
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, motor.pwm_duty);
        HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
    }
    else
    {
        /* V上桥关闭 */
        HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);
    }
    
    if(comm->vl_state)
    {
        /* V下桥PWM输出 */
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2N, motor.pwm_duty);
        HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2N);
    }
    else
    {
        /* V下桥关闭 */
        HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2N);
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
    }
    
    if(comm->wh_state)
    {
        /* W上桥PWM输出 */
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, motor.pwm_duty);
        HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
    }
    else
    {
        /* W上桥关闭 */
        HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
    }
    
    if(comm->wl_state)
    {
        /* W下桥PWM输出 */
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3N, motor.pwm_duty);
        HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3N);
    }
    else
    {
        /* W下桥关闭 */
        HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3N);
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
    }
    
    motor->comm_step = step;
    motor->electrical_angle = step * 60;  // 每步60度电角度
}

/**
 * @brief 更新换相
 */
void BLDC_UpdateCommutation(void)
{
    uint8_t hall_state = Hall_GetState();
    
    if(hall_state != motor.hall_state)
    {
        motor.hall_state = hall_state;
        motor.last_hall_time = motor.hall_timestamp;
        motor.hall_timestamp = HAL_GetTick();
        
        /* 根据霍尔状态和方向确定换相步骤 */
        uint8_t new_step = 0;
        const CommutationStep *comm_table = (motor.direction == DIR_CW) ? 
                                            comm_table_cw : comm_table_ccw;
        
        for(uint8_t i = 0; i < 6; i++)
        {
            if(comm_table[i].hall_state == hall_state)
            {
                new_step = i;
                break;
            }
        }
        
        /* 执行换相 */
        BLDC_SetCommutation(new_step);
    }
}

/**
 * @brief 设置PWM占空比
 * @param duty 占空比 (0-1000)
 */
void BLDC_SetPWM(uint16_t duty)
{
    if(duty > PWM_MAX_DUTY) duty = PWM_MAX_DUTY;
    
    motor.pwm_duty = duty;
    
    /* 更新当前PWM占空比 */
    switch(motor.comm_step)
    {
        case 0:  // U+ W-
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, duty);
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3N, duty);
            break;
        case 1:  // U+ V-
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, duty);
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2N, duty);
            break;
        case 2:  // W+ V-
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, duty);
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2N, duty);
            break;
        case 3:  // W+ U-
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, duty);
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1N, duty);
            break;
        case 4:  // V+ U-
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, duty);
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1N, duty);
            break;
        case 5:  // V+ W-
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, duty);
            __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3N, duty);
            break;
    }
}

/**
 * @brief 启动电机
 */
void BLDC_Start(void)
{
    if(motor.state != MOTOR_STOP && motor.state != MOTOR_FAULT)
        return;
    
    if(motor.fault_flags != 0)
    {
        printf("Cannot start motor with fault: 0x%02X\n", motor.fault_flags);
        return;
    }
    
    motor.state = MOTOR_ALIGN;
    motor.start_time = HAL_GetTick();
    motor.align_counter = 0;
    
    printf("Motor starting...\n");
    
    /* 启动序列 */
    BLDC_StartupSequence();
}

/**
 * @brief 停止电机
 */
void BLDC_Stop(void)
{
    motor.state = MOTOR_STOP;
    motor.speed_rpm = 0;
    motor.pwm_duty = 0;
    
    /* 关闭所有PWM输出 */
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1N);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2N);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3N);
    
    /* 关闭所有GPIO输出 */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
    
    printf("Motor stopped\n");
}

/**
 * @brief 刹车
 */
void BLDC_Brake(void)
{
    /* 三相下桥全开,上桥全关,实现能耗制动 */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);  // UL
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);  // VL
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);  // WL
    
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);  // UH
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);  // VH
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET); // WH
    
    motor.state = MOTOR_STOP;
    printf("Motor brake applied\n");
}

/**
 * @brief 设置旋转方向
 * @param dir 方向
 */
void BLDC_SetDirection(Direction dir)
{
    if(motor.state == MOTOR_RUNNING)
    {
        printf("Cannot change direction while motor is running\n");
        return;
    }
    
    motor.direction = dir;
    printf("Direction set to %s\n", (dir == DIR_CW) ? "CW" : "CCW");
}

/**
 * @brief 计算转速
 * @param motor 电机结构体指针
 */
void BLDC_CalculateSpeed(BLDC_Motor *motor)
{
    static uint32_t last_hall_time = 0;
    static uint8_t last_hall_state = 0;
    
    if(motor->hall_state != last_hall_state)
    {
        uint32_t current_time = HAL_GetTick();
        uint32_t delta_time = current_time - last_hall_time;
        
        if(delta_time > 0 && delta_time < 1000)  // 有效时间范围
        {
            /* 每6个霍尔状态变化为一圈 (6步换相) */
            /* 每个霍尔状态变化对应60度电角度,6个变化为360度 */
            /* 计算RPM: RPM = (1 / (delta_time * 6 / 1000 / 60)) */
            motor->speed_rpm = 60000 / (delta_time * 6);
        }
        else
        {
            motor->speed_rpm = 0;
        }
        
        last_hall_time = current_time;
        last_hall_state = motor->hall_state;
    }
}

/**
 * @brief 启动序列
 */
void BLDC_StartupSequence(void)
{
    uint32_t current_time = HAL_GetTick();
    
    switch(motor.state)
    {
        case MOTOR_ALIGN:
            /* 预定位阶段 */
            if(current_time - motor.start_time < 1000)  // 1秒预定位
            {
                /* 强制定位到0度位置 (U+ V-) */
                BLDC_SetCommutation(1);  // 霍尔100对应
                BLDC_SetPWM(100);        // 10%占空比
            }
            else
            {
                /* 进入开环启动 */
                motor.state = MOTOR_START_OPENLOOP;
                motor.start_time = current_time;
                printf("Entering open-loop start\n");
            }
            break;
            
        case MOTOR_START_OPENLOOP:
            /* 开环加速阶段 */
            if(current_time - motor.start_time < 5000)  // 5秒加速
            {
                static uint32_t last_comm_time = 0;
                static uint16_t openloop_speed = 50;
                
                /* 逐步增加占空比 */
                if(current_time - motor.start_time < 1000)
                {
                    openloop_speed = 100;  // 10%
                }
                else if(current_time - motor.start_time < 2000)
                {
                    openloop_speed = 200;  // 20%
                }
                else if(current_time - motor.start_time < 3000)
                {
                    openloop_speed = 300;  // 30%
                }
                else
                {
                    openloop_speed = 400;  // 40%
                }
                
                BLDC_SetPWM(openloop_speed);
                
                /* 强制换相 (固定频率) */
                if(current_time - last_comm_time > 20)  // 50Hz换相
                {
                    last_comm_time = current_time;
                    motor.comm_step = (motor.comm_step + 1) % 6;
                    BLDC_SetCommutation(motor.comm_step);
                }
                
                /* 检查是否达到切换速度 */
                if(motor.speed_rpm > 300)
                {
                    motor.state = MOTOR_RUNNING;
                    printf("Entering closed-loop running\n");
                }
            }
            else
            {
                /* 启动超时 */
                motor.state = MOTOR_FAULT;
                motor.fault_flags |= FAULT_STALL;
                printf("Startup timeout\n");
            }
            break;
            
        case MOTOR_RUNNING:
            /* 正常运行,已由霍尔传感器控制换相 */
            break;
            
        default:
            break;
    }
}

2.4 霍尔传感器驱动

c 复制代码
/**
 * @file hall_sensor.h
 * @brief 霍尔传感器驱动
 */

#ifndef __HALL_SENSOR_H
#define __HALL_SENSOR_H

#include "bldc_driver.h"

/* 函数声明 */
void Hall_Init(void);
uint8_t Hall_GetState(void);
void Hall_Process(BLDC_Motor *motor);
uint8_t Hall_ValidateState(uint8_t state);
void Hall_ErrorHandler(uint8_t expected_state, uint8_t actual_state);
uint8_t Hall_GetNextState(uint8_t current_state, Direction dir);

/* 霍尔传感器有效状态 */
#define HALL_STATE_001  0x01
#define HALL_STATE_010  0x02
#define HALL_STATE_011  0x03
#define HALL_STATE_100  0x04
#define HALL_STATE_101  0x05
#define HALL_STATE_110  0x06

/* 霍尔传感器无效状态 */
#define HALL_STATE_000  0x00
#define HALL_STATE_111  0x07

#endif /* __HALL_SENSOR_H */
c 复制代码
/**
 * @file hall_sensor.c
 * @brief 霍尔传感器驱动实现
 */

#include "hall_sensor.h"

/* 霍尔传感器引脚定义 */
#define HALL_U_PIN    GPIO_PIN_0
#define HALL_U_PORT   GPIOA
#define HALL_V_PIN    GPIO_PIN_1
#define HALL_V_PORT   GPIOA
#define HALL_W_PIN    GPIO_PIN_2
#define HALL_W_PORT   GPIOA

/* 霍尔传感器状态转换表 (顺时针) */
static const uint8_t hall_next_state_cw[7] = {
    0xFF,  // 000 - 无效
    0x05,  // 001 -> 101
    0x03,  // 010 -> 011
    0x06,  // 011 -> 110
    0x01,  // 100 -> 001
    0x04,  // 101 -> 100
    0x02   // 110 -> 010
};

/* 霍尔传感器状态转换表 (逆时针) */
static const uint8_t hall_next_state_ccw[7] = {
    0xFF,  // 000 - 无效
    0x04,  // 001 -> 100
    0x06,  // 010 -> 110
    0x02,  // 011 -> 010
    0x05,  // 100 -> 101
    0x01,  // 101 -> 001
    0x03   // 110 -> 011
};

/**
 * @brief 霍尔传感器初始化
 */
void Hall_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    /* 使能GPIOA时钟 */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    
    /* 配置霍尔传感器引脚为上拉输入 */
    GPIO_InitStruct.Pin = HALL_U_PIN | HALL_V_PIN | HALL_W_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;  // 霍尔传感器通常是开漏输出
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    printf("Hall sensors initialized\n");
}

/**
 * @brief 获取霍尔传感器状态
 * @return 霍尔状态 (3位: H3 H2 H1)
 */
uint8_t Hall_GetState(void)
{
    uint8_t state = 0;
    
    /* 读取霍尔传感器值 (低电平有效) */
    if(HAL_GPIO_ReadPin(HALL_U_PORT, HALL_U_PIN) == GPIO_PIN_RESET)
        state |= 0x01;  // H1
    
    if(HAL_GPIO_ReadPin(HALL_V_PORT, HALL_V_PIN) == GPIO_PIN_RESET)
        state |= 0x02;  // H2
    
    if(HAL_GPIO_ReadPin(HALL_W_PORT, HALL_W_PIN) == GPIO_PIN_RESET)
        state |= 0x04;  // H3
    
    return state;
}

/**
 * @brief 处理霍尔传感器
 * @param motor 电机结构体指针
 */
void Hall_Process(BLDC_Motor *motor)
{
    static uint8_t last_valid_state = 0;
    static uint32_t error_count = 0;
    
    uint8_t current_state = Hall_GetState();
    
    /* 验证霍尔状态 */
    if(Hall_ValidateState(current_state))
    {
        if(current_state != motor->hall_state)
        {
            /* 霍尔状态变化 */
            motor->hall_state = current_state;
            motor->last_hall_time = motor->hall_timestamp;
            motor->hall_timestamp = HAL_GetTick();
            
            /* 检查霍尔序列是否正确 */
            if(last_valid_state != 0)
            {
                uint8_t expected_state = Hall_GetNextState(last_valid_state, motor->direction);
                if(expected_state != current_state)
                {
                    Hall_ErrorHandler(expected_state, current_state);
                    error_count++;
                    
                    if(error_count > 10)  // 连续10次错误
                    {
                        motor->fault_flags |= FAULT_HALL_ERROR;
                        printf("Hall sensor sequence error\n");
                    }
                }
                else
                {
                    error_count = 0;  // 重置错误计数
                }
            }
            
            last_valid_state = current_state;
            
            /* 更新换相 */
            if(motor->state == MOTOR_RUNNING)
            {
                BLDC_UpdateCommutation();
            }
        }
    }
    else
    {
        /* 无效霍尔状态 */
        if(current_state == HALL_STATE_000 || current_state == HALL_STATE_111)
        {
            error_count++;
            
            if(error_count > 5)  // 连续5次无效状态
            {
                motor->fault_flags |= FAULT_HALL_ERROR;
                printf("Invalid hall state: 0x%02X\n", current_state);
            }
        }
    }
}

/**
 * @brief 验证霍尔状态
 * @param state 霍尔状态
 * @return 1:有效, 0:无效
 */
uint8_t Hall_ValidateState(uint8_t state)
{
    /* 只允许6个有效状态 */
    return (state >= 1 && state <= 6);
}

/**
 * @brief 霍尔错误处理
 * @param expected_state 期望状态
 * @param actual_state 实际状态
 */
void Hall_ErrorHandler(uint8_t expected_state, uint8_t actual_state)
{
    printf("Hall sequence error: Expected 0x%02X, Got 0x%02X\n", 
           expected_state, actual_state);
    
    /* 可以根据错误类型采取不同措施 */
    if(actual_state == 0x00 || actual_state == 0x07)
    {
        /* 霍尔传感器失效 */
    }
    else
    {
        /* 霍尔传感器错位 */
    }
}

/**
 * @brief 获取下一个霍尔状态
 * @param current_state 当前状态
 * @param dir 旋转方向
 * @return 下一个预期状态
 */
uint8_t Hall_GetNextState(uint8_t current_state, Direction dir)
{
    if(current_state < 1 || current_state > 6)
        return 0xFF;
    
    if(dir == DIR_CW)
        return hall_next_state_cw[current_state];
    else
        return hall_next_state_ccw[current_state];
}

2.5 PWM定时器配置

c 复制代码
/**
 * @file tim_pwm.c
 * @brief PWM定时器配置
 */

#include "main.h"

TIM_HandleTypeDef htim1;

/**
 * @brief TIM1 PWM初始化
 */
void TIM1_PWM_Init(void)
{
    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};
    TIM_OC_InitTypeDef sConfigOC = {0};
    TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
    
    /* 使能TIM1时钟 */
    __HAL_RCC_TIM1_CLK_ENABLE();
    
    /* 定时器基础配置 */
    htim1.Instance = TIM1;
    htim1.Init.Prescaler = 0;  // 不分频
    htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;  // 中央对齐模式
    htim1.Init.Period = PWM_PERIOD;  // PWM周期
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim1.Init.RepetitionCounter = 0;
    htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    HAL_TIM_PWM_Init(&htim1);
    
    /* 时钟源配置 */
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig);
    
    /* 主输出配置 */
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);
    
    /* 输出比较配置 */
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;  // 初始占空比为0
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
    sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
    
    /* 配置通道1 (U相上桥) */
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
    
    /* 配置通道1N (U相下桥) */
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1N);
    
    /* 配置通道2 (V相上桥) */
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2);
    
    /* 配置通道2N (V相下桥) */
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2N);
    
    /* 配置通道3 (W相上桥) */
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3);
    
    /* 配置通道3N (W相下桥) */
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3N);
    
    /* 死区和刹车配置 */
    sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
    sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
    sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
    sBreakDeadTimeConfig.DeadTime = PWM_DEAD_TIME;  // 死区时间
    sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
    sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
    sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
    HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig);
    
    /* 启动PWM输出 */
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1N);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2N);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3N);
    
    /* 禁用输出,等待启动命令 */
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1N);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2N);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);
    HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3N);
    
    printf("TIM1 PWM initialized: Freq=%dHz, DeadTime=%dns\n", 
           PWM_FREQUENCY, (PWM_DEAD_TIME * 1000) / 72);
}

2.6 故障保护

c 复制代码
/**
 * @file fault_handler.c
 * @brief 故障保护处理
 */

#include "fault_handler.h"

/* 故障阈值 */
#define OVER_CURRENT_THRESHOLD    10.0f    // 10A
#define OVER_VOLTAGE_THRESHOLD    60.0f    // 60V
#define UNDER_VOLTAGE_THRESHOLD   20.0f    // 20V
#define OVER_TEMP_THRESHOLD       85.0f    // 85°C
#define STALL_TIME_THRESHOLD      2000     // 2秒堵转

/**
 * @brief 电流保护检测
 */
void Current_Protection_Check(void)
{
    static float filtered_current = 0;
    float current_sample = ADC_GetCurrent();
    
    /* 一阶低通滤波 */
    filtered_current = filtered_current * 0.9 + current_sample * 0.1;
    
    /* 过流检测 */
    if(filtered_current > OVER_CURRENT_THRESHOLD)
    {
        motor.fault_flags |= FAULT_OVERCURRENT;
        BLDC_Stop();
        printf("Over current protection: %.2fA\n", filtered_current);
    }
}

/**
 * @brief 电压保护检测
 */
void Voltage_Protection_Check(void)
{
    float voltage = ADC_GetVoltage();
    
    if(voltage > OVER_VOLTAGE_THRESHOLD)
    {
        motor.fault_flags |= FAULT_OVERVOLTAGE;
        BLDC_Stop();
        printf("Over voltage protection: %.2fV\n", voltage);
    }
    else if(voltage < UNDER_VOLTAGE_THRESHOLD)
    {
        motor.fault_flags |= FAULT_UNDERVOLTAGE;
        BLDC_Stop();
        printf("Under voltage protection: %.2fV\n", voltage);
    }
}

/**
 * @brief 温度保护检测
 */
void Temperature_Protection_Check(void)
{
    float temperature = ADC_GetTemperature();
    
    if(temperature > OVER_TEMP_THRESHOLD)
    {
        motor.fault_flags |= FAULT_OVERTEMP;
        BLDC_Stop();
        printf("Over temperature protection: %.1fC\n", temperature);
    }
}

/**
 * @brief 堵转检测
 */
void Stall_Protection_Check(void)
{
    static uint32_t last_speed_time = 0;
    static uint16_t last_speed = 0;
    
    if(motor.state == MOTOR_RUNNING)
    {
        uint32_t current_time = HAL_GetTick();
        
        if(motor.speed_rpm < 50)  // 速度低于50RPM
        {
            if(current_time - last_speed_time > STALL_TIME_THRESHOLD)
            {
                motor.fault_flags |= FAULT_STALL;
                BLDC_Stop();
                printf("Stall protection triggered\n");
            }
        }
        else
        {
            last_speed_time = current_time;
        }
        
        last_speed = motor.speed_rpm;
    }
}

/**
 * @brief 清除故障
 */
void Clear_Fault(void)
{
    if(motor.fault_flags != 0)
    {
        printf("Clearing faults: 0x%02X\n", motor.fault_flags);
        motor.fault_flags = 0;
    }
}

三、PID速度控制

3.1 PID控制器

c 复制代码
/**
 * @file pid_controller.c
 * @brief PID速度控制器
 */

#include "pid_controller.h"

/**
 * @brief PID初始化
 */
void PID_Init(PID_Controller *pid, float kp, float ki, float kd, 
              float max_output, float max_integral)
{
    pid->Kp = kp;
    pid->Ki = ki;
    pid->Kd = kd;
    pid->max_output = max_output;
    pid->max_integral = max_integral;
    pid->integral = 0;
    pid->prev_error = 0;
    pid->output = 0;
}

/**
 * @brief PID计算
 */
float PID_Calculate(PID_Controller *pid, float target, float feedback, float dt)
{
    float error = target - feedback;
    
    /* 比例项 */
    float P_out = pid->Kp * error;
    
    /* 积分项 */
    pid->integral += error * dt;
    
    /* 积分限幅 */
    if(pid->integral > pid->max_integral)
        pid->integral = pid->max_integral;
    else if(pid->integral < -pid->max_integral)
        pid->integral = -pid->max_integral;
    
    float I_out = pid->Ki * pid->integral;
    
    /* 微分项 */
    float derivative = (error - pid->prev_error) / dt;
    float D_out = pid->Kd * derivative;
    pid->prev_error = error;
    
    /* 计算输出 */
    pid->output = P_out + I_out + D_out;
    
    /* 输出限幅 */
    if(pid->output > pid->max_output)
        pid->output = pid->max_output;
    else if(pid->output < 0)
        pid->output = 0;
    
    return pid->output;
}

/**
 * @brief 速度控制任务
 */
void Speed_Control_Task(void)
{
    static uint32_t last_control_time = 0;
    uint32_t current_time = HAL_GetTick();
    float dt = (current_time - last_control_time) / 1000.0f;  // 转换为秒
    
    if(dt >= 0.01f)  // 100Hz控制频率
    {
        last_control_time = current_time;
        
        /* PID计算 */
        float duty_output = PID_Calculate(&speed_pid, 
                                         motor.target_rpm, 
                                         motor.speed_rpm, 
                                         dt);
        
        /* 转换为PWM占空比 */
        uint16_t pwm_duty = (uint16_t)duty_output;
        
        /* 设置PWM */
        if(pwm_duty > MAX_DUTY) pwm_duty = MAX_DUTY;
        if(pwm_duty < MIN_DUTY) pwm_duty = MIN_DUTY;
        
        BLDC_SetPWM(pwm_duty);
        
        /* 调试输出 */
        static uint32_t debug_counter = 0;
        if(debug_counter++ >= 10)  // 每10次输出一次
        {
            debug_counter = 0;
            printf("PID: Target=%d, Actual=%d, Output=%.1f, Duty=%d\n",
                   motor.target_rpm, motor.speed_rpm, duty_output, pwm_duty);
        }
    }
}

四、测试程序

4.1 电机测试程序

c 复制代码
/**
 * @file motor_test.c
 * @brief 电机测试程序
 */

#include "bldc_driver.h"

/**
 * @brief 测试换相序列
 */
void Test_Commutation_Sequence(void)
{
    printf("Testing commutation sequence...\n");
    
    /* 测试顺时针换相 */
    printf("\nClockwise commutation:\n");
    motor.direction = DIR_CW;
    
    for(int i = 0; i < 6; i++)
    {
        BLDC_SetCommutation(i);
        printf("Step %d: Hall=0x%02X\n", i, comm_table_cw[i].hall_state);
        HAL_Delay(500);
    }
    
    /* 测试逆时针换相 */
    printf("\nCounter-clockwise commutation:\n");
    motor.direction = DIR_CCW;
    
    for(int i = 0; i < 6; i++)
    {
        BLDC_SetCommutation(i);
        printf("Step %d: Hall=0x%02X\n", i, comm_table_ccw[i].hall_state);
        HAL_Delay(500);
    }
    
    BLDC_Stop();
    printf("Commutation test completed\n");
}

/**
 * @brief 测试霍尔传感器
 */
void Test_Hall_Sensors(void)
{
    printf("Testing Hall sensors...\n");
    printf("Manually rotate the motor and check Hall states\n");
    
    uint8_t last_state = 0;
    uint32_t start_time = HAL_GetTick();
    
    while(HAL_GetTick() - start_time < 10000)  // 测试10秒
    {
        uint8_t state = Hall_GetState();
        
        if(state != last_state)
        {
            last_state = state;
            printf("Hall state: 0x%02X\n", state);
            
            if(state == 0x00 || state == 0x07)
            {
                printf("Warning: Invalid Hall state!\n");
            }
        }
        
        HAL_Delay(10);
    }
    
    printf("Hall sensor test completed\n");
}

/**
 * @brief 测试PWM输出
 */
void Test_PWM_Output(void)
{
    printf("Testing PWM output...\n");
    
    /* 逐步增加占空比 */
    for(uint16_t duty = 0; duty <= 1000; duty += 100)
    {
        BLDC_SetPWM(duty);
        printf("Duty: %d\n", duty);
        HAL_Delay(1000);
    }
    
    /* 逐步减少占空比 */
    for(uint16_t duty = 1000; duty > 0; duty -= 100)
    {
        BLDC_SetPWM(duty);
        printf("Duty: %d\n", duty);
        HAL_Delay(1000);
    }
    
    BLDC_SetPWM(0);
    printf("PWM test completed\n");
}

/**
 * @brief 完整电机测试
 */
void Complete_Motor_Test(void)
{
    printf("=== Complete Motor Test ===\n");
    
    /* 1. 霍尔传感器测试 */
    Test_Hall_Sensors();
    HAL_Delay(1000);
    
    /* 2. 换相测试 */
    Test_Commutation_Sequence();
    HAL_Delay(1000);
    
    /* 3. PWM测试 */
    Test_PWM_Output();
    HAL_Delay(1000);
    
    /* 4. 启动测试 */
    printf("\nStarting motor...\n");
    BLDC_Start();
    
    /* 运行10秒 */
    uint32_t start_time = HAL_GetTick();
    while(HAL_GetTick() - start_time < 10000)
    {
        printf("Speed: %d RPM, Duty: %d\n", motor.speed_rpm, motor.pwm_duty);
        HAL_Delay(100);
    }
    
    /* 停止电机 */
    BLDC_Stop();
    
    printf("\nMotor test completed\n");
}

参考代码 直流无刷电机六拍方波控制器程序 www.youwenfan.com/contentcsv/70758.html

五、硬件配置

5.1 系统时钟配置

c 复制代码
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    
    /* 配置HSE 8MHz */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;  // 8MHz * 9 = 72MHz
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
    
    /* 配置系统时钟 */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                  | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;     // HCLK = 72MHz
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;      // PCLK1 = 36MHz
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;      // PCLK2 = 72MHz
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
}

六、使用说明

6.1 基本操作

  1. 初始化 :调用BLDC_Init()初始化电机
  2. 启动 :调用BLDC_Start()启动电机
  3. 停止 :调用BLDC_Stop()停止电机
  4. 设置方向 :调用BLDC_SetDirection()设置旋转方向
  5. 设置速度 :调用BLDC_SetPWM()设置PWM占空比
  6. 故障清除 :调用Clear_Fault()清除故障标志

6.2 参数调整

c 复制代码
/* PWM频率调整 */
#define PWM_FREQUENCY     16000    // 常用范围8-20kHz

/* 死区时间调整 */
#define PWM_DEAD_TIME     72       // 1us (72MHz时钟)

/* 保护阈值调整 */
#define OVER_CURRENT_THRESHOLD    10.0f    // 根据电机额定电流调整
#define OVER_VOLTAGE_THRESHOLD    60.0f    // 根据电源电压调整
#define OVER_TEMP_THRESHOLD       85.0f    // 根据器件耐温调整

/* PID参数调整 */
float Kp = 0.5;  // 比例系数
float Ki = 0.1;  // 积分系数
float Kd = 0.01; // 微分系数
相关推荐
fengfuyao9854 小时前
STM32 HAL库实现串口DMA接收不定长数据
stm32·单片机·嵌入式硬件
番茄灭世神5 小时前
PN学堂GD32教程第21篇——WiFiIOT
c语言·stm32·单片机·嵌入式·gd32
不怕犯错,就怕不做6 小时前
ARM设备异常断电容易造成数据损坏,硬件如何设计
linux·驱动开发·嵌入式硬件
jghhh017 小时前
基于DSP28335的RS485串口通信与AD采样开发方案
单片机·嵌入式硬件
say_fall7 小时前
微处理器及其体系结构:从8088到现代多核处理器
单片机·硬件架构·硬件工程
2301_775602387 小时前
晶振相关知识
单片机
2zcode8 小时前
基于STM32的直流电机串级PID伺服控制系统设计与实现
stm32·单片机·嵌入式硬件·直流电机
都在酒里8 小时前
STM32低功耗休眠详解——睡眠、停止与待机模式实战,综合应用(三)
stm32·单片机·嵌入式硬件
嵌入式小站8 小时前
STM32 零基础可移植教程 06:外部中断按键,不用一直在 while 里盯着它
stm32·单片机·嵌入式硬件