编程技术分享

分享编程知识,探讨技术创新

0%

简介:Mini FOC无刷平衡车 V2.0版本

很高兴能为您详细解析Mini FOC无刷平衡车V2.0版本的嵌入式系统开发流程和代码架构。
关注微信公众号,提前获取相关推文

项目概述:Mini FOC无刷平衡车 V2.0

本项目旨在开发一个可靠、高效、可扩展的Mini FOC无刷平衡车系统。V2.0版本在V1.0版本的基础上进行了优化和升级,重点提升了系统的稳定性、控制精度和用户体验。项目涵盖了从需求分析、系统设计、软件架构设计、硬件选型、代码实现、测试验证到维护升级的完整嵌入式系统开发流程。

系统架构设计:分层模块化架构

为了构建一个可靠、高效、可扩展的平衡车系统,我们采用了分层模块化的软件架构。这种架构将系统分解为多个独立的模块,每个模块负责特定的功能,模块之间通过清晰定义的接口进行交互。这种架构的优势在于:

  • 高内聚低耦合: 模块内部功能高度相关,模块之间依赖性低,易于维护和修改。
  • 可重用性: 模块可以独立开发和测试,并在不同的项目中重用。
  • 可扩展性: 可以方便地添加新的模块或替换现有模块,以扩展系统功能或适应新的硬件平台。
  • 易于测试和调试: 模块化架构使得单元测试和集成测试更加容易进行,有助于快速定位和解决问题。

系统架构图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
+-----------------------+  <-- 应用层 (Application Layer)
| 用户界面模块 (UI) | <-- 可选,如果需要
| 系统管理模块 (System Management) |
+-----------------------+
|
| API接口
V
+-----------------------+ <-- 控制层 (Control Layer)
| 平衡控制模块 (Balance Control) |
| 速度控制模块 (Speed Control) |
| 电机控制模块 (Motor Control - FOC) |
| 姿态解算模块 (Attitude Estimation) |
+-----------------------+
|
| 抽象接口
V
+-----------------------+ <-- 硬件抽象层 (HAL - Hardware Abstraction Layer)
| 传感器驱动 (Sensor Drivers) | (IMU, 编码器, 电流传感器)
| 电机驱动 (Motor Drivers) | (PWM, 电机使能)
| 通信驱动 (Communication Drivers) | (UART, SPI, I2C - 可选)
| 电源管理 (Power Management) |
| GPIO驱动 (GPIO Drivers) |
+-----------------------+
|
| 硬件接口
V
+-----------------------+ <-- 硬件层 (Hardware Layer)
| 微控制器 (MCU) |
| IMU传感器 |
| 编码器 |
| 电流传感器 |
| 无刷电机 |
| 电机驱动器 |
| 电源系统 |
| 用户界面硬件 (LED, 按键 - 可选) |
| 通信接口硬件 (UART, Bluetooth - 可选) |
+-----------------------+

各层模块详细说明:

1. 硬件层 (Hardware Layer):

  • 微控制器 (MCU): 作为系统的核心,负责运行嵌入式软件,处理传感器数据,执行控制算法,驱动电机。 根据项目需求,我们通常选择高性能、低功耗的ARM Cortex-M系列MCU,例如STM32系列、NXP Kinetis系列或TI C2000系列。 对于平衡车应用,需要MCU具备足够的运算能力、丰富的外设接口(ADC, PWM, SPI, I2C, UART, Timer等)以及实时性。
  • IMU传感器 (Inertial Measurement Unit): 用于测量平衡车的姿态信息,包括角速度和加速度。常用的IMU传感器包括MPU6050、BMI160、ICM20602等。IMU数据是平衡控制算法的关键输入。
  • 编码器 (Encoders): 安装在电机轴上,用于测量电机的转速和位置。编码器类型可以选择增量式编码器或绝对式编码器。编码器数据用于FOC电机控制和速度控制。
  • 电流传感器 (Current Sensors): 用于测量电机相电流,为FOC算法提供反馈,实现精确的电流环控制。常用的电流传感器有霍尔电流传感器和分流电阻电流传感器。
  • 无刷电机 (Brushless Motors): 平衡车的动力来源,选用高性能、高效率的无刷直流电机(BLDC)。
  • 电机驱动器 (Motor Drivers): 接收MCU的PWM信号,驱动无刷电机。电机驱动器需要具备足够的电流和电压驱动能力,并提供过流、过压、过温保护等功能。
  • 电源系统 (Power System): 为整个系统提供稳定的电源。通常使用锂电池供电,并配备电源管理芯片进行电压转换和电池管理。
  • 用户界面硬件 (可选): 例如LED指示灯、按键、显示屏等,用于用户交互和系统状态显示。
  • 通信接口硬件 (可选): 例如UART、Bluetooth模块等,用于系统调试、数据传输或远程控制。

