第二周任务:STM32 + 永刚VESC6电调 + N5065电机CAN通信控制

STM32 + VESC6 + N5065电机CAN通信控制教程

硬件平台 :STM32G474VET6 + VESC6电调 + N5065无刷电机
开发环境 :CubeMX + CLion + OpenOCD(DAPLink调试器)
上位机:VOFA+ 和 VESC Tool 6.02

后续会将项目代码上传至github

效果展示

vofa+视角

电机视角
上位机教程

哔哩哔哩

VESC6.4电机驱动器固件更新和简单测试 VESC6.4使用教程(一)_哔哩哔哩_bilibili

csdn

VESC电调使用教程进阶篇之电机调参校准功能步骤详细解说-CSDN博客

N5065有感(带霍尔传感器))

永刚VESC6


一、VESC电调预配置(必须先完成)

1.1 使用VESC Tool连接电调

  1. 将VESC6电调通过USB连接到电脑
  2. 打开VESC_Tool_6.02.exe
  3. 点击右上角"连接"按钮,选择对应COM口

后续步骤参考

VESC电调使用教程进阶篇之电机调参校准功能步骤详细解说-CSDN博客

1.2 电机检测与配置

  1. 进入左侧菜单:Motor Settings → FOC → General

  2. 点击 Run Detection 按钮

  3. 按照提示完成:

    • 电机参数检测
    • 霍尔传感器检测(如果有)
    • 确认检测结果
  4. 点击 Apply 保存配置

1.3 设置CAN总线ID(关键步骤)

  1. 进入左侧菜单:App Settings → General
  2. 找到 CAN Status Message Mode ,设置为 CAN_STATUS_1_2_3_4_5
  3. 找到 Controller ID,设置ID号(默认为0,可设置0-254)
  4. 记住这个ID号,后续代码中需要使用
  5. 点击 Write Configuration 保存

1.4 CAN通信参数设置

  1. 进入左侧菜单:App Settings → CAN
  2. 设置 CAN Baud Rate500000(500kbps)
  3. 确认 Send CAN Status 已勾选
  4. 点击 Write Configuration 保存

注意:配置完成后断开USB,使用CAN总线通信时不要同时连接USB


二、CubeMX硬件配置

2.1 创建新工程

  1. 打开STM32CubeMX
  2. 选择芯片:STM32G474VETx
  3. 设置工程名:VESC6_N5065_Motor_Control

2.2 时钟配置(RCC)

路径Pinout & Configuration → System Core → RCC

  • HSE (High Speed External) :Crystal/Ceramic Resonator
  • LSE (Low Speed External) :Disable

Clock Configuration标签页

  • Input frequency: 48 MHz(外部晶振频率)
  • PLL Source Mux: HSE
  • PLLM: /12
  • PLLN: ×85
  • System Clock Mux: PLLCLK
  • HCLK: 170 MHz
  • APB1: /2 → 85 MHz
  • APB2: 170 MHz

2.3 FDCAN1配置(CAN总线)

路径Connectivity → FDCAN1

Mode标签页

  • Mode: Activated(勾选)

Parameter Settings

  • Nominal Prescaler: 10
  • Nominal Time Seg1: 13
  • Nominal Time Seg2: 3
  • Nominal Sync Jump Width: 1
  • Data Prescaler: 1

计算得到波特率

ini 复制代码
CAN_Clock = 85MHz / 10 = 8.5MHz
Bit_Time = 1 + 13 + 3 = 17
Baud_Rate = 8.5MHz / 17 = 500kbps

GPIO配置(自动设置):

  • PA11: FDCAN1_RX
  • PA12: FDCAN1_TX

NVIC Settings(中断配置):

  • ✅ FDCAN1_IT0_IRQn(勾选使能)

2.4 USART1配置(VOFA通信)

路径Connectivity → USART1

Mode标签页

  • Mode: Asynchronous

Parameter Settings

  • Baud Rate: 115200 Bits/s
  • Word Length: 8 Bits
  • Parity: None
  • Stop Bits: 1

GPIO配置(自动设置):

  • PC4: USART1_TX
  • PC5: USART1_RX

NVIC Settings

  • ✅ USART1 global interrupt(勾选使能)

2.5 TIM2定时器配置(10ms任务循环)

路径Timers → TIM2

Clock Source

  • Internal Clock(内部时钟源)

Parameter Settings

  • Prescaler: 16999
  • Counter Period: 99
  • Auto-reload preload: Enable

计算公式

ini 复制代码
Timer_Clock = 170MHz
Prescaler = 16999 → 实际分频系数 = 17000
Counter_Clock = 170MHz / 17000 = 10kHz
Period = 99 → 实际周期 = 100
Interrupt_Freq = 10kHz / 100 = 100Hz → 10ms中断一次

