解析MWC的串口通讯正式版0407.docx

上传人:b****5 文档编号:12093473 上传时间:2023-04-17 格式:DOCX 页数:27 大小:274.67KB
下载 相关 举报
解析MWC的串口通讯正式版0407.docx_第1页
第1页 / 共27页
解析MWC的串口通讯正式版0407.docx_第2页
第2页 / 共27页
解析MWC的串口通讯正式版0407.docx_第3页
第3页 / 共27页
解析MWC的串口通讯正式版0407.docx_第4页
第4页 / 共27页
解析MWC的串口通讯正式版0407.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

解析MWC的串口通讯正式版0407.docx

《解析MWC的串口通讯正式版0407.docx》由会员分享,可在线阅读,更多相关《解析MWC的串口通讯正式版0407.docx(27页珍藏版)》请在冰豆网上搜索。

解析MWC的串口通讯正式版0407.docx

解析MWC的串口通讯正式版0407

解析MWC的串口通讯

一使用的软件

二使用的MWC定义串口协议文件

updated04July

Multiwiiserialprotocolwasredesigned:

•tobelight,asbefore

•tobegeneric:

itcanbeusedtransparenltybyaGUI,OSD,telemetryorhomemadeconfigtool.

ienomorespecificOSDcodeshouldbecodedinmultiwii

•tobebitwireefficient:

onlyrequesteddataaretransmittedinabinaryformat

•tobequitesecure:

dataaresentwithachecksum,preventingcorruptedconfigurationtobeinjected.

•tobeheadersensitive:

asitisdesignedwithaspecificheader,itcanbemixedwithotherframe,likeGPSframe

ie,itwillbepossibletoconnecteitheraGUIoraGPSonthesameserialportwithoutchangingtheconf

•tobelesssensitivetoevolutions:

ieincaseofparameterevolution,themainprotocolwillremaincompatibleandtheGUIwillbemuchlessversiondependent.

variabledatalengthallowstoconsideronlythebeginningofamessage,leavingtheotheroctetsattheendtoextendtransparentlythemessage(forinstancetoaddanewPID)

IthoughtfirstaboutanimplementationofMavlink,butIthinkit'snotwhatIwaslookingfor.

Evenwithapartialimplementation,thepredefinedstructuresarenotlightenoughforwhatIhaveinmind.

Somemessagesarehoweverinspiredfrommavlinkstructure.

Themainruleremains:

Multiwiineversendssomethingonitsown.

Arequestmustbedoneineachcasetoretrieveorsetdata.

Eachmessagesreceivedareacknowledgedevenifthereisnodatainside.

Thereare2mainmessagestoconsider:

•requestmessagetomultiwii

•multiwiioutputmessage

requestmessagetomultiwii

Torequestsimpledatawithoutparameters/sendaspecificcommand/injectnewparametersinmultiwii

messagesareformatedlikethis:

$M>[datalength][code][data][checksum]

1octet'$'

1octet'M'

1octet'<'

1octet[datalength]

1octet[code]

severaloctets[data]

1octet[checksum]

[datalength]canbe0incaseofnoparamcommand

multiwiioutputmessage

messagesareformatedlikethis:

$M>[datalength][code][data][checksum]

1octet'$'

1octet'M'

1octet'>'

1octet[datalength]

1octet[code]

severaloctets[data]

1octet[checksum]

ifthemessageisunknown:

$M|[0][code][checksum]

1octet'$'

1octet'M'

1octet'|'

1octet0

1octet[unknowncode]

1octet[checksum]

三、对写入MWC的原文件分析

voidserialCom(){//①MWC通过c=SerialRead(CURRENTPORT);解析缓冲区的数据

uint8_tc,n;

staticuint8_toffset[UART_NUMBER];

staticuint8_tdataSize[UART_NUMBER];

staticenum_serial_state{//串口的几种状态

IDLE,//空闲?

HEADER_START,//数据头开始$

HEADER_M,//数据头M

HEADER_ARROW,//数据箭头《

HEADER_SIZE,//数据尺寸

HEADER_CMD,//指令

}c_state[UART_NUMBER];//=IDLE;//状态数组默认空闲

for(n=0;n

#if!

defined(PROMINI)//假如不是ATmega328版本执行该段代码

CURRENTPORT=n;

#endif

#defineGPS_COND//假如定义了GPS_COND执行该段代码

#ifdefined(GPS_SERIAL)

#ifdefined(GPS_PROMINI)

#defineGPS_COND

#else

#defineGPS_COND&&(GPS_SERIAL!

=CURRENTPORT)

#endif

#endif

#defineSPEK_COND//假如定义了SPEK_COND执行该段代码

#ifdefined(SPEKTRUM)&&(UART_NUMBER>1)

#defineSPEK_COND&&(SPEK_SERIAL_PORT!

=CURRENTPORT)