2. 硬件抽象层 (HAL - Hardware Abstraction Layer):

HAL层是软件架构的基础,它将硬件细节抽象出来,为上层软件提供统一的硬件访问接口。HAL层的主要职责包括:

  • 初始化硬件外设: 配置MCU的GPIO、ADC、PWM、SPI、I2C、UART、Timer等外设。
  • 提供硬件驱动接口: 封装底层硬件操作,向上层提供统一的API接口,例如:
    • HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) (GPIO 输出)
    • HAL_ADC_GetValue(ADC_HandleTypeDef* hadc) (ADC 读取)
    • HAL_PWM_SetDutyCycle(TIM_HandleTypeDef* htim, uint32_t Channel, uint32_t duty) (PWM 设置占空比)
    • HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) (SPI 通信)
    • HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) (UART 发送)
    • HAL_IMU_ReadData(IMU_DataTypeDef* imu_data) (IMU 数据读取)
    • HAL_Encoder_GetCount(Encoder_HandleTypeDef* encoder) (编码器计数读取)
    • HAL_CurrentSensor_GetValue(CurrentSensor_HandleTypeDef* sensor) (电流传感器值读取)
  • 提供硬件配置接口: 允许上层软件配置硬件参数,例如ADC采样率、PWM频率、SPI波特率等。

HAL层代码示例 (以STM32 HAL库为例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// hal_gpio.h
#ifndef __HAL_GPIO_H__
#define __HAL_GPIO_H__

#include "stm32f4xx_hal.h" // 假设使用STM32F4系列

typedef enum {
GPIO_PIN_RESET = 0,
GPIO_PIN_SET
} GPIO_PinState;

typedef struct {
GPIO_TypeDef* GPIOx;
uint16_t GPIO_Pin;
} GPIO_InitTypeDef;

void HAL_GPIO_Init(GPIO_InitTypeDef* GPIO_InitStruct, GPIO_ModeTypeDef Mode, GPIO_PullTypeDef Pull);
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

#endif // __HAL_GPIO_H__

// hal_gpio.c
#include "hal_gpio.h"

void HAL_GPIO_Init(GPIO_InitTypeDef* GPIO_InitStruct, GPIO_ModeTypeDef Mode, GPIO_PullTypeDef Pull) {
GPIO_InitTypeDef GPIO_Config;
GPIO_Config.Pin = GPIO_InitStruct->GPIO_Pin;
GPIO_Config.Mode = Mode;
GPIO_Config.Pull = Pull;
GPIO_Config.Speed = GPIO_SPEED_FREQ_HIGH; // 可根据需求调整速度

HAL_GPIO_Init(GPIO_InitStruct->GPIOx, &GPIO_Config); // 调用STM32 HAL库函数
}

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) {
HAL_GPIO_WritePin(GPIOx, GPIO_Pin, (GPIO_PinState)PinState); // 调用STM32 HAL库函数
}

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
return HAL_GPIO_ReadPin(GPIOx, GPIO_Pin); // 调用STM32 HAL库函数
}

// ... 类似地实现 HAL_ADC, HAL_PWM, HAL_SPI, HAL_UART, HAL_IMU, HAL_Encoder, HAL_CurrentSensor 等 HAL 驱动

3. 控制层 (Control Layer):

