一:准備材料: mavlink源碼 stm32串口程序
1.mavlink源碼:
b.下拉到MAVLink Code and Generator點擊MAVLink Generator (C/C++, Python)下載源碼生成器
c.解壓縮下載的文件,點擊mavgenerate.py這個文件(前提是已經安裝好了python軟件)
d.xml是生成的源文件,out是生成的目錄 langguage是生成的代碼語言。
xml:mavlink-master/message_definitions/v1.0/common.xml
out:D:/Backup/桌面/mav
langguage:C
protocol:1.0
點擊generate就能生成相應的文件到out目錄里去
2.stm32串口代碼選用正點原子的串口代碼,將生成的文件新建一個MAVLINK文件夾添加到工程里去(添加文件,添加頭文件)
其中manlink_avoid_errors.h是我自己添加的用來解決報錯的文件,盡量將更改添加到這個文件,方便以后移植
二:准備移植
將准備好的工程編譯,會出現一堆錯誤("..\OBJ\USART.axf" - 30 Error(s), 17 Warning(s).),別急,一個一個解決就好了
錯誤1:..\MAVLINK\common\../mavlink_types.h(53): error: #20: identifier "pack" is undefined
解決方法:這個錯誤是因為對齊方式的原因,因為gun編譯跟mdk有些差異,具體我沒有深究。
屏蔽mavlink_types.h中的如下代碼
// Macro to define packed structures//#ifdef __GNUC__// #define MAVPACKED( __Declaration__ ) __Declaration__ __attribute__((packed))//#else// #define MAVPACKED( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )//#endif
在 mavlink_avoid_errors.h中加入如下代碼(意思就是讓MAVPACKED不起任何作用)
#define MAVPACKED( __Declaration__ ) __Declaration__
編譯后:"..\OBJ\USART.axf" - 30 Error(s), 7 Warning(s).
錯誤2:..\MAVLINK\common\../mavlink_types.h(53): error: #3092: anonymous unions are only supported in --gnu mode, or when enabled with #pragma anon_unions
解決方法:根據錯誤提示在
mavlink_avoid_errors.h中添加如下代碼
#pragma anon_unions
編譯后:"..\OBJ\USART.axf" - 30 Error(s), 8 Warning(s).
錯誤3:..\MAVLINK\common\../checksum.h(34): warning: #260-D: explicit type is missing ("int" assumed)
解決方法:
包括后面很多錯誤都有共同點,指向有inline的行,這里是因為mdk中無法識別inline,重新定義inline就好
在
mavlink_avoid_errors.h中加入如下代碼(因為mdk認識__INLINE)
#defineinline __INLINE
編譯后:"..\OBJ\USART.axf" - 4 Error(s), 195 Warning(s).
錯誤4:..\MAVLINK\common\../mavlink_conversions.h(167): error: #268: declaration may not appear after executable statement in block
解決方法:這個錯誤是因為將參數定義到了函數后面了。
更改mavlink_conversions.h中的代碼為
MAVLINK_HELPER void mavlink_dcm_to_quaternion(constfloat dcm[3][3],float quaternion[4]){int dcm_j,dcm_k;float s;float tr = dcm[0][0]+ dcm[1][1]+ dcm[2][2];if(tr >0.0f){float s = sqrtf(tr +1.0f);quaternion[0]= s *0.5f;s =0.5f/ s;quaternion[1]=(dcm[2][1]- dcm[1][2])* s;quaternion[2]=(dcm[0][2]- dcm[2][0])* s;quaternion[3]=(dcm[1][0]- dcm[0][1])* s;}else{/* Find maximum diagonal element in dcm* store index in dcm_i */int dcm_i =0;int i;for(i =1; i <3; i++){if(dcm[i][i]> dcm[dcm_i][dcm_i]){dcm_i = i;}}dcm_j =(dcm_i +1)%3;dcm_k =(dcm_i +2)%3;s = sqrtf((dcm[dcm_i][dcm_i]- dcm[dcm_j][dcm_j]-dcm[dcm_k][dcm_k])+1.0f);quaternion[dcm_i +1]= s *0.5f;s =0.5f/ s;quaternion[dcm_j +1]=(dcm[dcm_i][dcm_j]+ dcm[dcm_j][dcm_i])* s;quaternion[dcm_k +1]=(dcm[dcm_k][dcm_i]+ dcm[dcm_i][dcm_k])* s;quaternion[0]=(dcm[dcm_k][dcm_j]- dcm[dcm_j][dcm_k])* s;}}
更改mavlink_helpers.h中的代碼為
MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t*buffer,constmavlink_message_t*msg){uint8_t*ck;memcpy(buffer,(constuint8_t*)&msg->magic, MAVLINK_NUM_HEADER_BYTES +(uint16_t)msg->len);ck = buffer +(MAVLINK_NUM_HEADER_BYTES +(uint16_t)msg->len);ck[0]=(uint8_t)(msg->checksum &0xFF);ck[1]=(uint8_t)(msg->checksum >>8);return MAVLINK_NUM_NON_PAYLOAD_BYTES +(uint16_t)msg->len;}
編譯后:"..\OBJ\USART.axf" - 0 Error(s), 195 Warning(s).
警告:..\MAVLINK\common\./mavlink_msg_heartbeat.h(261): warning: #191-D: type qualifier is meaningless on cast type
解決方法:按照提示跟蹤錯誤到protocol.h,
更改
protocol.h的代碼為(就是去掉了const)
#define_MAV_RETURN_int8_t(msg, wire_offset)(int8_t)_MAV_PAYLOAD(msg)[wire_offset]#define_MAV_RETURN_uint8_t(msg, wire_offset)(uint8_t)_MAV_PAYLOAD(msg)[wire_offset]
編譯后:"..\OBJ\USART.axf" - 0 Error(s), 0 Warning(s).
到此不代表移植好了,上面是本人邊移植邊寫的教程,如下給大家做一個總結。可能很多東西跟上面重復的,如果大家想盡快的移植好可以參考下面的,如果你想了解為什么這么移植請參考上 面的移植過程。
三:不需要懂過程的快速移植,只需做好這幾步就能快速移植了
1.准備好工程變添加好生成的mavlink純凈文件(未經任何修改的文件)
2.添加我寫好的mavlink_avoid_errors.h文件,代碼如下
/** @file mavlink_avoid_errors.h* @簡介:本文件是由624668529添加,用來統一解決mavlink報錯信息* @see QQ624668529*/#ifndef MAVLINK_AVOID_ERRORS_H#define MAVLINK_AVOID_ERRORS_H/*解決..\MAVLINK\common\../mavlink_types.h(53): error: #20: identifier "pack" is undefined*/#define MAVPACKED( __Declaration__ ) __Declaration__/*解決..\MAVLINK\common\../mavlink_types.h(53): error: #3092: anonymous unions are only supported in --gnu mode, or when enabled with #pragma anon_unions*/#pragma anon_unions#defineinline __INLINE#ifndef memset//由624668529添加 2018-08-24staticinlinevoid*memset(void*dest,int data,size_t length){uint32_t i;int*point = dest;for(i=0; i<length; i++) point[i]= data;return dest;}#endif#ifndef memcpy//由624668529添加 2018-08-24void*memcpy(void*dest,constvoid*src,size_t n){unsignedchar*pout =(unsignedchar*)dest;unsignedchar*pin =(unsignedchar*)src;while(n-->0)*pout++=*pin++;return dest;}#include"mavlink_types.h"#define MAVLINK_USE_CONVENIENCE_FUNCTIONS#define MAVLINK_SEPARATE_HELPERS//mavlink_system_t mavlink_system = {0,0};mavlink_system_t mavlink_system ={1,1};// System ID, 1-255, Component/Subsystem ID, 1-255void comm_send_ch(mavlink_channel_t chan,uint8_t buf){chan=chan;USART_SendData(USART1, buf);//向串口1發送數據while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待發送結束}#endif#include"mavlink.h"#include"mavlink_helpers.h"#endif//AVLINK_AVOID_ERRORS_H
3.在main.c中更改成如下代碼
#include"sys.h"#include"delay.h"#include"usart.h"#include"led.h"#include"beep.h"#include"key.h"#include"mavlink_avoid_errors.h"//ALIENTEK 探索者STM32F407開發板 實驗4//串口通信實驗 -庫函數版本//技術支持:www.openedv.com//淘寶店鋪:http://eboard.taobao.com//廣州市星翼電子科技有限公司//作者:正點原子 @ALIENTEKint main(void){mavlink_heartbeat_t packet_in ={963497464,17,84,151,218,3};mavlink_heartbeat_t packet1;memset(&packet1,0,sizeof(packet1));packet1.custom_mode = packet_in.custom_mode;packet1.type = packet_in.type;packet1.autopilot = packet_in.autopilot;packet1.base_mode = packet_in.base_mode;packet1.system_status = packet_in.system_status;packet1.mavlink_version = packet_in.mavlink_version;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置系統中斷優先級分組2delay_init(168);//延時初始化uart_init(115200);//串口初始化波特率為115200LED_Init();//初始化與LED連接的硬件接口while(1){mavlink_msg_heartbeat_send(MAVLINK_COMM_1 , packet1.type , packet1.autopilot , packet1.base_mode , packet1.custom_mode , packet1.system_status );delay_ms(1000);}}
4將mavlink_conversions.h更改這一部分代碼為
MAVLINK_HELPER void mavlink_dcm_to_quaternion(constfloat dcm[3][3],float quaternion[4]){int dcm_j,dcm_k;float s;float tr = dcm[0][0]+ dcm[1][1]+ dcm[2][2];if(tr >0.0f){float s = sqrtf(tr +1.0f);quaternion[0]= s *0.5f;s =0.5f/ s;quaternion[1]=(dcm[2][1]- dcm[1][2])* s;quaternion[2]=(dcm[0][2]- dcm[2][0])* s;quaternion[3]=(dcm[1][0]- dcm[0][1])* s;}else{/* Find maximum diagonal element in dcm* store index in dcm_i */int dcm_i =0;int i;for(i =1; i <3; i++){if(dcm[i][i]> dcm[dcm_i][dcm_i]){dcm_i = i;}}dcm_j =(dcm_i +1)%3;dcm_k =(dcm_i +2)%3;s = sqrtf((dcm[dcm_i][dcm_i]- dcm[dcm_j][dcm_j]-dcm[dcm_k][dcm_k])+1.0f);quaternion[dcm_i +1]= s *0.5f;s =0.5f/ s;quaternion[dcm_j +1]=(dcm[dcm_i][dcm_j]+ dcm[dcm_j][dcm_i])* s;quaternion[dcm_k +1]=(dcm[dcm_k][dcm_i]+ dcm[dcm_i][dcm_k])* s;quaternion[0]=(dcm[dcm_k][dcm_j]- dcm[dcm_j][dcm_k])* s;}}
5.將mavlink_helpers.h中更改這一部分代碼為
MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t*buffer,constmavlink_message_t*msg){uint8_t*ck;memcpy(buffer,(constuint8_t*)&msg->magic, MAVLINK_NUM_HEADER_BYTES +(uint16_t)msg->len);ck = buffer +(MAVLINK_NUM_HEADER_BYTES +(uint16_t)msg->len);ck[0]=(uint8_t)(msg->checksum &0xFF);ck[1]=(uint8_t)(msg->checksum >>8);return MAVLINK_NUM_NON_PAYLOAD_BYTES +(uint16_t)msg->len;}
6.屏蔽mavlink_types.h中這一部分代碼
// Macro to define packed structures//#ifdef __GNUC__// #define MAVPACKED( __Declaration__ ) __Declaration__ __attribute__((packed))//#else// #define MAVPACKED( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )//#endif
7.更改protocol.h中的代碼為(即去掉const)解決警告的方法
#define_MAV_RETURN_int8_t(msg, wire_offset)(int8_t)_MAV_PAYLOAD(msg)[wire_offset]#define_MAV_RETURN_uint8_t(msg, wire_offset)(uint8_t)_MAV_PAYLOAD(msg)[wire_offset]
編譯后:"..\OBJ\USART.axf" - 0 Error(s), 0 Warning(s).
四:下載到開發板打開串口調試助手
成功接收到數據,如圖,表示移植成功
移植成功。
作者:恆久力行 QQ:624668529
本次進添加了串口發送函數,以后若有需要我會繼續添加串口接收函數。
分享教程,只希望中國的科學技術突飛猛進過,望早日超越其他國家。加油中國人