NVIC Settings

  • ✅ TIM2 global interrupt(勾选使能)

2.6 GPIO配置(LED指示灯)

路径System Core → GPIO

手动配置两个LED引脚:

  • PE12: GPIO_Output(LED1)
  • PE13: GPIO_Output(LED2)

配置参数:

  • Output Level: Low
  • Mode: Output Push Pull
  • Pull-up/Pull-down: No pull-up and no pull-down
  • Max output speed: Low

2.7 调试接口配置

路径System Core → SYS

Debug

  • Serial Wire(保留SWD调试接口)

Timebase Source

  • TIM1(避免与HAL_Delay冲突)

2.8 中断优先级配置

路径System Core → NVIC

NVIC标签页配置优先级:

  • TIM1 UP TIM16: Priority 15(最低,用于系统滴答)
  • FDCAN1_IT0: Priority 0(最高,CAN接收)
  • USART1: Priority 0(高优先级,串口接收)
  • TIM2: Priority 0(高优先级,控制任务)

2.9 生成代码

  1. Project Manager → Project

    • Project Name: VESC6_N5065_Motor_Control
    • Toolchain/IDE: STM32CubeIDE
  2. Code Generator

    • ✅ Generate peripheral initialization as a pair of '.c/.h' files per peripheral
  3. 点击右上角 GENERATE CODE 生成工程


三、CLion工程配置

3.1 导入CubeMX生成的工程

  1. 将生成的工程复制到工作目录
  2. 在CLion中打开工程的CMakeLists.txt文件

3.2 添加自定义源文件

Core目录下直接添加用户文件:

bash 复制代码
Core/
├── Inc/                           # 头文件目录
│   ├── main.h                    # CubeMX生成
│   ├── stm32g4xx_it.h           # CubeMX生成
│   ├── stm32g4xx_hal_conf.h     # CubeMX生成
│   ├── motor_control.h          # 手动添加
│   ├── vesc_communication.h     # 手动添加
│   ├── vesc_motor.h             # 手动添加
│   └── vofa_protocol.h          # 手动添加
└── Src/                           # 源文件目录
    ├── main.c                    # CubeMX生成(需修改)
    ├── stm32g4xx_it.c           # CubeMX生成
    ├── stm32g4xx_hal_msp.c      # CubeMX生成
    ├── system_stm32g4xx.c       # CubeMX生成
    ├── motor_control.c          # 手动添加
    ├── vesc_communication.c     # 手动添加
    ├── vesc_motor.c             # 手动添加
    └── vofa_protocol.c          # 手动添加

3.3 CMakeLists.txt说明

CubeMX生成的CMakeLists.txt已经包含了Core/IncCore/Src,无需额外修改。 用户自定义文件直接放在这两个目录下即可自动编译。

3.4 配置OpenOCD调试(DAPLink)

创建文件 :项目根目录创建daplink.cfg