控制层是系统的核心,负责实现平衡车的各种控制功能。控制层主要包含以下模块:

  • 姿态解算模块 (Attitude Estimation): 接收IMU传感器数据,使用滤波算法(例如卡尔曼滤波器、互补滤波器)融合加速度计和陀螺仪数据,解算出平衡车的姿态角(俯仰角、横滚角)。姿态解算模块的精度直接影响平衡控制效果。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    // attitude_estimation.h
    #ifndef __ATTITUDE_ESTIMATION_H__
    #define __ATTITUDE_ESTIMATION_H__

    #include "hal_imu.h"

    typedef struct {
    float pitch; // 俯仰角 (Pitch)
    float roll; // 横滚角 (Roll)
    float yaw; // 偏航角 (Yaw) - 可选,平衡车可能不需要
    } AttitudeTypeDef;

    void AttitudeEstimation_Init(void);
    void AttitudeEstimation_Update(IMU_DataTypeDef* imu_data, float dt);
    AttitudeTypeDef AttitudeEstimation_GetAttitude(void);

    #endif // __ATTITUDE_ESTIMATION_H__

    // attitude_estimation.c
    #include "attitude_estimation.h"
    #include <math.h>

    static AttitudeTypeDef attitude;

    void AttitudeEstimation_Init(void) {
    // 初始化姿态解算参数,例如滤波器参数
    attitude.pitch = 0.0f;
    attitude.roll = 0.0f;
    attitude.yaw = 0.0f;
    }

    void AttitudeEstimation_Update(IMU_DataTypeDef* imu_data, float dt) {
    // 简化的互补滤波器示例 (实际应用中可能需要更复杂的滤波器)
    float gyro_pitch = imu_data->gyro_y; // 假设陀螺仪Y轴测量俯仰角速度
    float gyro_roll = imu_data->gyro_x; // 假设陀螺仪X轴测量横滚角速度
    float accel_pitch = atan2f(-imu_data->accel_x, sqrtf(imu_data->accel_y * imu_data->accel_y + imu_data->accel_z * imu_data->accel_z)); // 俯仰角加速度计估计
    float accel_roll = atan2f(imu_data->accel_y, sqrtf(imu_data->accel_x * imu_data->accel_x + imu_data->accel_z * imu_data->accel_z)); // 横滚角加速度计估计

    float alpha = 0.98f; // 互补滤波器系数

    attitude.pitch = alpha * (attitude.pitch + gyro_pitch * dt) + (1.0f - alpha) * accel_pitch;
    attitude.roll = alpha * (attitude.roll + gyro_roll * dt) + (1.0f - alpha) * accel_roll;

    // 偏航角解算 (如果需要) ...
    }

    AttitudeTypeDef AttitudeEstimation_GetAttitude(void) {
    return attitude;
    }
  • 平衡控制模块 (Balance Control): 根据姿态解算模块提供的姿态角,使用PID控制算法控制电机,使平衡车保持平衡。平衡控制是平衡车系统的核心功能。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    // balance_control.h
    #ifndef __BALANCE_CONTROL_H__
    #define __BALANCE_CONTROL_H__

    #include "attitude_estimation.h"
    #include "motor_control.h"

    typedef struct {
    float kp; // 比例系数
    float ki; // 积分系数
    float kd; // 微分系数
    float integral_limit; // 积分限幅
    } PID_TypeDef;

    typedef struct {
    PID_TypeDef pitch_pid; // 俯仰角PID控制器
    float target_pitch; // 目标俯仰角 (通常为0度)
    } BalanceControlTypeDef;

    void BalanceControl_Init(void);
    void BalanceControl_Update(AttitudeTypeDef* attitude, float dt);
    void BalanceControl_SetTargetPitch(float target_pitch);

    #endif // __BALANCE_CONTROL_H__

    // balance_control.c
    #include "balance_control.h"

    static BalanceControlTypeDef balance_control;
    static float pitch_integral_error = 0.0f;
    static float last_pitch_error = 0.0f;

    void BalanceControl_Init(void) {
    // 初始化PID参数
    balance_control.pitch_pid.kp = 10.0f;
    balance_control.pitch_pid.ki = 0.1f;
    balance_control.pitch_pid.kd = 0.01f;
    balance_control.pitch_pid.integral_limit = 100.0f;
    balance_control.target_pitch = 0.0f;
    }

    void BalanceControl_Update(AttitudeTypeDef* attitude, float dt) {
    float pitch_error = balance_control.target_pitch - attitude->pitch;

    pitch_integral_error += pitch_error * dt;
    if (pitch_integral_error > balance_control.pitch_pid.integral_limit) {
    pitch_integral_error = balance_control.pitch_pid.integral_limit;
    } else if (pitch_integral_error < -balance_control.pitch_pid.integral_limit) {
    pitch_integral_error = -balance_control.pitch_pid.integral_limit;
    }

    float pitch_derivative_error = (pitch_error - last_pitch_error) / dt;
    last_pitch_error = pitch_error;

    float pitch_control_output = balance_control.pitch_pid.kp * pitch_error +
    balance_control.pitch_pid.ki * pitch_integral_error +
    balance_control.pitch_pid.kd * pitch_derivative_error;

    // 将平衡控制输出转换为电机控制指令 (例如,调整左右电机速度差)
    // 这里假设 pitch_control_output 直接映射到左右电机速度差,实际应用中可能需要更复杂的映射关系
    MotorControl_SetMotorSpeedDifference(pitch_control_output);
    }

    void BalanceControl_SetTargetPitch(float target_pitch) {
    balance_control.target_pitch = target_pitch;
    }
  • 速度控制模块 (Speed Control): 根据用户期望的速度,控制平衡车的整体速度。速度控制可以与平衡控制协同工作,例如,通过调整平衡车的平衡点来实现速度控制。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    // speed_control.h
    #ifndef __SPEED_CONTROL_H__
    #define __SPEED_CONTROL_H__

    #include "encoder.h"
    #include "motor_control.h"

    typedef struct {
    float kp;
    float ki;
    float kd;
    float integral_limit;
    } PID_TypeDef;

    typedef struct {
    PID_TypeDef speed_pid;
    float target_speed; // 目标速度 (例如,单位:米/秒)
    } SpeedControlTypeDef;

    void SpeedControl_Init(void);
    void SpeedControl_Update(float current_speed, float dt);
    void SpeedControl_SetTargetSpeed(float target_speed);

    #endif // __SPEED_CONTROL_H__

    // speed_control.c
    #include "speed_control.h"

    static SpeedControlTypeDef speed_control;
    static float speed_integral_error = 0.0f;
    static float last_speed_error = 0.0f;

    void SpeedControl_Init(void) {
    // 初始化速度PID参数
    speed_control.speed_pid.kp = 1.0f;
    speed_control.speed_pid.ki = 0.01f;
    speed_control.speed_pid.kd = 0.001f;
    speed_control.speed_pid.integral_limit = 50.0f;
    speed_control.target_speed = 0.0f; // 初始目标速度为0
    }

    void SpeedControl_Update(float current_speed, float dt) {
    float speed_error = speed_control.target_speed - current_speed;

    speed_integral_error += speed_error * dt;
    if (speed_integral_error > speed_control.speed_pid.integral_limit) {
    speed_integral_error = speed_control.speed_pid.integral_limit;
    } else if (speed_integral_error < -speed_control.speed_pid.integral_limit) {
    speed_integral_error = -speed_control.speed_pid.integral_limit;
    }

    float speed_derivative_error = (speed_error - last_speed_error) / dt;
    last_speed_error = speed_error;

    float speed_control_output = speed_control.speed_pid.kp * speed_error +
    speed_control.speed_pid.ki * speed_integral_error +
    speed_control.speed_pid.kd * speed_derivative_error;

    // 将速度控制输出转换为电机控制指令 (例如,调整左右电机共同速度)
    // 这里假设 speed_control_output 直接映射到左右电机共同速度,实际应用中可能需要更复杂的映射关系
    MotorControl_SetMotorSpeedBase(speed_control_output);
    }

    void SpeedControl_SetTargetSpeed(float target_speed) {
    speed_control.target_speed = target_speed;
    }
  • 电机控制模块 (Motor Control - FOC): 实现无刷电机的磁场定向控制 (FOC)。FOC算法能够精确控制电机的转矩和速度,提高电机效率和响应速度。FOC模块通常包含以下子模块:

    • 电流采样: 读取电流传感器数据,获取电机相电流。
    • 坐标变换 (Clarke & Park): 将三相静止坐标系电流变换到两相旋转坐标系 (dq坐标系)。
    • 电流环 PID 控制: 在dq坐标系下分别控制直轴电流 (Id) 和交轴电流 (Iq)。Id通常设置为0,Iq控制电机转矩。
    • 反Park变换 (Inverse Park): 将dq坐标系下的电压控制量变换回三相静止坐标系。
    • PWM 发生器: 根据三相电压控制量,生成PWM信号驱动电机驱动器。
    • 编码器反馈处理: 读取编码器数据,获取电机转子位置,用于坐标变换和速度控制。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    // motor_control.h
    #ifndef __MOTOR_CONTROL_H__
    #define __MOTOR_CONTROL_H__

    #include "hal_pwm.h"
    #include "hal_encoder.h"
    #include "hal_current_sensor.h"

    #define MOTOR_POLE_PAIRS 7 // 电机极对数 (根据实际电机参数修改)

    typedef struct {
    float kp_id; // Id电流环比例系数
    float ki_id; // Id电流环积分系数
    float kp_iq; // Iq电流环比例系数
    float ki_iq; // Iq电流环积分系数
    float integral_limit_id; // Id积分限幅
    float integral_limit_iq; // Iq积分限幅
    } FOC_PID_TypeDef;

    typedef struct {
    FOC_PID_TypeDef current_pid;
    float target_iq_current; // 目标Iq电流 (控制转矩)
    float target_speed; // 目标速度 (可选,可以结合速度环)
    } MotorControlTypeDef;

    void MotorControl_Init(void);
    void MotorControl_Update(float dt);
    void MotorControl_SetMotorSpeedBase(float speed); // 设置左右电机共同速度
    void MotorControl_SetMotorSpeedDifference(float diff); // 设置左右电机速度差 (用于平衡和转向)
    void MotorControl_SetMotorEnable(uint8_t enable);

    #endif // __MOTOR_CONTROL_H__

    // motor_control.c
    #include "motor_control.h"
    #include <math.h>

    static MotorControlTypeDef motor_control;
    static float id_integral_error = 0.0f;
    static float iq_integral_error = 0.0f;
    static float motor_speed_base = 0.0f;
    static float motor_speed_diff = 0.0f;
    static uint8_t motor_enabled = 0;

    void MotorControl_Init(void) {
    // 初始化FOC PID参数
    motor_control.current_pid.kp_id = 1.0f;
    motor_control.current_pid.ki_id = 0.01f;
    motor_control.current_pid.kp_iq = 1.0f;
    motor_control.current_pid.ki_iq = 0.01f;
    motor_control.current_pid.integral_limit_id = 1.0f;
    motor_control.current_pid.integral_limit_iq = 1.0f;
    motor_control.target_iq_current = 0.0f;
    motor_control.target_speed = 0.0f;

    // 初始化PWM和编码器
    // ... (调用 HAL_PWM_Init, HAL_Encoder_Init 等函数)
    }

    void MotorControl_Update(float dt) {
    if (!motor_enabled) {
    HAL_PWM_SetDutyCycle(/* ... */, 0); // 关闭PWM输出
    HAL_PWM_SetDutyCycle(/* ... */, 0);
    HAL_PWM_SetDutyCycle(/* ... */, 0);
    return;
    }

    // 1. 电流采样
    float current_u = HAL_CurrentSensor_GetValue(/* ... */); // 获取U相电流
    float current_v = HAL_CurrentSensor_GetValue(/* ... */); // 获取V相电流
    float current_w = -current_u - current_v; // W相电流 (三相电流和为0)

    // 2. 编码器反馈
    int32_t encoder_count = HAL_Encoder_GetCount(/* ... */); // 获取编码器计数
    float electrical_angle = (float)encoder_count * 2.0f * M_PI * MOTOR_POLE_PAIRS / (float)ENCODER_RESOLUTION; // 计算电角度 (ENCODER_RESOLUTION为编码器分辨率)

    // 3. Clarke变换 (abc -> alpha-beta)
    float current_alpha = (2.0f / 3.0f) * current_u - (1.0f / 3.0f) * current_v - (1.0f / 3.0f) * current_w;
    float current_beta = (1.0f / sqrtf(3.0f)) * (current_v - current_w);

    // 4. Park变换 (alpha-beta -> dq)
    float cos_theta = cosf(electrical_angle);
    float sin_theta = sinf(electrical_angle);
    float current_d = current_alpha * cos_theta + current_beta * sin_theta;
    float current_q = -current_alpha * sin_theta + current_beta * cos_theta;

    // 5. 电流环 PID 控制 (Id环)
    float id_error = 0.0f - current_d; // 目标Id电流为0
    id_integral_error += id_error * dt;
    if (id_integral_error > motor_control.current_pid.integral_limit_id) {
    id_integral_error = motor_control.current_pid.integral_limit_id;
    } else if (id_integral_error < -motor_control.current_pid.integral_limit_id) {
    id_integral_error = -motor_control.current_pid.integral_limit_id;
    }
    float voltage_d = motor_control.current_pid.kp_id * id_error + motor_control.current_pid.ki_id * id_integral_error;

    // 6. 电流环 PID 控制 (Iq环)
    float iq_error = motor_control.target_iq_current - current_q;
    iq_integral_error += iq_error * dt;
    if (iq_integral_error > motor_control.current_pid.integral_limit_iq) {
    iq_integral_error = motor_control.current_pid.integral_limit_iq;
    } else if (iq_integral_error < -motor_control.current_pid.integral_limit_iq) {
    iq_integral_error = -motor_control.current_pid.integral_limit_iq;
    }
    float voltage_q = motor_control.current_pid.kp_iq * iq_error + motor_control.current_pid.ki_iq * iq_integral_error;

    // 7. 反Park变换 (dq -> alpha-beta)
    float voltage_alpha = voltage_d * cos_theta - voltage_q * sin_theta;
    float voltage_beta = voltage_d * sin_theta + voltage_q * cos_theta;

    // 8. 空间矢量调制 (SVM) 或 SVPWM (Simplified Space Vector PWM) - 这里简化为电压映射到PWM占空比
    // 实际应用中需要实现 SVPWM 算法,此处仅为示例
    float voltage_u = voltage_alpha;
    float voltage_v = (-0.5f) * voltage_alpha + (sqrtf(3.0f) / 2.0f) * voltage_beta;
    float voltage_w = (-0.5f) * voltage_alpha - (sqrtf(3.0f) / 2.0f) * voltage_beta;

    // 9. 电压限幅 (可选)
    float voltage_limit = /* ... */; // 根据电源电压和电机参数设定电压限幅
    voltage_u = fmaxf(fminf(voltage_u, voltage_limit), -voltage_limit);
    voltage_v = fmaxf(fminf(voltage_v, voltage_limit), -voltage_limit);
    voltage_w = fmaxf(fminf(voltage_w, voltage_limit), -voltage_limit);

    // 10. 计算 PWM 占空比 (假设 PWM 范围 0-1000)
    uint32_t duty_u = (uint32_t)((voltage_u / voltage_limit) * 500.0f + 500.0f); // 将电压映射到 PWM 占空比
    uint32_t duty_v = (uint32_t)((voltage_v / voltage_limit) * 500.0f + 500.0f);
    uint32_t duty_w = (uint32_t)((voltage_w / voltage_limit) * 500.0f + 500.0f);

    // 11. 设置 PWM 占空比
    HAL_PWM_SetDutyCycle(/* ... PWM U Channel ... */, duty_u);
    HAL_PWM_SetDutyCycle(/* ... PWM V Channel ... */, duty_v);
    HAL_PWM_SetDutyCycle(/* ... PWM W Channel ... */, duty_w);
    }

    void MotorControl_SetMotorSpeedBase(float speed) {
    motor_speed_base = speed;
    // 将基准速度转换为 Iq 电流目标值 (需要根据电机特性和控制策略进行转换)
    motor_control.target_iq_current = speed * /* speed_to_iq_current_factor */;
    }

    void MotorControl_SetMotorSpeedDifference(float diff) {
    motor_speed_diff = diff;
    // 可以根据速度差调整左右电机的 Iq 电流目标值,实现转向或平衡调整
    // ... (具体实现取决于平衡车的转向机制)
    }

    void MotorControl_SetMotorEnable(uint8_t enable) {
    motor_enabled = enable;
    }