#endif

while(SerialAvailable(CURRENTPORT)GPS_CONDSPEK_COND){//③while循环

uint8_tbytesTXBuff=((uint8_t)(serialHeadTX[CURRENTPORT]-serialTailTX[CURRENTPORT]))%TX_BUFFER_SIZE;

//indicatesthenumberofoccupiedbytesinTXbuffer发送缓冲区占用字节标定。

if(bytesTXBuff>TX_BUFFER_SIZE-50)return;

//ensurethereisenoughfreeTXbuffertogofurther(50bytesmargin)确保发送缓冲区之手50字节的余量。

c=SerialRead(CURRENTPORT);//读串口缓冲区serialBufferRX[数据指针][串口端口号],该缓冲区的数据是由串口接收中断函数inlinestore_uart_in_buf(uint8_tdata,uint8_tportnum)获取的来自电脑的数据。

if(c_state[CURRENTPORT]==IDLE)//这是一组完整指令代码244D3C006464$M<\#0dd

{//串口状态空闲等待HEADER_START状态的到来。

c_state[CURRENTPORT]=(c=='$')?

HEADER_START:

IDLE;//判定是$字符吗?

是进入HEADER_START状态。

if(c_state[CURRENTPORT]==IDLE)evaluateOtherData(c);//evaluateallotherincomingserialdata

}

elseif(c_state[CURRENTPORT]==HEADER_START)

{

c_state[CURRENTPORT]=(c=='M')?

HEADER_M:

IDLE;

}

elseif(c_state[CURRENTPORT]==HEADER_M)

{

c_state[CURRENTPORT]=(c=='<')?

HEADER_ARROW:

IDLE;//是字符<吗?

是表示有数据要进入MWC,此前发送都是数据头。

}

elseif(c_state[CURRENTPORT]==HEADER_ARROW)

{//是ARROW字符,判定缓冲区的大小。

if(c>INBUF_SIZE)

{//nowweareexpectingthepayloadsize我们期望足够的数据占用缓冲区。

c_state[CURRENTPORT]=IDLE;//数据位置不够退出循环。

continue;//不执行该while循环包含的后面的语句,跳出开始下一轮循环。

}

dataSize[CURRENTPORT]=c;//缓冲区够,将收到的数据赋值给当前端口的数据尺寸数组dataSize[串口端口号]。

offset[CURRENTPORT]=0;//设置数据指针的偏移位0。

checksum[CURRENTPORT]=0;//初始化数据的校验和为0。

存入数组中。

indRX[CURRENTPORT]=0;//

checksum[CURRENTPORT]^=c;//说明数据长度是校验的第一个字母。

c_state[CURRENTPORT]=HEADER_SIZE;//thecommandistofollow

//MWC收到数据长度,后面就是电脑发送的数据了。

MWC串口状态进入HWADER_SIZE。

}

elseif(c_state[CURRENTPORT]==HEADER_SIZE)

{//MWC串口是在HEADER_SIZE状态吗?

cmdMSP[CURRENTPORT]=c;//在HEADER_SIZE状态收到的第一个数据是指令。

checksum[CURRENTPORT]^=c;//将该数据异或进入校验和的数组中去。

c_state[CURRENTPORT]=HEADER_CMD;//MWC收到数据后,说明在指令状态,MWC进入HEAFER_CMD状态。

}

elseif(c_state[CURRENTPORT]==HEADER_CMD&&offset[CURRENTPORT]

{

checksum[CURRENTPORT]^=c;//进入校验和异或。

inBuf[offset[CURRENTPORT]++][CURRENTPORT]=c;//MWC将收到的电脑数据存入缓冲区内。

offset[CURRENTPORT]加1。

}

elseif(c_state[CURRENTPORT]==HEADER_CMD&&offset[CURRENTPORT]>=dataSize[CURRENTPORT])

{

//判定偏移指针大于等于数据预留位置大小吗?

if(checksum[CURRENTPORT]==c)

{//comparecalculatedandtransferredchecksum

//偏移指针大于等于数据预留位置大小,就将从电脑这次收到的数据作为校验和,与已经累计异或的checksum[]中的校验和数据对比,为真,表示,该数据包是有效的,可以调用下面的函数evaluateCommand()进行,数据包的解析。

evaluateCommand();//wegotavalidpacket,evaluateit我们获得了一个有效的数据包,解析评估这些数据。

}

c_state[CURRENTPORT]=IDLE;//MWC串口开始进入空闲状态。

}

}//③while循环

}//②for循环

}①

