资源描述:
《Modbus 通讯协议编程.doc》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
Modbus通讯协议编程本人最近为了实现电脑与DeltaVFD-M变频器通讯,特意用VB6.0编了一个Modbus协议通讯软件,不过这只是一个测试版,但Modbus的ASCii协议和RTU协议都己经实现。现在将源程序上贴,希望可以帮助到有需要的朋友,谢谢!(我发现图片贴不上去)另外,假如你觉得有更好的想法,欢迎E-mail指教。附:VB6源程序OptionExplicitPrivateTextltextAsStringPrivateRTUCRCAsString'串口选择PrivateSubCombo1_Click()MSComml.CommPort=Combol.Listindex+1EndSub'数据位改变PrivateSubCombo2_Click()CallsettingEndSub'波特率改变PrivateSubCombo3_Click()CallsettingEndSub'奇偶校验改变PrivateSubCombo4_Click()CallsettingEndSub'停止位改变PrivateSubCombo5_Click()CallsettingEndSubPrivateSubsetting()MSComml.Settings=CStr(Combo3.Text)&&CStr(Combo4.Text)&",”&CStr(Combo2.Text)_&&CStr(Combo5.Text)EndSub'打开关闭串口PrivateSubCommand1_Click()OnErrorResumeNextIfMSComml.PortOpen=FalseThenMSComml.PortOpen=True ElseMSComml.PortOpen=FalseEndIf IfMSComml.PortOpenThen使能Commandl.Caption=”关闭串口"Combol.Enabled=FalseElseCommandl.Caption=”打开串口”Combol.Enabled=TrueEndIfIfErrThenMsgBoxError$,48,"错误信息”ExitSubEndIfEndSub'10转16进制PrivateSubCommand2_Click(IndexAsInteger)OnErrorResumeNextText4.Text=Hex(Text3.Text)IfErrThenMsgBoxError$,48,”错误信息”ExitSubEndIfEndSubT6转10进制PrivateSubCommand3_Click()DimaAsLonga=Val(”&H”&CStr(Text4.Text))Text3.Text=aEndSub'手动串口发送PrivateSubCommand4_Click()IfMSComml.PortOpen=FalseThenMsgBox”请先打开串口,”错误信息'ExitSubEndIfCallsentsubEndSub'清除接收窗PrivateSubCommand5_Click()Text2.Text=””EndSubPrivateSubCommand6_Click()UnloadMeEndSub'打开关闭按钮显示文字及combol'打开串口失败,则显示出错信息“则显示出错信息 PrivateSubCommand7_Click()OnErrorResumeNextDimSTPAsStringSTP=CStr(Chr(2))&**010001"&CStr(Chr(3))&n25"MSComml.Settings="9600,N,7,2”MSComml.PortOpen=TrueMSComml.Output=STPMSComml.PortOpen=FalseIfErrThen'打开串口失败,则显示出错信息MsgBoxError$,48,”错误信息"ExitSubEndIfEndSubPrivateSubCommand8_Click()OnErrorResumeNextDimFWDAsStringFWD=CStr(Chr(2))&"010101"&CStr(Chr(3))&"26"MSComml.Settings=”9600,N,7,2”MSComml.PortOpen=TrueMSComml.Output=FWDMSComml.PortOpen=FalseIfErrThen'打开串口失败,则显示出错信息MsgBoxError$,48,”错误信息”ExitSubEndIfEndSubPrivateSubCommand9_Click()OnErrorResumeNextDimREVAsStringREV=CStr(Chr(2))&”010201”&CStr(Chr(3))&“27”MSComml.Settings="9600,N,7,2"MSComml.PortOpen=TrueMSComml.Output=REVMSComml.PortOpen=FalseIfErrThen'打开串口失败,则显示出错信息MsgBoxError$,48,“错误信息”ExitSubEndIfEndSub'窗口加载PrivateSubForm_Load()Dimd%Ford=1To16Combol.AddItem("COM"&CStr(d))Next Combol.Listindex=0Combo2.AddItem”6”Combo2.AddItem"7"Combo2.AddltemCombo2.Listlndex=2Combo3.Addltem“110”Combo3.Addltem“330”Combo3.Addltem“1200”Combo3.Addltem“2400”Combo3.AddItem"4800"Combo3.AddItem"9600"Combo3.AddItem"19200"Combo3.AddItem"38400"Combo3.AddItem"56000"Combo3.AddItem“57600“Combo3.AddItem"115200"Combo3.Listindex=5Combo4.AddItem"n"Combo4.AddItem"o"Combo4.AddItem"e"Combo4.Listindex=0Combo5.AddItem"1"Combo5.Addltem"2"Combo5.Listlndex=0Ford=0To254Combo6.AddItemdNextCombo6.Listlndex=1Textl.Text=u010601001770"Text2.Text="uText3.Text=""Text4.Text=Text5.Text=n1000uText6.Text=“06“Text7.Text=”0”Text8.Text="1"Optionl.value=TrueOption3.value=TrueOption7.value=True Option9.value=TrueIfMSComml.PortOpen=FalseThenCommandl.Caption=”打开串口”ElseCommandl.Caption=”关闭串口"EndIfEndSub'串口接收程序PrivateSubMSComm1_OnComm()DimHexchrAsString,hexstringAsString,iAsInteger,jAsInteger,hexdispAsStringIfOption8.valueThenhexstring=MSComml.Input'十六进制显示i=Len(hexstring)Forj=1ToiHexchr=Mid(hexstring,j,1)IfHex(Asc(Hexchr))<16ThenText2.Text=Text2.Text&"O"&Hex(Asc(Hexchr))&””ElseText2.Text=Text2.Text&Hex(Asc(Hexchr))&””EndIfNextjText2.Text=Text2.Text&CStr(Chr(13))&CStr(Chr(1O))ElseText2.Text=Text2.Text&MSComml.Input&CStr(Chr(13))&CStr(Chr(1O))*ASCll码显示EndIfEndSub'手动发送选择PrivateSubOption1_Click()IfOptionl.value=TrueThenTimer1.Enabled=FalseCommand4.Enabled=TrueElseTimerl.Enabled=TrueCommand4.Enabled=FalseEndIfEndSub•DeltaASCII发送协议PrivateSubOption10_Click()Combo6.Enabled=TrueText6.Enabled=TrueText7.Enabled=TrueText8.Enabled=TrueLabellO.Enabled=TrueLabel11.Enabled= TrueLabel12.Enabled=TrueLabell3.Enabled=TrueOption6・Enabled=FalseOption7.Enabled=FalseOptionl1・value=TrueCombo2.Listlndex=1Combo5.Listlndex=1Textl.Enabled=FalseLabell4.Enabled=FalseFrame7.Visible=TrueEndSub'自动发送选择PrivateSubOption2_Click()IfOption2value=TrueThenTimerl.Enabled=TrueCommand4.Enmbled=FalseElseTimerl.Enabled=FalseCommand4.Enabled=TrueEndIfEndSubPrivateSubOption3_Click()'Non选项Combo6.Enabled=FalseText6.Enabled=FalseText7.Enabled=FalseText8.Enabled=FalseLabell0.Enabled=FalseLabel11.Enabled=FalseLabel12.Enabled=FalseLabell3.Enabled=FalseOption6.Enabled=TrueOption7.Enabled=TrueCombo2.Listindex=2Combo5.Listindex=0Text"!・Enabled=TrueLabell4.Enabled=TrueFrame7.Visible=FalseEndSubPrivateSubOption4_Click()'ASCII选项Combo6.Enabled=TrueText6.Enabled=TrueText7.Enabled=TrueText8.Enabled=TrueLabellO.Enabled=TrueLabel11.Enabled=TrueLabel12.Enabled=TrueLabell3.Enabled=TrueOption6・Enabled=FalseOption7.Enabled=False Combo2.Listlndex=1Combo5.Listindex=1Textl.Enabled=FalseLabell4.Enabled=FalseFrame7.Visible=FalseEndSubPrivateSubOption5_Click()*RTU选项Combo6.Enabled=TrueText6.Enabled=TrueText7.Enabled=TrueText8.Enabled=TrueLabellO.Enabled=TrueLabell1.Enabled=TrueLabell2.Enabled=TrueLabell3.Enabled=TrueOption6・Enabled=FalseOption7.Enabled=FalseCombo2.Listindex=2Combo5.Listindex=1Textl.Enabled=FalseLabell4.Enabled=FalseFrame7.Visible=FalseEndSub'发送时间间隔调整输入PrivateSubText5_Change()DimnumberAsStringDimnumAsIntegerDimnumcycAsIntegernum=Len(Text5.Text)Fornumeye=1Tonumnumber=Mid(Text5.Text,numeye,1)SelectCaselnStr("0123456789",number)Case0MsgBox”输入时间间隔错误,请重新输入“,,”错误信息”ExitSubEndSelectNextTimerl」nterval=Text5.TextEndSub'自动发送定时器PrivateSubTimer1_Timer()IfMSComml.PortOpenThenCallsentsubEndIf EndSub'状态刷新定时器PrivateSubTimer2_Timer()StatusBarl.Panels(1).Text="串口选择:”&CStr(Combol.Text)StatusBarl.Panels(2).Text=”串口设置:"&CStr(MSComm1.Settings)StatusBarl.Panels(3).Text="串II状态:"&CStr(MSComm1.PortOpen)EndSub'串口发送子程序PrivateSubsentsub()Dimoptioncase%IfOption3.valueThenoptioncase=1IfOption4.valueThenoptioncase=2IfOption5.valueThenoptioncase=3IfOptionlO.valueThenoptioncase=4SelectCaseoptioncaseCase1IfOption6.valueThenText1text=Textl.TextCallHexsentElseText1text=Textl.TextCallASCIIsentEndIfCase2Callincorporate'将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串CallASCIIcheckCallASCIIsentCase3Callincorporate'将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串CallRTUcheckCallHexsentCase4Callincorporatel'将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串CalldeltaASCIICallASCIIsentEndSelectEndSub'十人•进制发送PrivateSubHexsent()Dimhexchrlen%,HexchrAsString,hexcyc%,hexmidAsByte,hexmiddleAsString Dimhexchrgroup()AsByte,iAsIntegerhexchrlen=Len(Textltext)Forhexcyc=1Tohexchrlen,检查Textl文本框内数值是否合适Hexchr=Mid(Text1text,hexcyc,1)IflnStr(n0123456789ABCDEFabcdef1,Hexchr)=0ThenMsgBox"无效的数值,请重新输入“,,“错误信息“ExitSubEndIfNextReDimhexchrgroup(1Tohexchrlen2)AsByteForhexcyc=1TohexchrlenStep2,将文本框内数值分成两个、两个i=i+1Hexchr=Mid(Text1text,hexcyc,2)hexmid=Val(”&H”&CStr(Hexchr))hexchrgroup(i)=hexmid'MSComml.Output=CStr(hexmid)NextMSComml.Output=hexchrgroupEndSub•ASC码发送PrivateSubASCIIsent()MSComml.Output=Text1textEndSub'ASC校验,此段程序计算出LRC校验值,并加上字头和字尾PrivateSubASCIIcheck()Dima%,b%,chrnum%,LrcbyteAsStringDimchecksum%,char%,AscLrc%,Lrc%chrnum=Len(Textltext) Fora=1TochrnumStep2char=Val(”&H”&CStr(Mid(Text1text,a,checksum=checksum+charNextAscLrc=checksumMod&H100Lrc=(&HFF-AscLrc)+1IfLrc<16ThenLrcbyte="0"+CStr(Hex(Lrc))ElseLrcbyte=CStr(Hex(Lrc))EndIf2)))'两个两个的取字符'全部加起来'取255的余数'取二次补'此段程序是判断Hex(lrc)是否是一位'如果是的话,前面加0;否则不加零Textltext=CStr(Chr(58))&CStr(Textltext)&Lrcbyte&CStr(Chr(13))&CStr(Chr(10))EndSub•DeltaASCII校验,此段程序计算出LRC校验值,并加上字头和字尾PrivateSubdeltaASCII()Dima%,b%,chrnum%,LrcbyteAsStringDimchecksum%,char%,Lrc%chrnum=Len(Textltext)Fora=1Tochrnumchar=Asc(Mid(Text1text,a,1)),两个两个的取字符checksum=checksum+charNextLrc=(checksum+&H3)Mod&H100IfLrc<16Then数,Lrcbyte="0"+CStr(Hex(Lrc))ElseLrcbyte=CStr(Hex(Lrc))EndIf'全部加起来'収255的余数'此段程序是判断Hex(lrc)是否是一位'如果是的话,前面加0;否则不加零Textltext=CStr(Chr(2))&CStr(Textltext)&CStr(Chr(3))&LrcbyteEndSub*RTU校验PrivateSubRTUcheck()DimCRC()AsByteDimd(5)AsByteDimstringlAsStringDimjAsInteger,chrlengthAsInteger,tempAsStringstringl=Textltextchrlength=Len(stringl)Forj=0Tochrlength/2-1temp=Mid(string1,j*2+1,2)d(j)=Val(”&H“&temp)NextRTUCRC=CRC16(d),调用CRC16计算函数,CRC(O)为高 位,CRC⑴为低位Textltext=Textltext&RTUCRCEndSubPrivateSubincorporate(),将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串DimwholecharAsString,wc%,wcyc%,wcharAsStringDimSIDAsString,CmdAsString,InfoAddAsString,dataAsStringDimSIDnum%,Cmdnum%,InfoAddNum%,Datanum%OnErrorResumeNextwholechar=CStr(Combo6.Text)&CStr(Text6.Text)&CStr(Text7.Text)&CStr(Text8.Text)wc=Len(wholechar)Forwcyc=1Towcwchar=Mid(wholechar,wcyc,1)IflnStr(MO123456789",wchar)=0ThenMsgBoxH输入钮误,请重新输入”,,%昔误提示”ExitSubEndIfNextSIDnum=Len(CStr(Hex(Combo6.Text)))SelectCaseSIDnumCase0ExitSubCase1SID="0n&CStr(Hex(Combo6.Text))Case2SID=CStr(Hex(Combo6.Text))EndSelectCmdnum=Len(CStr(Hex(Text6.Text)))SelectCaseCmdnumCase0ExitSubCase1Cmd="0"&CStr(Hex(Text6.Text))Case1Cmd=CStr(Hex(Text6.Text))EndSelectInfoAddNum=Len(CStr(Hex(Text7.Text)))SelectCaseInfoAddNumCase0ExitSub Case1InfoAdd="000"&CStr(Hex(Text7.Text))Case2InfoAdd="00"&CStr(Hex(Text7.Text))Case3InfoAdd="0"&CStr(Hex(Text7.Text))Case4InfoAdd=CStr(Hex(Text7.Text))EndSelectDatanum=Len(CStr(Hex(Text8.Text)))SelectCaseDatanumCase0ExitSubCase1data=”000”&CStr(Hex(Text8.Text))Case2data="00"&CStr(Hex(Text8.Text))Case3data="0"&CStr(Hex(Text8.Text))Case4data=CStr(Hex(Text8.Text))EndSelectIfErrThen'显示出错信息MsgBoxErrors,48,”错误信息”ExitSubEndIfTextltext=CStr(SID)&CStr(Cmd)&CStr(InfoAdd)&CStr(data)EndSubPrivateSubincorporate1()'将输入的十进制从机地址、命令、资料地址和资料内容合并成字符串DimwholecharAsString,wc%,wcyc%,wcharAsStringDimSIDAsString,CmdAsString,InfoAddAsString,dataAsStringDimSIDnum%,Cmdnum%,InfoAddNum%,Datanum%OnErrorResumeNextwholechar=CStr(Combo6.Text)&CStr(Text7.Text)&CStr(Text8.Text)wc=Len(wholechar)Forwcyc=1Towcwchar=Mid(wholechar,wcyc,1)IflnStr(,'0123456789H,wchar)=0ThenMsgBox“输入错误,请重新输入”,,”错误提示”ExitSub EndIfNextSIDnum=Len(CStr(Hex(Combo6.Text)))SelectCaseSIDnumCase0ExitSubCase1SID="0"&CStr(Hex(Combo6.Text))Case2SID=CStr(Hex(Combo6.Text))EndSelect'Cmdnum=Len(CStr(Hex(Text6.Text)))'SelectCaseCmdnum'Case0'ExitSub'Case1*Cmd="0"&CStr(Hex(Text6.Text))'Case1'Cmd=CStr(Hex(Text6.Text))'EndSelectInfoAddNum=Len(CStr(Hex(Text7.Text)))SelectCaseInfoAddNumCase0ExitSubCase1InfoAdd="0"&CStr(Hex(Text7.Text))Case2InfoAdd=CStr(Hex(Text7.Text))EndSelectDatanum=Len(CStr(Hex(Text8.Text)))SelectCaseDatanumCase0ExitSubCase1data="000"&CStr(Hex(Text8.Text))Case2data="00”&CStr(Hex(Text8.Text))Case3data="0"&CStr(Hex(Text8.Text))Case4data=CStr(Hex(Text8.Text)) EndSelect'显示出错信息IfErrThenMsgBoxError$,48,H错误信息”ExitSubEndIfIfOption11.valueThenCmd=“08“Textltext=CStr(SID)&CStr(Cmd)&CStr(lnfoAdd)ElseCmd=”07”Textltext=CStr(SID)&CStr(Cmd)&CStr(lnfoAdd)&CStr(data)EndIfEndSubPrivateFunctionCRC16(data()AsByte)AsStringDimCRC16LoAsByte,CRC16HiAsByte*CRC寄存器DimCLAsByte,CHAsByte'多项式码&HA001DimCRCLoAsString,CRCHiAsStringDimSaveHiAsByte,SaveLoAsByteDimiAsIntegerDimFlagAsIntegerCRC16Lo=&HFFCRC16Hi=&HFFCL=&H1CH=&HAOFori=0ToUBound(data)CRC16Lo=CRC16LoXordata(i),每一个数据与CRC寄存器进行异或ForFlag=0To7SaveHi=CRC16HiSaveLo=CRC16LoCRC16Hi=CRC16Hi2'高位右移一位CRC16L0=CRCI6L02•低位右移一位If((SaveHiAnd&H1)=&H1)Then'如果高位字节最后一位为1CRC16LO=CRCI6L0Or&H80'则低位字节右移后前面补1EndIf'否则自动补0If((SaveLoAnd&H1)=&H1)Thenyl果LSB为1,则与多项式码进行异或CRC16Hi=CRC16HiXorCHCRCI6L0=CRCI6L0XorCLEndIfNextFlagNextiIfLen(Hex(CRC16Hi))=1ThenCRCHi=©+Hex(CRC16Hi) ElseCRCHi=Hex(CRC16Hi)EndIfIfLen(Hex(CRC16Lo))=1ThenCRCLo=”0”+Hex(CRC16Lo)ElseCRCLo=Hex(CRC16Lo)EndIfCRC16=CRCLo+CRCHiEndFunction