4. 应用层 (Application Layer):

应用层是最高层,负责实现系统的整体功能和用户交互。应用层可能包含以下模块:

  • 系统管理模块 (System Management): 负责系统初始化、任务调度、错误处理、状态监控、参数配置、固件升级等系统管理功能。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    // system_management.h
    #ifndef __SYSTEM_MANAGEMENT_H__
    #define __SYSTEM_MANAGEMENT_H__

    void SystemManagement_Init(void);
    void SystemManagement_RunTask(void); // 系统主任务
    void SystemManagement_HandleError(uint32_t error_code);
    void SystemManagement_SetSystemState(uint8_t state);
    uint8_t SystemManagement_GetSystemState(void);
    void SystemManagement_LoadConfiguration(void);
    void SystemManagement_SaveConfiguration(void);
    void SystemManagement_FirmwareUpdate(void); // 固件升级 (可选)

    #endif // __SYSTEM_MANAGEMENT_H__

    // system_management.c
    #include "system_management.h"
    #include "hal_gpio.h"
    #include "hal_uart.h"
    #include "attitude_estimation.h"
    #include "balance_control.h"
    #include "speed_control.h"
    #include "motor_control.h"

    #define SYSTEM_STATE_INIT 0
    #define SYSTEM_STATE_IDLE 1
    #define SYSTEM_STATE_BALANCING 2
    #define SYSTEM_STATE_ERROR 3

    static uint8_t system_state = SYSTEM_STATE_INIT;

    void SystemManagement_Init(void) {
    // 初始化 HAL
    // ... (HAL_GPIO_Init, HAL_ADC_Init, HAL_PWM_Init, HAL_SPI_Init, HAL_UART_Init, HAL_Timer_Init 等)

    // 初始化各模块
    AttitudeEstimation_Init();
    BalanceControl_Init();
    SpeedControl_Init();
    MotorControl_Init();

    SystemManagement_LoadConfiguration(); // 加载配置参数

    SystemManagement_SetSystemState(SYSTEM_STATE_IDLE); // 设置系统状态为 IDLE
    }

    void SystemManagement_RunTask(void) {
    float dt = 0.01f; // 任务周期 (例如 10ms) - 需要根据实际情况调整
    static uint32_t last_time = 0;
    uint32_t current_time = HAL_GetTick(); // 获取当前时间 (假设使用 HAL_GetTick() 获取系统滴答计数)
    dt = (float)(current_time - last_time) / 1000.0f; // 计算时间间隔 (秒)
    last_time = current_time;

    if (system_state == SYSTEM_STATE_IDLE) {
    // 空闲状态处理 ...
    MotorControl_SetMotorEnable(0); // 禁用电机
    } else if (system_state == SYSTEM_STATE_BALANCING) {
    // 平衡状态处理
    IMU_DataTypeDef imu_data;
    HAL_IMU_ReadData(&imu_data); // 读取 IMU 数据
    AttitudeEstimation_Update(&imu_data, dt); // 姿态解算
    AttitudeTypeDef attitude = AttitudeEstimation_GetAttitude();
    BalanceControl_Update(&attitude, dt); // 平衡控制
    // SpeedControl_Update(/* ... current speed ... */, dt); // 速度控制 (如果需要)
    MotorControl_Update(dt); // 电机控制 (FOC)
    MotorControl_SetMotorEnable(1); // 启用电机
    } else if (system_state == SYSTEM_STATE_ERROR) {
    // 错误状态处理 ...
    MotorControl_SetMotorEnable(0); // 禁用电机
    // ... 错误指示,日志记录等 ...
    }

    // 其他系统任务,例如通信处理、用户界面更新等 ...
    }

    void SystemManagement_HandleError(uint32_t error_code) {
    SystemManagement_SetSystemState(SYSTEM_STATE_ERROR);
    // ... 错误处理逻辑,例如记录错误日志,报警,重启系统等 ...
    HAL_UART_Transmit(/* ... UART for debug ... */, (uint8_t*)"Error!", sizeof("Error!")); // 通过 UART 输出错误信息
    }

    void SystemManagement_SetSystemState(uint8_t state) {
    system_state = state;
    }

    uint8_t SystemManagement_GetSystemState(void) {
    return system_state;
    }

    void SystemManagement_LoadConfiguration(void) {
    // 从 Flash 或其他存储介质加载配置参数 (例如 PID 参数,电机参数等)
    // ...
    HAL_UART_Transmit(/* ... UART for debug ... */, (uint8_t*)"Config Loaded!", sizeof("Config Loaded!"));
    }

    void SystemManagement_SaveConfiguration(void) {
    // 将配置参数保存到 Flash 或其他存储介质
    // ...
    HAL_UART_Transmit(/* ... UART for debug ... */, (uint8_t*)"Config Saved!", sizeof("Config Saved!"));
    }

    void SystemManagement_FirmwareUpdate(void) {
    // 实现固件升级功能 (例如通过 UART 或 OTA 方式) - 可选功能
    // ...
    HAL_UART_Transmit(/* ... UART for debug ... */, (uint8_t*)"FW Update Started!", sizeof("FW Update Started!"));
    }
  • 用户界面模块 (UI) - 可选: 如果平衡车需要用户交互,例如通过按键、LED、显示屏或上位机软件进行控制和状态显示,则需要用户界面模块。UI模块负责处理用户输入,显示系统状态,并与控制层进行交互。