四、对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=d115=s102=f103=g104=h105=I106=j107=k109=m110=n253254

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(toggleRead){//只要按读按钮就发送下面的代码36个

toggleRead=false;

int[]requests={MSP_BOXNAMES,MSP_PIDNAMES,MSP_RC_TUNING,MSP_PID,MSP_BOX,MSP_MISC};//116=t117=u111=o112=p113=q114=r

sendRequestMSP(requestMSP(requests));

buttonWRITE.setColorBackground(green_);

}

if(toggleCalibAcc){

toggleCalibAcc=false;

sendRequestMSP(requestMSP(MSP_ACC_CALIBRATION));

}

if(toggleCalibMag){

toggleCalibMag=false;

sendRequestMSP(requestMSP(MSP_MAG_CALIBRATION));

}

if(toggleWrite){

toggleWrite=false;

//MSP_SET_RC_TUNING

payload=newArrayList();

payload.add(char(round(confRC_RATE.value()*100)));

payload.add(char(round(confRC_EXPO.value()*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(requestMSP(MSP_SET_RC_TUNING,payload.toArray(newCharacter[payload.size()])));

//MSP_SET_PID

payload=newArrayList();

for(i=0;i

byteP[i]=(round(confP[i].value()*10));

byteI[i]=(round(confI[i].value()*1000));

byteD[i]=(round(confD[i].value()));

}

…………………..

五、MWC处理指令的代码分析

voidevaluateCommand(){

switch(cmdMSP[CURRENTPORT]){

caseMSP_SET_RAW_RC:

for(uint8_ti=0;i<8;i++){

rcData[i]=read16();

}

headSerialReply(0);

break;

#ifGPS

caseMSP_SET_RAW_GPS:

f.GPS_FIX=read8();

GPS_numSat=read8();

GPS_coord[LAT]=read32();

GPS_coord[LON]=read32();

GPS_altitude=read16();

GPS_speed=read16();

GPS_update|=2;//NewdatasignalisationtoGPSfunctions

headSerialReply(0);

break;

#endif

caseMSP_SET_PID:

for(uint8_ti=0;i

conf.P8[i]=read8();//处理来自电脑的数据从inBuf[]数组中

conf.I8[i]=read8();

conf.D8[i]=read8();

}

headSerialReply(0);//处理完成后向电脑发送“$M>\#0\#0MSP_SET_PID”

break;

caseMSP_SET_BOX:

for(uint8_ti=0;i

conf.activate[i]=read16();

}

headSerialReply(0);

break;

caseMSP_SET_RC_TUNING:

conf.rcRate8=read8();

conf.rcExpo8=read8();

conf.rollPitchRate=read8();

conf.yawRate=read8();

conf.dynThrPID=read8();

conf.thrMid8=read8();

conf.thrExpo8=read8();

headSerialReply(0);

break;

caseMSP_SET_MISC:

#ifdefined(POWERMETER)

conf.powerTrigger1=read16()/PLEVELSCALE;

#endif

headSerialReply(0);

break;

caseMSP_IDENT:

headSerialReply(7);

serialize8(VERSION);//multiwiiversion

serialize8(MULTITYPE);//typeofmulticopter

serialize8(MSP_VERSION);//MultiWiiSerialProtocolVersion

serialize32(0);//"capability"

break;

caseMSP_STATUS:

headSerialReply(10);

serialize16(cycleTime);

serialize16(i2c_errors_count);

serialize16(ACC|BARO<<1|MAG<<2|GPS<<3|SONAR<<4);

serialize32(

#ifACC

f.ANGLE_MODE<

f.HORIZON_MODE<

#endif

#ifBARO&&(!

defined(SUPPRESS_BARO_ALTHOLD))

f.BARO_MODE<

#endif

#ifMAG

f.MAG_MODE<

#endif

#ifdefined(SERVO_TILT)||defined(GIMBAL)

rcOptions[BOXCAMSTAB]<

#endif

#ifdefined(CAMTRIG)

rcOptions[BOXCAMTRIG]<

#endif

#ifGPS

f.GPS_HOME

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1