【RM】VGD25超电CAN通信文档
Version:1.0
对应软硬件:25超电硬件V0.3,软件V2.7
该文档写于25/01,现经过小修改小完善,发布于博客上,方便查阅和实时更新。
一 基本逻辑
1.1 电路原理

增加了超级电容的底盘电路可以理解成上面的三端网络,由电管、底盘、电容三个端口组成,由基尔霍夫定律可知,电管功率等于底盘功率与电容功率之和;这个关系对于电容放电也是成立的,此时图中电容功率为负,底盘功率比电管功率大。
1.2 控制实现

超电发送的数据有底盘当前功率和电容目标功率。底盘当前功率是底盘电机消耗的功率,作为底盘主控那边的功率检测输入使用(25赛季开始要求裁判系统不给底盘功率数据,必须超电模块检测),电容目标功率就是底盘主控发送过来更新的功率,指的是电容充/放电的功率,用于检验超电这边确实更新了。超电模块状态目前只是个雏形,后面完善(咕咕咕)。电容电压指的是电容组当前剩余的电压,也就是指示电容组剩余能量。
关于当前功率-缓冲能量-限制功率之间关系的计算,有学校在超电主控上完成也有在底盘主控上完成,因为咱们底盘已经有功率控制代码了,设定为底盘那边计算,给超电只需要发送一个超电需要吸收/供给的目标功率即可。这里的基本逻辑是用电管允许的功率减去底盘实际消耗的能量(由上面的三端网络图可知),得到剩余的功率就是允许超电此时趁机吸收的能量;反之如果相减的值为负值,也就是说底盘消耗的功率比电管允许功率大,那么超电往外辅助放电,保证电管功率不超过限额。
二 数据格式
2.1 CAN通信配置
波特率: 1MBit/s
超电使用CAN ID: 0x211
底盘主控请使用CAN ID: 0x210
发送频率: 其使用的定时器中断频率是193Hz,实际发送没有测过,这个方便调节的.
2.2 超电发送数据格式
发送的数据需要使用四个元素的uint16_t数组接收;但CAN通信是以一个字节(即8位)为单位发送数据的,因此一般来说CAN发送函数会要求你的发送数据数组只能放uint8_t类型,。那么有下面两种解决方案。
底盘主控接收代码示例(使用强制类型转换)
对uint16_t数组直接进行强制类型转换,四个元素的uint16_t转换过来就是八个元素的uint8_t,然后按照正常的长度为8的CAN数据发送即可。
1 | |
在代码中的实际使用:

底盘主控接收代码示例(使用低位在前逻辑)
这里的强制类型转换在效果上与低位在前的数据存储方式是一样的,C620电机是高位在前,与此相反;电控直接把读取C620的代码复制过来,把两个uint8_t变量的顺序倒换过来,变成低位在前,是一样的效果,全向用的就是这个方式读取,总之两种接收方式,二选一即可,效果都一样。
1 | |
建议按照示例代码,这样代码风格统一。
接收效果大概像这样(数值仅供示意,重点是这里是四个uint16_t类型数据):

内容
CAN报文的四个元素按顺序分别为:
- 底盘当前功率
- 目标设定功率
- 电管当前功率
- 电容电压
下面是数据的详细解析。
底盘当前功率
即上面电路原理中的Pchassis.
因为使用的都是uint16_t类型的元素,所以不能直接表示浮点数和负数。超电主控把数据如下处理:
其中x,y分别是原数据和发送数据,为了表示一位小数把x乘10,为了表示负数把它的零点”居中“在十六进制0x0000到0xFFFF的一半,即0x7FFF。
底盘主控接收到数据y之后,应对其反变换:
即可获得原始发送数据x,即带正负,保留一位小数的底盘功率(注意及时转换成float以免丢失)
电容目标功率
即上面电路原理中Pcap的目标值。
同底盘功率进行相同的从x到y的变换。
电管当前功率
即上面电路原理中的Preferee.
同底盘功率进行相同的从x到y的变换。
电容电压
即电容组电压,反映超级电容组剩余电量
使用的变换为
类似地,乘以100是为了保留两位小数。
底盘主控在接收到数据y之后,应对其作反变换:
以获得原始数据x。(注意及时转换为float类型)
超电状态(该数据暂不启用 暂不发送)
这里用状态码的思路进行表示超电状态。(未成熟,暂不启用和发送给底盘主控)
| 数值 | 状态 | 具体意思 |
|---|---|---|
| 0xFFFF | 未初始化 | 此为超电状态码初始值,没有变成别的说明还没初始化跑起来 |
| 0x0001 | 正常充电 | 超电状态正常且电容组正在充电(功率>0) |
| 0x0002 | 正常放电 | 超电状态正常且电容组正在放电(功率<0) |
| 0x0003 | 正常待机 | 超电状态正常且电容组不参与底盘工作(不上电容状态) |
| 0x0005 | 过压过流过充过放 保护 |
电压或电流过大,或者超电充满了或者耗尽了,自动停机 |
| 0x0009 | 高温保护 | 超电上有测温用的NTC,后面做高温保护 |
可能还有别的状态,我还没想好(
总之我设计的可能花样多一点,底盘那边看需要就用。
对数据进行反变换的代码示例
在使用上面那个示例代码进行数据接收后,需要对四个(实际上是三个)数据进行反变换,得到浮点数.
1 | |
2.3 超电接收数据格式
内容
底盘发送数据按顺序依次为:
- 电容目标功率
- 未定
- 未定
- 未定
电容目标功率
即给超电模块发送超电要充电的目标功率(负值即为放电),发送过来后超电由此值进行更新自己的电容目标功率,为了避免超电模块PID的超调/过冲导致进入保护,甚至烧坏板子(亲身经历),请不要使得您发送的目标功率变化过大,瞬态变化不要超过50W。
对数据进行变换的代码示例
有具体要发送的数据之后,这里操作的顺序和上面接收的顺序(接收->反变换)相反,先变换后转化为uint8_t进行CAN通信发送。
下面是进行变换的示例代码:
1 | |
底盘主控发送代码示例(使用低位在前逻辑)
由底盘主控发送、超电主控接收的数据,采用和上面所讲述的一样的数据格式,也就是四个uint16_t元素组成的数组,然后以强制类型转换或者低位在前逻辑转化为CAN实际发送使用的uint8_t类型元素进行数据传输。这里仅展示后者。
这里沿用上面的Cap_Send_Data结构体,进行发送。
1 | |
Version 1.0
写于25/09/19
