使用大疆M3508、M2006的CAN总线知识与配置方法


电机

前言:

两个月前的一篇文章:PID与三环控制发布以后,有不少朋友在微信上交流大疆M3508、M2006的使用问题,其中有一个方面值得单独拿出来聊一聊:CAN通信

对于很多朋友,包括我自己,使用大疆的M3508、M2006无刷直流电机和C610、C620电调是第一次接触到CAN通信。大疆的这几款产品原本设计的非常容易上手,应该几天就能熟练使用。但是由于C610、C620电调选用了CAN总线通信,给不少人带来了困扰。然而使用这几个电机并不需要把CAN通信了解的有多么深

困扰往往来自:

  • CAN总线之前用的比较少
  • 现有CAN通信资料少而且复杂

这篇文章旨在快速扫盲,给出使用M3508、M2006电机的必备CAN通信知识,希望能降低使用门槛,给各位朋友节约时间。内容均使用M3508与M2006实测过,演示视频在文章末尾。

本文仅涉及必备知识,甚至尽量避开复杂的通信原理,力求浅显易懂。

0x00 需要额外的CAN收发器!!!

这件事要放到前面去说,因为已经有几位朋友的经历指出了其必要性。

如果我们有一块STM32开发板,也有电调电机和电源。那么我们的STM32引脚与电调的CAN_H和CAN_L之间是不能直接相连的。

需要购买如下图所示的CAN收发器,作为两者连接的桥梁。一般我用的是TJA1050芯片的模块。

CAN收发器

CAN收发器是使用电机的必备硬件条件,一定要先确定自己有这个东西。至于原因,咱们接下来说明。

0x01 硬件层面分析

为什么需要CAN收发器

通过分析硬件层面我们能知道为什么需要额外的CAN收发器。请看下图:

硬件结构

从图中我们能看出,STM32拥有的外设叫做:CAN控制器,它负责CAN通信的筛选、优先级、仲裁等问题。相当于咱们的邮局,帮忙盖个邮戳,分分类。通过复用GPIO以后,它延伸出两个引脚:CAN_RXCAN_TX,类比串口我们知道一个负责收一个负责发。

实际上,这两个引脚上传输的数据已经是CAN报文了,该有的格式它都有,STM32的CAN回环模式就相当于直接把CAN_RXCAN_TX相连,就可以收到自己发的消息。

问题是,CAN在设计的时候为了消除共模干扰,特地选用了差分信号(也叫差模信号)传输。咱们的C610、C620电调,接收发送的就是差分信号。这才是CAN收发器的作用:

把来自STM32的信号转换成差分信号让电调听得懂,把来自电调的差分信号转换成STM32听得懂的信号。


请注意:

连接CAN_RXCAN_TX引脚与CAN收发器的引脚时,并不需要像串口一样交叉。直接将RX连接到标有RX的引脚,TX类似。


120Ω的终端电阻呢?

不知道朋友们有没有注意到C610、C620电调上都有一个开关,C620的在侧面,旁边写着CAN RESISTOR,这也是CAN总线的设计要求。

根据咱们学的《电路理论》这门课,当信号波长小于电路尺寸的时候,我们就不能把电路当成集中电路来分析。对于can总线是一样的,由于电调采用1MHz的通信频率,为了防止一些不必要的干扰,我们需要在CAN总线的两端分别用120Ω电阻跨接起来。比如之前图中的两端可以认为是咱们的CAN收发器是一端,下面的电调是另一端。

对于只有一个电调的情况下,可以打开电调上的电阻,然后直接和CAN收发器连接,这样虽然少了一端的终端电阻,但实际上可以运行。如果同时控制两个及以上的电调,那就可以打开其中两个的终端电阻,构成总线的两端。当然也可以手动组成如下图的总线结构并且关闭电调上的终端电阻,图中还加入了电容进行滤波。

CAN总线图

0x02 软件配置简析

其实,看完硬件部分就已经可以正常使用电调电机了,因为大疆官方例程中已经把CAN通信配置好了,直接可以使用。

但是如果涉及非常多的设备同时控制,比如超过四个电机的情况下,或者还有其他的外设要通过CAN总线相连,简单了解软件配置也是很有好处。

而且,我发现很多朋友是在做RoboMaster比赛,全面的了解软硬件还是十分必要的,如果出现问题也有利于排查,不至于浪费大量时间。

接下来我们还是使用咱们的老朋友:大疆官方M2006例程M3508例程来作为样本。主要探究以下问题:

  • 通信频率如何设定为1MHz
  • CAN过滤器的配置
  • 报文的接收与发送

两个文件:bsp_can.ccan.c

如何把通信频率设定为1MHz?

以下是文件can.c中截取的代码(有删改):

CAN_HandleTypeDef hcan1;

/* CAN1 init function */
void MX_CAN1_Init(void)
{

  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 3;//分频系数设置为3
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SJW = CAN_SJW_1TQ;
    
 // =================请看这里
版权声明:本文为huxiaoan原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/huxiaoan/p/15046967.html