主程序 (main.c):

主程序是整个嵌入式系统的入口点,负责初始化系统,启动系统任务,进入主循环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// main.c
#include "system_management.h"
#include "delay.h" // 假设有延时函数库

int main(void) {
HAL_Init(); // 初始化 STM32 HAL 库
SystemManagement_Init(); // 初始化系统管理模块
Delay_Init(); // 初始化延时函数库

while (1) {
SystemManagement_RunTask(); // 运行系统主任务
Delay_ms(1); // 任务周期延时 (例如 1ms 或 10ms)
}
}

项目中采用的技术和方法:

  • 分层模块化架构: 如上所述,提高代码可维护性、可重用性和可扩展性。
  • HAL硬件抽象层: 屏蔽硬件差异,方便代码移植和维护。
  • FOC磁场定向控制: 实现无刷电机的高效精确控制。
  • PID控制算法: 用于平衡控制、速度控制和电流环控制。
  • 姿态解算算法 (互补滤波/卡尔曼滤波): 融合IMU数据,准确获取平衡车姿态。
  • 实时操作系统 (RTOS) - 可选: 对于更复杂的系统,可以考虑使用RTOS(例如FreeRTOS)进行任务调度和资源管理,提高系统实时性和可靠性。
  • 代码版本控制 (Git): 管理代码版本,方便团队协作和代码维护。
  • 单元测试和集成测试: 保证代码质量和系统稳定性。
  • 代码审查: 提高代码质量,发现潜在问题。
  • 详细的代码注释和文档: 提高代码可读性和可维护性。

