1.8 RM 电机初步 - 实验篇
1.8 RM 电机初步 - 实验篇
Sarzn接线
手册在我的仓库中也有 ***
CAN通信
请首先分清楚两个不同的概念: CAN ID 和电调 ID CAN ID 是大疆在手册中已经定好了的, 发送控制报文的时候, CAN ID 有两个固定的值0x200 和 0x1ff 电调 ID 是在电调是上我们手动去改的 ID
CAN通信波特率为1Mbps, 一条CAN总线上可以允许有多个电调, 其电调 ID 各不相同
单片机通过标准数据帧控制电调进而控制电机, 我们主要写的就是数据段的内容, 也就是下面表格的数据域
帧的 CAN ID 有两个 0x200 或0x1ff, 这两个是发送帧; 同样电机也会反馈他们的状态给你, 电机给你反馈的帧就是反馈帧, 它的 CAN ID 是 0x201~0x208 这个是根据电机电调 ID 来确定的, 比如电调 ID 是 1, 那么反馈帧就是 0x201, 电调 ID 是 2 反馈帧就是 0x202以此类推
0x200 分管电调 ID 为 1-4 的设备, 0x1ff 分管电调 ID 为 5-8 的设备, 具体看官网手册即可
帧的数据长度(DLC) 为 8 字节
控制电流范围 -16384016384 , 映射到电调输出的转矩电流 -20020A
核心问题是: 一个字节(8 位)最大只能装 0~255, 而控制电流值要到 16384, 一个字节根本装不下, 所以必须拆成两个字节接力装, 这就是高低位的意义
比如我要让 1 号电机输出 10A 1
2
3current = (int16_t)(10.0f / 20.0f * 16384); // = 8192
DATA[0] = current >> 8; // 高 8 位
DATA[1] = current & 0xFF; // 低 8 位
既然是 10A 就是 16384 的一半, 就是 8192, 我们从理论上走一遍装数据的流程
首先 current 被我们计算得到是 8192, 注意到他是 2^13, 那么他写成 16 位二进制就是 00100000 00000000 高亮的这一部分就是高位, 没高亮的就是低位 根据上边的表我们知道, 控制电流高 8 位放进 DATA[0], 所以我们直接向右移8 位, 把低八位挤掉
然后低八位我们直接与上一个 0xFF 即 1111 1111, 结果直接放入DATA[0]
大端 big-endian
放好之后得决定先发哪半截, 大疆协议规定高 8 位在前(DATA[0] 放高位,DATA[1] 放低位),这叫 大端序. 这不是数学要求, 只是大疆协定约定的摆放顺序
相应的, 电调也是按照第一个字节是高位的约定来读
CubeMX
根据原理图我们发现 A 板上具有 24v 供电的接口, 只要我们通过 GPIO
配置一下就好了
另外: CAN1: PD0 PD1 在 APB1 总线上 CAN2: PB12 PB13 在 APB1 总线上
这里我们就直接使用 A 板的输出 24v 供电, 就不接分电板了 并且在这个实验中, 我们只关心发送报文, 并不关心电机发送回来的数据, 所以我们会在后面写一些空的回调函数 ***
首先我们配置基本的工程项目…记得将 HSE 配置为 12MHz,
不然起振会有问题
然后我们将PH2~PH5配置为 GPIO_Output 并将其配置为推挽上拉, 以启用 24v
输出

代码
打开 Clion, 我们需要将另外的一些开源 bsp
文件(这里采用中科大视频中的代码)加入我们的编译中, 这个代码我已经改好了,
在我的仓库中
首先包含我们要用到的库 1
2
3
4/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
由于在这个实验我们不关心电机发送回来的数据,
所以我们写个空回调函数以适用这个板级支持包 1
2
3
4
5
6
7
8
9
10/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
* @brief 空回调函数
* * @param Rx_Buffer CAN接收的信息结构体
*/void NULL_Call_Back(struct Struct_CAN_Rx_Buffer *Rx_Buffer)
{
}
/* USER CODE END 0 */
main函数编写
我们要使能一个 24v 的电源输出 - LD代表 A 板 left down
位置的电源输出口, 并且使能 CAN1 1
2
3
4/* USER CODE BEGIN 2 */
BSP_Init(BSP_DC24_LD_ON);
CAN_Init(&hcan1, NULL_Call_Back);
/* USER CODE END 2 */
然后写电机转动的主逻辑, 像呼吸灯一样的转动. 将电调 ID 配置为 1, 这样我们就知道应该发送 CAN ID为 0x200
和上文讲过的一样, 我们将电流大小写到数据段上, 然后把它发出去
1 | /* Infinite loop */ |
烧录你的代码, 现在应该可以让电机转起来了!
一个小问题
如果你烧录代码之后断电, 再重新上电, 你大概率会发现电机不转了,
然后接上调试器发现他停在了这里
这个原因是 HSE 起振裕度不够, 冷上电时 12MHz 晶振从静止开始起振,没在 HAL 的超时窗口内稳住12M, HAL_RCC_OscConfig 失败就进 Error_Handler 的死循环了
解决办法是你按下 Reset 键就好了. 当你按下复位键时, 晶振已经在正常工作了, 电机就转起来了!







