1. 认识小米CyberGear微电机与CAN通信
小米CyberGear微电机是一款高性能的智能执行器,专门为机器人、智能硬件和自动化设备设计。它内置了高精度编码器和电流传感器,支持多种控制模式,包括位置控制、速度控制和力矩控制。在实际项目中,我经常用它来构建机械臂、四足机器人和精密传动系统,效果非常不错。
这款电机最特别的地方是采用了CAN总线通信协议,而不是常见的PWM或串口通信。CAN总线有什么优势呢?简单来说,它就像是一个高效的团队沟通系统——多个设备可以共享同一条总线,相互之间不会干扰,传输距离远(最长可达1公里),而且抗干扰能力极强。我在工业现场测试过,即使周围有大功率电机干扰,CAN通信依然稳定如初。
对于STM32开发者来说,控制CyberGear电机需要掌握几个关键点:首先是CAN总线的配置,必须设置为1Mbps的波特率;其次是理解电机的扩展帧格式,这是通信的基础;最后是要熟悉各种控制模式的数据封装方式。别担心,接下来我会用实际代码和案例带你一步步掌握这些知识。
2. 硬件连接与电路设计
在实际项目中,硬件设计是第一步也是最重要的一步。我刚开始用STM32控制CyberGear电机时,就因为在电路设计上疏忽而踩过坑。STM32F103系列虽然内置了CAN控制器,但很多型号的时钟频率无法直接支持1Mbps的高速CAN通信,这就需要外接晶振。
这是我的典型硬件配置方案:
- 主控芯片:STM32F103RET6(性价比高,资源丰富)
- CAN收发器:VP230或TJA1050(都是很稳定的选择)
- 外接晶振:8MHz(确保CAN时钟精度)
- 电源模块:24V直流电源(电机额定电压)
电路设计方面,CAN总线部分需要特别注意终端电阻的配置。在1Mbps的高速通信下,总线两端必须各接一个120Ω的电阻,否则会出现信号反射导致通信失败。有一次我调试了半天才发现是因为忘记接终端电阻,这个教训很深刻。
接线时要注意:
- CAN_H和CAN_L要使用双绞线,减少电磁干扰
- 电源线要足够粗,电机峰值电流可达23A
- 最好在电源输入端加滤波电容,避免电压波动
如果你是自己设计PCB,记得把CAN收发器尽量靠近STM32的CAN引脚,走线要短而直。我推荐使用4层板设计,专门用一层作为地平面,这样能显著提高信号完整性。
3. CAN总线基础配置
配置STM32的CAN模块是控制CyberGear电机的第一步。虽然CubeMX可以自动生成初始化代码,但理解每个参数的意义很重要,这样在遇到问题时才能快速定位。
首先是时钟配置。STM32F103的APB1时钟最高是36MHz,而CAN模块需要在这个基础上分频得到1Mbps的波特率。计算公式是:波特率 = APB1时钟 / (Prescaler * (TimeSegment1 + TimeSegment2 + 1))。经过实际测试,我最常用的配置是:
- Prescaler = 4
- TimeSegment1 = 5
- TimeSegment2 = 2 这样得到的实际波特率是36MHz / (4 * (5+2+1)) = 1.125MHz,虽然略有误差但在允许范围内。
void MyCAN_Init(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
// 启用CAN时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
// CAN参数配置
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = ENABLE;
CAN_InitStructure.CAN_AWUM = ENABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_5tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
CAN_InitStructure.CAN_Prescaler = 4;
CAN_Init(CAN1, &CAN_InitStructure);
// 过滤器配置
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_Fil


4352

被折叠的 条评论
为什么被折叠?



