版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、解析MWC的串口通讯一使用的软件 二使用的MWC定义串口协议文件updated 04 JulyMultiwii serial protocol was redesigned: to be light, as before to be generic: it can be used transparenlty by a GUI, OSD, telemetry or home made config tool.ie no more specific OSD code should be coded in multiwii to be bit wire efficient: only request
2、ed data are transmitted in a binary format to be quite secure: data are sent with a checksum, preventing corrupted configuration to be injected. to be header sensitive: as it is designed with a specific header, it can be mixed with other frame, like GPS frameie, it will be possible to connect either
3、 a GUI or a GPS on the same serial port without changing the conf to be less sensitive to evolutions:ie in case of parameter evolution, the main protocol will remain compatible and the GUI will be much less version dependent.variable data length allows to consider only the beginning of a message, le
4、aving the other octets at the end to extend transparently the message (for instance to add a new PID)I thought first about an implementation of Mavlink, but I think its not what I was looking for.Even with a partial implementation, the predefined structures are not light enough for what I have in mi
5、nd.Some messages are however inspired from mavlink structure.The main rule remains: Multiwii never sends something on its own.A request must be done in each case to retrieve or set data.Each messages received are acknowledged even if there is no data inside.There are 2 main messages to consider:requ
6、est message to multiwiimultiwii output messagerequest message to multiwiiTo request simple data without parameters / send a specific command / inject new parameters in multiwiimessages are formated like this:$Mdata lengthcodedatachecksum1 octet $1 octet M1 octet data lengthcodedatachecksum1 octet $1
7、 octet M1 octet 1 octet data length1 octet codeseveral octets data1 octet checksumif the message is unknown:$M|0codechecksum1 octet $1 octet M1 octet |1 octet 01 octet unknown code1 octet checksum三、对写入MWC的原文件分析void serialCom() / MWC通过c = SerialRead(CURRENTPORT);解析缓冲区的数据 uint8_t c,n; static uint8_t o
8、ffsetUART_NUMBER; static uint8_t dataSizeUART_NUMBER; static enum _serial_state /串口的几种状态 IDLE, /空闲? HEADER_START, /数据头 开始 $ HEADER_M, /数据头 M HEADER_ARROW, /数据 箭头 HEADER_SIZE, /数据尺寸 HEADER_CMD, /指令 c_stateUART_NUMBER;/ = IDLE;/状态数组 默认 空闲 for(n=0;n 1) #define SPEK_COND & (SPEK_SERIAL_PORT != CURRENTPO
9、RT) #endif while (SerialAvailable(CURRENTPORT) GPS_COND SPEK_COND) /while循环 uint8_t bytesTXBuff = (uint8_t)(serialHeadTXCURRENTPORT-serialTailTXCURRENTPORT)%TX_BUFFER_SIZE; / indicates the number of occupied bytes in TX buffer 发送缓冲区占用字节标定。 if (bytesTXBuff TX_BUFFER_SIZE - 50 ) return; / ensure there
10、 is enough free TX buffer to go further (50 bytes margin) 确保发送缓冲区之手50字节的余量。 c = SerialRead(CURRENTPORT); /读串口缓冲区serialBufferRX数据指针串口端口号,该缓冲区的数据是由串口接收中断函数inline store_uart_in_buf(uint8_t data, uint8_t portnum)获取的来自电脑的数据。 if (c_stateCURRENTPORT = IDLE) /这是一组完整指令代码 24 4D 3C 00 64 64 $M#0dd /串口状态空闲 等待HE
11、ADER_START状态的到来。 c_stateCURRENTPORT = (c=$) ? HEADER_START : IDLE;/判定是$字符吗?是进入HEADER_START状态。 if (c_stateCURRENTPORT = IDLE) evaluateOtherData(c); / evaluate all other incoming serial data else if (c_stateCURRENTPORT = HEADER_START) c_stateCURRENTPORT = (c=M) ? HEADER_M : IDLE; else if (c_stateCURRE
12、NTPORT = HEADER_M) c_stateCURRENTPORT = (c=) ? HEADER_ARROW : IDLE;/是字符 INBUF_SIZE) / now we are expecting the payload size 我们期望足够的数据占用缓冲区。 c_stateCURRENTPORT = IDLE;/数据位置不够 退出循环。 continue; /不执行该while循环包含的后面的语句,跳出开始下一轮循环。 dataSizeCURRENTPORT = c;/缓冲区够,将收到的数据赋值给当前端口的数据尺寸数组dataSize串口端口号。 offsetCURRENT
13、PORT = 0;/设置数据指针的偏移位0。 checksumCURRENTPORT = 0;/初始化数据的校验和为0。存入数组中。 indRXCURRENTPORT = 0;/ checksumCURRENTPORT = c;/说明数据长度是校验的第一个字母。 c_stateCURRENTPORT = HEADER_SIZE; / the command is to follow/MWC收到数据长度,后面就是电脑发送的数据了。MWC串口状态进入HWADER_SIZE。 else if (c_stateCURRENTPORT = HEADER_SIZE) /MWC串口是在HEADER_SIZE
14、状态吗? cmdMSPCURRENTPORT = c;/在HEADER_SIZE状态收到的第一个数据是指令。 checksumCURRENTPORT = c;/将该数据异或进入校验和的数组中去。 c_stateCURRENTPORT = HEADER_CMD;/MWC收到数据后,说明在指令状态,MWC进入HEAFER_CMD状态。 else if (c_stateCURRENTPORT = HEADER_CMD & offsetCURRENTPORT = dataSizeCURRENTPORT) /判定偏移指针大于等于数据预留位置大小吗? if (checksumCURRENTPORT = c
15、) / compare calculated and transferred checksum /偏移指针大于等于数据预留位置大小,就将从电脑这次收到的数据作为校验和,与已经累计异或的checksum中的校验和数据对比,为真,表示,该数据包是有效的,可以调用下面的函数evaluateCommand()进行,数据包的解析。 evaluateCommand(); / we got a valid packet, evaluate it我们获得了一个有效的数据包,解析评估这些数据。 c_stateCURRENTPORT = IDLE;/MWC串口开始进入空闲状态。 /while循环 /for循环四、
16、对MWC的配置文件的原文件分析 if (time-time2)40 & ! toggleRead & ! toggleWrite) /不按读写按钮发送的78个数据 time2=time; int requests = MSP_IDENT, MSP_MOTOR_PINS, MSP_STATUS, MSP_RAW_IMU, MSP_SERVO, MSP_MOTOR, MSP_RC, MSP_RAW_GPS, MSP_COMP_GPS, MSP_ALTITUDE, MSP_BAT, MSP_DEBUGMSG, MSP_DEBUG;/100=d 115=s 102=f 103=g 104=h 105=
17、I 106=j 107=k 109=m 110=n 253 254 sendRequestMSP(requestMSP(requests); if (time-time3)20 & ! toggleRead & ! toggleWrite) sendRequestMSP(requestMSP(MSP_ATTITUDE);/108=l time3=time; if (toggleReset) toggleReset=false; toggleRead=true; sendRequestMSP(requestMSP(MSP_RESET_CONF);/MSP_RESET_COF=208 if (to
18、ggleRead) /只要按读按钮 就发送下面的代码36个 toggleRead=false; int requests = MSP_BOXNAMES, MSP_PIDNAMES, MSP_RC_TUNING, MSP_PID, MSP_BOX, MSP_MISC ;/116=t 117=u 111=o 112=p 113=q 114=r sendRequestMSP(requestMSP(requests); buttonWRITE.setColorBackground(green_); if (toggleCalibAcc) toggleCalibAcc=false; sendReques
19、tMSP(requestMSP(MSP_ACC_CALIBRATION); if (toggleCalibMag) toggleCalibMag=false; sendRequestMSP(requestMSP(MSP_MAG_CALIBRATION); if (toggleWrite) toggleWrite=false; / MSP_SET_RC_TUNING payload = new ArrayList(); payload.add(char( round(confRC_RATE.value()*100) ); payload.add(char( round(confRC_EXPO.v
20、alue()*100) ); payload.add(char( round(rollPitchRate.value()*100) ); payload.add(char( round(yawRate.value()*100) ); payload.add(char( round(dynamic_THR_PID.value()*100) ); payload.add(char( round(throttle_MID.value()*100) ); payload.add(char( round(throttle_EXPO.value()*100) ); sendRequestMSP(reque
21、stMSP(MSP_SET_RC_TUNING,payload.toArray( new Characterpayload.size() ); / MSP_SET_PID payload = new ArrayList(); for(i=0;iPIDITEMS;i+) bytePi = (round(confPi.value()*10); byteIi = (round(confIi.value()*1000); byteDi = (round(confDi.value(); .五、MWC处理指令的代码分析 void evaluateCommand() switch(cmdMSPCURRENT
22、PORT) case MSP_SET_RAW_RC: for(uint8_t i=0;i8;i+) rcDatai = read16(); headSerialReply(0); break; #if GPS case MSP_SET_RAW_GPS: f.GPS_FIX = read8(); GPS_numSat = read8(); GPS_coordLAT = read32(); GPS_coordLON = read32(); GPS_altitude = read16(); GPS_speed = read16(); GPS_update |= 2; / New data signa
23、lisation to GPS functions headSerialReply(0); break; #endif case MSP_SET_PID: for(uint8_t i=0;i#0#0MSP_SET_PID” break; case MSP_SET_BOX: for(uint8_t i=0;iCHECKBOXITEMS;i+) conf.activatei=read16(); headSerialReply(0); break; case MSP_SET_RC_TUNING: conf.rcRate8 = read8(); conf.rcExpo8 = read8(); conf
24、.rollPitchRate = read8(); conf.yawRate = read8(); conf.dynThrPID = read8(); conf.thrMid8 = read8(); conf.thrExpo8 = read8(); headSerialReply(0); break; case MSP_SET_MISC: #if defined(POWERMETER) conf.powerTrigger1 = read16() / PLEVELSCALE; #endif headSerialReply(0); break; case MSP_IDENT: headSerial
25、Reply(7); serialize8(VERSION); / multiwii version serialize8(MULTITYPE); / type of multicopter serialize8(MSP_VERSION); / MultiWii Serial Protocol Version serialize32(0); / capability break; case MSP_STATUS: headSerialReply(10); serialize16(cycleTime); serialize16(i2c_errors_count); serialize16(ACC|
26、BARO1|MAG2|GPS3|SONAR4); serialize32( #if ACC f.ANGLE_MODEBOXANGLE| f.HORIZON_MODEBOXHORIZON| #endif #if BARO & (!defined(SUPPRESS_BARO_ALTHOLD) f.BARO_MODEBOXBARO| #endif #if MAG f.MAG_MODEBOXMAG|f.HEADFREE_MODEBOXHEADFREE|rcOptionsBOXHEADADJBOXHEADADJ| #endif #if defined(SERVO_TILT) | defined(GIMB
27、AL) rcOptionsBOXCAMSTABBOXCAMSTAB| #endif #if defined(CAMTRIG) rcOptionsBOXCAMTRIGBOXCAMTRIG| #endif #if GPS f.GPS_HOME_MODEBOXGPSHOME|f.GPS_HOLD_MODEBOXGPSHOLD| #endif #if defined(FIXEDWING) | defined(HELICOPTER) | defined(INFLIGHT_ACC_CALIBRATION) f.PASSTHRU_MODEBOXPASSTHRU| #endif #if defined(BUZ
28、ZER) rcOptionsBOXBEEPERONBOXBEEPERON| #endif #if defined(LED_FLASHER) rcOptionsBOXLEDMAXBOXLEDMAX| #endif #if defined(LANDING_LIGHTS_DDR) rcOptionsBOXLLIGHTSBOXLLIGHTS | #endif f.ARMEDBOXARM); break; case MSP_RAW_IMU: headSerialReply(18); for(uint8_t i=0;i3;i+) serialize16(accSmoothi); for(uint8_t i
29、=0;i3;i+) serialize16(gyroDatai); for(uint8_t i=0;i3;i+) serialize16(magADCi); break; case MSP_SERVO: headSerialReply(16);/发送数据头 包括数据长度 指令码 初始化校验和 for(uint8_t i=0;i8;i+) #if defined(SERVO) serialize16(servoi); #else serialize16(0); #endif break; case MSP_MOTOR: headSerialReply(16); for(uint8_t i=0;i
30、8;i+) serialize16( (i NUMBER_MOTOR) ? motori : 0 ); break; case MSP_RC: headSerialReply(16); for(uint8_t i=0;i8;i+) serialize16(rcDatai); break; #if GPS case MSP_RAW_GPS: headSerialReply(14); serialize8(f.GPS_FIX); serialize8(GPS_numSat); serialize32(GPS_coordLAT); serialize32(GPS_coordLON); seriali
31、ze16(GPS_altitude); serialize16(GPS_speed); break; case MSP_COMP_GPS: headSerialReply(5); serialize16(GPS_distanceToHome); serialize16(GPS_directionToHome); serialize8(GPS_update & 1); break; #endif case MSP_ATTITUDE: headSerialReply(8); for(uint8_t i=0;i2;i+) serialize16(anglei); serialize16(headin
32、g); serialize16(headFreeModeHold); break; case MSP_ALTITUDE: headSerialReply(4); serialize32(EstAlt); break; case MSP_BAT: headSerialReply(3); serialize8(vbat); serialize16(intPowerMeterSum); break; case MSP_RC_TUNING: headSerialReply(7); serialize8(conf.rcRate8); serialize8(conf.rcExpo8); serialize
33、8(conf.rollPitchRate); serialize8(conf.yawRate); serialize8(conf.dynThrPID); serialize8(conf.thrMid8); serialize8(conf.thrExpo8); break; case MSP_PID: headSerialReply(3*PIDITEMS); for(uint8_t i=0;iPIDITEMS;i+) serialize8(conf.P8i); serialize8(conf.I8i); serialize8(conf.D8i); break; case MSP_BOX: hea
34、dSerialReply(2*CHECKBOXITEMS); for(uint8_t i=0;iCHECKBOXITEMS;i+) serialize16(conf.activatei); break; case MSP_BOXNAMES: headSerialReply(strlen_P(boxnames); serializeNames(boxnames); break; case MSP_PIDNAMES: headSerialReply(strlen_P(pidnames); serializeNames(pidnames); break; case MSP_MISC: headSer
35、ialReply(2); serialize16(intPowerTrigger1); break; case MSP_MOTOR_PINS: headSerialReply(8); for(uint8_t i=0;i8;i+) serialize8(PWM_PINi); break; #if defined(USE_MSP_WP) case MSP_WP: uint8_t wp_no = read8(); /get the wp number headSerialReply(12); if (wp_no = 0) serialize8(0); /wp0 serialize32(GPS_hom
36、eLAT); serialize32(GPS_homeLON); serialize16(0); /altitude will come here serialize8(0); /nav flag will come here else if (wp_no = 16) serialize8(16); /wp16 serialize32(GPS_holdLAT); serialize32(GPS_holdLON); serialize16(0); /altitude will come here serialize8(0); /nav flag will come here break; #en
37、dif case MSP_RESET_CONF: if(!f.ARMED) conf.checkNewConf+; checkFirstTime(); headSerialReply(0); break; case MSP_ACC_CALIBRATION: if(!f.ARMED) calibratingA=400; headSerialReply(0); break; case MSP_MAG_CALIBRATION: if(!f.ARMED) f.CALIBRATE_MAG = 1; headSerialReply(0); break; case MSP_EEPROM_WRITE: wri
38、teParams(0); headSerialReply(0); break; case MSP_DEBUG: headSerialReply(8); for(uint8_t i=0;i 16) size = 16; headSerialReply(size); debugmsg_serialize(size); break; #endif default: / we do not know how to handle the (valid) message, indicate error MSP $M! headSerialError(0); break; tailSerialReply()
39、;/上面case执行完成后,发送最后一个数据 实际就是发送校验和。二、测试过程1、打开32位MWC配置软件 选择串行口 按erad读取数据2、打开串口监视精灵 特别是115200波特率的选择十分重要,因为MWC的软件就是这样写的,设定的。监视到的原始数据COM3,Wirte(36): $M#0tt$M#0uu$M#0oo$M#0pp$M#0qq$MCOM3, Read(1): ,COM3, Read(1): tCOM3, Read(1): ACOM3, Read(1): NCOM3, Read(1): GCOM3, Read(1): LCOM3, Read(1): M.COM3, Read(1
40、): #0COM3, Read(1): #0COM3, Read(1): #0COM3, Read(1): #0COM3, Read(1): COM3, Read(1): $COM3, Read(1): MCOM3, Read(1): COM3, Read(1): #2COM3, Read(1): rCOM3, Read(1): #0COM3, Read(1): #0COM3, Read(1): pCOM3,Wirte(78): $M#0dd$M#0ss$M#0ee$M#0ff$M#0gg$M#0hh$M#0ii$M#0jj$M#0kk$M#0mm$M#0nn$M#0$M#0COM3,Wirt
41、e(6): $MCOM3, Read(1): #7COM3, Read(1): dCOM3, Read(1): COM3, Read(1): #2COM3, Read(1): #0COM3, Read(1): #0COM3, Read(1): #0COM3, Read(1): #0COM3, Read(1): #0COM3, Read(1): COM3, Read(1): $COM3, Read(1): MCOM3, Read(1): COM3, Read(1): #8COM3, Read(1): sCOM3, Read(1): #9COM3, Read(1): #10COM3, Read(1): #11COM3, Read(1): #3COM3, Read(1): #6COM3, Read(1): #5COM3, Read(1): #16COM3, Read(1): #12COM3, Read(1): oCOM3, Read(1): $COM3, Read(1): MCOM3, Read(1): COM3, Read(1): #10COM3, Read(1): eCOM3, Read(1): COM3, Read(1): #11COM3, Read(1): #0COM3, Read(1): #0COM3, Read(1): #7COM3, Read(1
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年度网络安全技术服务合同标的及属性2篇
- 2024年全新船舶油品质量保证及节能减排协议2篇
- 2024版含地下室储藏室设计二手房销售合同2篇
- 2024年仓库钢材储存协议2篇
- 2024年度今日头条媒体采购合同3篇
- 2024年度药店商品陈列优化及销售合作协议3篇
- 2024三方冷链仓储配送一体化合同范本3篇
- 2024版建筑工程外墙真石漆涂覆合同3篇
- 2024版学校科研项目合作合同3篇
- 2024年度生物技术研究与开发合同6篇
- 生命科学前沿技术智慧树知到期末考试答案章节答案2024年苏州大学
- 2023年小儿推拿保健师考试真题试卷(含答案)
- 高血压护理常规课件
- 心脏介入手术谈话技巧
- 海南省三亚市吉阳区2022-2023学年六年级上学期期末数学试卷
- 办公楼消防改造工程环境保护措施
- 2023-2024学年高一下学期家长会 课件
- 溯源与解读:学科实践即学习方式变革的新方向
- 班克街教育方案
- 护理教育改革与创新研究
- 知识点总结(知识清单)-2023-2024学年人教PEP版英语六年级上册
评论
0/150
提交评论