粘贴配置内容 :(见项目文件daplink.cfg

CLion Run Configuration

  1. Edit Configurations → + → OpenOCD Download & Run
  2. Board config file: 选择 daplink.cfg
  3. Executable: 选择生成的.elf文件

四、硬件连接

4.1 STM32与VESC6连接

STM32引脚 VESC6引脚 说明
PA11 (FDCAN1_RX) CAN_H CAN总线H
PA12 (FDCAN1_TX) CAN_L CAN总线L
GND GND 共地

注意

  • 需要在CAN_H和CAN_L之间接120Ω终端电阻
  • STM32和VESC必须共地
  • CAN总线不需要供电引脚

4.2 STM32与VOFA连接(USB转TTL)

STM32引脚 USB转TTL 说明
PC4 (USART1_TX) RX 串口接收
PC5 (USART1_RX) TX 串口发送
GND GND 共地

4.3 DAPLink调试器连接

STM32引脚 DAPLink 说明
PA13 (SWDIO) SWDIO 调试数据
PA14 (SWCLK) SWCLK 调试时钟
GND GND 共地
3V3 3V3 供电(可选)

4.4 电源连接

  • STM32:5V或3.3V供电(视开发板而定)
  • VESC6:电池供电(根据电机电压选择,N5065建议12-48V)
  • 电机:连接到VESC的三相输出端子

五、VOFA+上位机调试

5.1 VOFA配置

  1. 打开VOFA+软件
  2. 选择对应的串口(USB转TTL的COM口)
  3. 波特率设置为:115200
  4. 协议选择:FireWater(CSV模式)

5.2 数据通道配置

在VOFA中配置8个通道(按CSV顺序):

  1. target_duty - 目标占空比
  2. current_duty - 当前占空比
  3. current_rpm - 当前转速
  4. target_current - 目标电流
  5. current_current - 当前电流
  6. temp_fet - MOSFET温度
  7. temp_motor - 电机温度
  8. control_type - 控制模式

5.3 控制指令格式

在VOFA的"发送区"输入以下指令(输入后按回车发送):

切换控制模式

bash 复制代码
mode:0    # 占空比模式
mode:1    # 电流模式
mode:2    # 转速模式
mode:3    # 刹车模式

占空比控制(-1.0 ~ 1.0):

bash 复制代码
duty:0.05     # 正转5%占空比
duty:-0.05    # 反转5%占空比
duty:0        # 停止

电流控制(单位:A):

bash 复制代码
current:1.5   # 正转1.5A电流
current:-2.0  # 反转2A电流(刹车)

转速控制(单位:RPM):

bash 复制代码
rpm:1000      # 正转1000RPM
rpm:-500      # 反转500RPM

刹车控制(单位:A):

bash 复制代码
brake:3.0     # 3A刹车电流

通用目标值设置

bash 复制代码
target:0.1    # 根据当前模式设置目标值

使能控制

bash 复制代码
enable:1      # 使能电机控制
enable:0      # 禁用电机控制

紧急停止

arduino 复制代码
stop          # 立即停止电机

六、测试与调试流程

6.1 第一次上电测试(安全检查)

  1. 断开电机,仅连接STM32和VESC6的CAN线

  2. 给STM32和VESC分别上电

  3. 观察LED指示:

    • LED1应该每500ms闪烁一次(心跳)
    • LED2应该每2秒闪烁一次(系统运行)
  4. 打开VOFA,观察是否收到数据(此时RPM和电流应为0)

6.2 电机低速测试

  1. 连接电机到VESC
  2. 在VOFA中发送:duty:0.05
  3. 观察电机是否缓慢转动
  4. 在VOFA中发送:stop
  5. 观察电机是否停止

6.3 反向测试

  1. 在VOFA中发送:duty:-0.05
  2. 观察电机是否反向转动
  3. 发送:stop

6.4 逐步提升测试

  1. 逐步增加占空比:duty:0.1duty:0.2duty:0.3
  2. 观察转速变化和系统稳定性
  3. 监控温度数据(不应超过80°C)

6.5 其他模式测试

电流模式测试

makefile 复制代码
mode:1
current:2.0

转速模式测试

makefile 复制代码
mode:2
rpm:1500

七、can通信波特率计算

根据你的时钟配置图,让我详细分析CAN波特率的计算过程:

第一步:确定FDCAN时钟源

从你的时钟树图可以看到:

PLL配置路径

  1. HSE输入:48 MHz(外部晶振)
  2. PLLM分频 :÷12 → 48MHz ÷ 12 = 4 MHz(PLL输入)
  3. PLLN倍频 :×85 → 4MHz × 85 = 340 MHz(VCO频率)
  4. PLLQ分频 :÷4 → 340MHz ÷ 4 = 85 MHz(FDCAN时钟源)

关键 :FDCAN使用的是PLLQ输出 ,频率为 85 MHz

第二步:CAN波特率计算公式

CAN波特率由以下参数决定:

scss 复制代码
波特率 = FDCAN_Clock / (Prescaler × Bit_Time)

其中:

  • FDCAN_Clock = 85 MHz(PLLQ输出)
  • Prescaler(预分频器) = 10
  • Bit_Time(位时间) = Sync_Seg + Time_Seg1 + Time_Seg2

第三步:位时间构成

你的配置参数:

  • Sync_Seg(同步段) = 1 TQ(固定值,总是1)
  • Time_Seg1 = 13 TQ
  • Time_Seg2 = 3 TQ
ini 复制代码
Bit_Time = 1 + 13 + 3 = 17 TQ(时间量子)

第四步:最终计算

方法1:直接计算
ini 复制代码
波特率 = 85,000,000 Hz / (10 × 17)
       = 85,000,000 / 170
       = 500,000 bps
       = 500 kbps
方法2:分步计算(更直观)
ini 复制代码
步骤1:计算CAN模块时钟
CAN_Module_Clock = FDCAN_Clock / Prescaler
                 = 85 MHz / 10
                 = 8.5 MHz

步骤2:计算波特率
波特率 = CAN_Module_Clock / Bit_Time
       = 8.5 MHz / 17
       = 500 kbps

关键参数对照表

参数 配置值 说明
FDCAN时钟源 PLLQ = 85 MHz 来自PLL的Q输出
Prescaler 10 CAN模块分频
Sync_Seg 1 TQ 固定值
Time_Seg1 13 TQ 传播段+相位段1
Time_Seg2 3 TQ 相位段2
总位时间 17 TQ 1个CAN位的时间量子数
最终波特率 500 kbps 与VESC默认匹配

采样点位置

采样点 = (Sync_Seg + Time_Seg1) / Bit_Time = (1 + 13) / 17 = 82.35%

这是一个标准的CAN采样点位置(推荐75%-90%)。

为什么选择这些参数?

  1. 500 kbps:VESC默认CAN波特率,工业标准
  2. Prescaler=10:在85MHz下得到合适的TQ时钟
  3. 17 TQ:足够的位时间用于同步和采样
  4. 采样点82% :确保良好的抗干扰能力

这个配置与VESC Tool中设置的500kbps完全匹配!


八、常见问题排查

8.1 电机不转

可能原因

  1. CAN总线连接错误 → 检查CAN_H和CAN_L是否正确
  2. VESC ID不匹配 → 检查代码中VESC_CONTROLLER_ID是否与VESC Tool设置一致
  3. 占空比指令错误 → 旧版代码字节序错误,确保使用修正后的代码
  4. 电机未检测 → 重新用VESC Tool进行电机检测
  5. 安全限制 → 检查MAX_SAFE_DUTY是否设置过小
  6. can通信波特率不匹配

8.2 电机全速运转(无法控制)

原因 :字节序错误(小端序 vs 大端序) 解决 :使用修正后的vesc_communication.c代码(大端序发送)

8.3 VOFA收不到数据

可能原因

  1. 串口选择错误 → 检查COM口
  2. 波特率错误 → 确认为115200
  3. UART未初始化 → 检查VOFA_Init()是否调用

8.4 CAN通信无响应

排查步骤

  1. 使用逻辑分析仪或示波器检查CAN信号
  2. 确认终端电阻(120Ω)已接入
  3. 检查VESC Tool中的CAN设置
  4. 确认CAN中断是否使能

8.5 温度过高

处理措施

  1. 降低电流/占空比
  2. 检查散热器安装
  3. 检查电机负载是否过大
  4. 添加温度保护逻辑

九、代码安全保护机制

9.1 占空比限幅

vesc_motor.cVESC_Motor_SetTarget()中:

arduino 复制代码
#define MAX_SAFE_DUTY 0.05f  // 调试期间最大5%

调试完成后可修改为更大的值(最大1.0)

9.2 温度监控

建议添加温度保护逻辑:

ini 复制代码
if (motor.current_temp_fet > 80.0f || motor.current_temp_motor > 80.0f) {
    motor.enabled = 0;
    VESC_SetDuty(0);
    // 触发报警
}

9.3 启动延时

代码中已包含2秒启动延时和3次闪烁指示,避免上电瞬间误动作


十、扩展功能建议

10.1 PID闭环控制

可在vesc_motor.c中添加位置/速度PID控制器,实现精确控制

10.2 多电机控制

修改不同的VESC_CONTROLLER_ID,可同时控制多个电机

10.3 轨迹规划

结合TIM定时器,实现梯形/S型速度曲线

10.4 故障诊断

解析VESC的故障代码,实现故障自动检测和保护


十一、参考资料

  • VESC官方文档vesc-project.com/
  • VESC CAN协议 :项目中的VESC6_CAN_CommandsTelemetry.pdf
  • STM32G4参考手册:RM0440
  • FDCAN外设应用笔记:AN5348

教程完成! 按照以上步骤操作,即可实现STM32通过CAN总线控制VESC电调和无刷电机。

相关推荐
郝学胜_神的一滴3 小时前
深入理解C++完美转发失败的场景
c++
初圣魔门首席弟子4 小时前
c++中this指针使用bug
前端·c++·bug
K 旺仔小馒头4 小时前
《牛刀小试!C++ string类核心接口实战编程题集》
c++·算法
草莓熊Lotso5 小时前
《吃透 C++ vector:从基础使用到核心接口实战指南》
开发语言·c++·算法
2401_8414956412 小时前
【数据结构】红黑树的基本操作
java·数据结构·c++·python·算法·红黑树·二叉搜索树
CoderJia程序员甲13 小时前
GitHub 热榜项目 - 日榜(2025-10-01)
ai·开源·github·ai编程·github热榜
liu****13 小时前
负载均衡式的在线OJ项目编写(六)
运维·c++·负载均衡·个人开发
青草地溪水旁13 小时前
设计模式(C++)详解——迭代器模式(3)
c++·设计模式·迭代器模式
奔跑吧邓邓子14 小时前
【C++实战㊺】解锁C++代理模式:从理论到实战的深度剖析
c++·实战·代理模式