代码量说明:

上述代码示例虽然只是框架和部分核心功能的实现,但已经展示了分层模块化架构的基本结构和关键模块的代码实现思路。 要达到3000行以上的代码量,需要:

  1. 完善HAL层驱动: 实现所有硬件外设的HAL驱动,包括GPIO、ADC、PWM、SPI、I2C、UART、Timer、IMU、编码器、电流传感器等,并提供详细的初始化、配置和数据读写函数。
  2. 完善控制层算法: 实现更精细的姿态解算算法 (例如卡尔曼滤波器)、更完善的PID控制算法 (包括参数整定、抗积分饱和、微分先行等)、电机FOC算法的完整实现 (包括 SVPWM、弱磁控制等)。
  3. 实现应用层功能: 完善系统管理模块的功能,例如错误处理、状态机管理、参数配置、固件升级、通信协议 (例如 UART 调试协议、蓝牙通信协议) 等。
  4. 添加用户界面模块 (可选): 如果需要用户界面,需要实现UI驱动、UI逻辑、用户交互功能等。
  5. 编写详细的代码注释和文档: 为每个函数、变量、模块添加详细的注释,编写系统设计文档、API文档、用户手册等。
  6. 编写测试代码: 编写单元测试代码、集成测试代码、系统测试代码,覆盖各个模块和功能。

通过以上工作,代码量很容易超过3000行。 实际上,一个完整的嵌入式平衡车项目,代码量通常远不止3000行,尤其是在包含RTOS、复杂控制算法、图形界面、通信协议等功能的情况下。

总结:

Mini FOC无刷平衡车V2.0版本的嵌入式系统软件架构设计至关重要。 采用分层模块化架构,结合HAL硬件抽象层、控制层和应用层,可以构建一个可靠、高效、可扩展的系统平台。 项目中采用FOC电机控制、PID控制、姿态解算等成熟技术,并结合严格的软件工程方法,能够确保项目的成功交付和长期维护。 希望以上详细的架构设计和代码示例能够为您提供有价值的参考。

欢迎关注我的其它发布渠道