1 介绍

  • MAVLink:Micro Air Vehicle Link,即微型飞行器连接通信协议,于2009年初由Lorenz Meier首次发布。
  • Mavlink协议是在串口通讯基础上的一种更高层的开源通讯协议。
  • MAVLink是一种非常轻量级的通信协议,主要用于与无人机(以及板载无人机组件之间)进行通信。

官网:https://mavlink.io/en/

2 协议格式

image.png

2.1 MAVLink V1格式

MAVLink通信内容包含常见通信协议帧头、帧尾、长度、校验等。协议格式及详情见下图:
image.png

3 环境搭建

需要下载Python、future、MAVLink、pymavlink

3.1 Python安装

官网下载地址: https://www.python.org/downloads
在cmd里输入Python返回如下就说明安装好了
H@H30BKV()}879B6WXP(TRS.png

3.2 future安装

直接在cmd输入,命令在线安装

  1. pip install future

E4CXJS6W9YVO@)4J5W)2L3Q.png

3.3 MAVlink代码生成工具包

MAVlink代码生成工具包,环境搭建完成之后,用于代码生成的一项工具包(后面文章讲述代码生成会用到这工具包)。
官网下载地址:https://github.com/mavlink/mavlink
pymavlink地址:https://github.com/ArduPilot/pymavlink
下载的pymavlink文件解压后,将其中的内容复制到MavLink文件夹下的MavLink文件中。
然后在MavLink目录下右键使用 git bash 输入

  1. python mavgenerate.py

若弹出如下界面则环境变量安装成功
![MJVU7Y0F~TLPQ2}FTL@J7W.png
若不成功就需要添加Python到环境变量中
操作:
将该路径添加到系统环境变量path中:E:\Python\Python310\Scripts(自己的Python路径)

4 XML文件定义

MAVLink的MSG消息定义在XML文件中,遵循XML语法规则,通过生成器工具(Mavenerate或Mavgen)生成MAVLink C代码;
在MAVLink协议中,每一条MSG消息都具有一个ID,且ID具有唯一性。
在xml中定义一条Message消息,通过生成器工具就能生成该Message对应的C代码

可以参考XML语法:https://www.w3school.com.cn/xml/xml_syntax.asp

4.1 MSG

在MAVLink V1版本中,消息ID有效数字的范围为0到255。
其中0到149为公共消息ID(飞控系统共有消息,一般不建议用于自定义)。而150到240为用于自定义消息的ID范围。

4.1.1 MSG的定义

以下面的代码为例

  1. <message id="41" name="MISSION_SET_CURRENT">
  2. <description>Set the mission item with sequence number seq as current item. This means that the MAV will continue to this mission item on the shortest path (not following the mission items in-between).</description>
  3. <field type="uint8_t" name="target_system">System ID</field>
  4. <field type="uint8_t" name="target_component">Component ID</field>
  5. <field type="uint16_t" name="seq">Sequence</field>
  6. </message>
  • 标签

每条消息都被定义在这样一个消息标签内。

  • id=“41”

表示此消息的id或index编号为41。

  • name=”MISSION_SET_CURRENT”

该ID编号对应的名称。

对该消息描述,是一个非常重要,但可选的领域(意思是可以不用定义),可以理解为代码的注释。

对消息的一个字段进行定义,它类似于C语言中的一个变量,可以是8,16,32和64位长度(有符号或无符号),以及浮点类型等。

  • type=“uint8_t”

将此字段定义为8位无符号整数。数组的定义如下:type=“uint8_t[5]”。可以理解为一个函数参数的数据类型。

  • name = “type”

该字段的名称,可以理解为一个函数参数的名称。

  • Type of the MAV

字段说明,可以理解为函数参数的注释。

5 生成C代码

![$9L~F]1]$VHB0YLD(GJ34S.png
在这里直接双击打开
9NW5M1%$C4ZBILTEZII9MPA.png
XML:mavlink-master/message_definitions/v1.0/common.xml

6 MAVLink移植到STM32

6.1生成 C代码

可以参考上面的步骤自己生成代码,或者直接下载官方的代码
MAVLink V1版:https://github.com/mavlink/c_library_v1
MAVLink V2版:https://github.com/mavlink/c_library_v2

6.2 将C代码添加到工程(.h文件)

  • 将生成的代码拷贝到工程文件下,
  • 将.h文件添加到工程中(方便查阅修改),
  • 在keil中添加路径,
  • 然后在main中
    #include "mavlink.h"
    

    6.3 配置(如添加MAVLink路径、修改代码适配工程)

    将拷贝的文件路径添加到keil中
    解决报错
    在mavlink_types.h中修改如下俩个地方3RV152E{Q%]DH9}JWEMXY~5.png
    代码如下:
    #pragma anon_unions
    #define MAVPACKED( __Declaration__ ) __Declaration__
    
    若还有报错,参考:https://www.cnblogs.com/daxuezhidao/p/5809709.html

    6.4 添加MAVLink发送接收(及应用)代码

    在main.c: ```c

/ 静态申明 —————————————————————————————————/ static void MAVLink_SendTest(uint8_t SysState, uint16_t BatVol);

/** 函数名称 : System_Initializes 功 能 : 系统初始化 参 数 : 无 返 回 值 : 无 */ void System_Initializes(void) { BSP_Initializes(); TIMER_Initializes(); USART_Initializes(); }

/** 函数名称 : main 功 能 : 主函数入口 参 数 : 无 返 回 值 : int */ int main(void) { uint8_t sys_state; uint16_t voltage_battery;

/ 赋值 / sys_state = SYS_RUN; //枚举变量(系统运行状态) voltage_battery = 5000; //整形变量(电压5000mV)

System_Initializes();

while(1) { LED_TOGGLE(); //LED变化 TIMDelay_Nms(500); //TIM延时

                                             //测试: 间隔500ms发送一次
MAVLink_SendTest(sys_state, voltage_battery);

} }

/** 函数名称 : MAVLink_SendTest 功 能 : MAVLink发送测试 参 数 : SysState —- 系统状态 BatVol ——- 电池电压 返 回 值 : int */ static void MAVLink_SendTest(uint8_t SysState, uint16_t BatVol) { static mavlink_message_t MAVLink_Msg; //MAVLink协议信息(MSG) uint8_t MAVLink_Buf[8 + 3]; //发送的缓存(注意大小, 3代表两个参数的长度) uint16_t MAVLink_Len; //发送的长度

                                             //打包消息(到MAVLink_msg)

MAVLink_Len = mavlink_msg_sys_info_pack(1, 1, &MAVLink_Msg, SysState, BatVol);

                                             //根据消息得到Buf和Len

MAVLink_Len = mavlink_msg_to_send_buffer(MAVLink_Buf, &MAVLink_Msg);

                                             //通过串口发送

MAV_USART_SendNByte(MAVLink_Buf, MAVLink_Len); } ``` 其中的几个看似未定义的函数是写在.h文件中的
初始化程序需要自行添加

6.5 例程

MAVLink发送接收例程.rar

7 MAVLINK实现

利用MAVLink通信协议进行编程,主要实现的功能就是:

  • 发送端

将需要发送的数据(如:SysState, BatVol),添加MAVLink通信协议,通过硬件(如:UART、CAN)发送出去。

  • 接收端

硬件(如:UART、CAN)接收到的数据,通过MAVLink协议解析,得到一帧完整的MAVLink数据包,提取发送端发送的数据(如:SysState, BatVol),将得到的数据应用到我们程序中。

7.1 主要流程:

数据 -> MAVLink封装 -> 发送 -> 接收 -> MAVLink解析 ->数据

7.2 发送和接收流程图

image.png