用VB6标准模块实现微机与单片机间的通信源程序

  • 格式:doc
  • 大小:73.00 KB
  • 文档页数:7

VB6标准模块实现微机与单片机间的通信源程序用VB6标准模块实现微机与单片机间的通信源程序1、模块的使用方法:' (1) 在窗体中放置一个 MSComm 控件' (2) 设置好 MSComm 控件下面属性:' CommPort = 端口号 '端口号如为1,即COM1' Handshaking = 0 '无握手协议' InputMode = 1 '二进制收发模式' Settings = "9600,n,8,1" '波特率/奇偶校验/数据位/停止位' (3) 在程序入口放置下列命令:' Set CommControl = 窗体名.MSComm控件名' 如: Set CommControl = Form1.MSComm1'==============================================================' InitPort 函数说明打开指定端口并进行端口初始化' PortNum 指定端口号' ClosePort 函数说明关闭当前打开的端口' SendData 函数说明发送数据子程序' Addr 下位机地址号' Cmd 命令' Datas 数据(可选参数,调用时如不指定则发送一无数据的命令串)' Timeout 超时时间,单位:秒(s)' (每发送一帧数据后需接收一个回应数据,等于 0 - 成功不等于 0 - 失败)' GetData 函数说明接收数据子程序' lData 要接收数据长度(纯数据长度,不包含其它固定格式数据)' Buffer 接收数据缓冲区' Addr 要接收数据下位机地址(不指定时自动采用最后一次发送地址)' Timeout 超时时间,单位:秒(s)' 各个函数返回值' 0 vbSuccess '通信成功' 1 vbBusy '端口忙' 2 vbOpenPortFailed '端口打开失败,端口可能已被其它应用程序所占用' 3 vbTimeout '通信超时' 4 vbInvalidData '接收的数据有误' 5 vbPortNotOpened '端口还未初始化'==============================================================2、模块的程序设计:Option Explicit'======== 通信结果枚举定义 ========'Public Enum CommResultvbSuccess = 0vbBusy = 1vbOpenPortFailed = 2vbTimeout = 3vbInvalidData = 4vbPortNotOpened = 5End Enum'======== 通信常数定义 ========'Public Const SOI = &HAA '定义开始位Public Const EOI = &HBB '定义停止位Public Const VER = &H10 '定义版本号'========模块内部变量定义========'Public CommControl As MSComm '定义模块内部控件名Public DefAddr As Byte '定义默认下位机地址'------------------------------------------------------------------------------------------------Public Function ClosePort() As CommResult'打开通讯端口If Not CommControl.PortOpen ThenClosePort = vbPortNotOpened '端口还未初始化Exit FunctionEnd IfClosePort = vbSuccessCommControl.PortOpen = False '关闭端口End Function'------------------------------------------------------------------------------------------------Public Function InitPort(ByVal PortNum As Byte) As CommResult'打开通讯端口If CommControl.PortOpen Then '如果端口已打开,返回 vbBusyInitPort = vbBusyExit FunctionElse '否则尝试打开端口On Error Resume NextmPort = PortNumCommControl.PortOpen = TrueIf Err.Number <> 0 Then '如果打开失败,返回 vbOpenPortFailedInitPort = vbOpenPortFailedExit FunctionEnd IfEnd If '成功,继续End Function'------------------------------------------------------------------------------------------------Public Function GetData(ByVal lData As Byte, Buffer As String, Optional ByVal Addr As Byte = 0, _ Optional ByVal Timeout As Long = 1) As CommResultCheckComm '检测 CommControl 对象If Not CommControl.PortOpen Then '如果端口还未打开,返回GetData = vbPortNotOpenedExit FunctionEnd If'定义变量Dim CheckSum As Long, CheckSum2 As Long, i As ByteDim tmpBuffer As String, OldTimer As SingleIf Addr = 0 Then Addr = DefAddr '如果不指定地址,则以发送地址为接收地址lData = lData + 8CommControl.InputLen = lDataOldTimer = TimerDo '判断通信是否超时,是则中断通信并提示If CommControl.InBufferCount >= lData Then tmpBuffer = CommControl.Input: Exit DoIf Timer - OldTimer >= Timeout Then GetData = vbTimeout: Exit FunctionDoEventsLoop While TrueIf AscB(MidB(tmpBuffer, 1, 1)) <> SOI Or AscB(MidB(tmpBuffer, 2, 1)) <> VER Or _AscB(MidB(tmpBuffer, 3, 1)) <> Addr Or AscB(MidB(tmpBuffer, lData, 1)) <> EOI ThenGetData = vbInvalidDataExit FunctionEnd If'======== 算出收到数据的 CheckSum ===========CheckSum = 0lData = AscB(MidB(tmpBuffer, 5, 1))For i = 2 To lData + 5CheckSum = CheckSum + AscB(MidB(tmpBuffer, i, 1))NextCheckSum = CheckSum And &HFFFF&CheckSum2 = AscB(MidB(tmpBuffer, 7 + lData, 1)) * 256 + AscB(MidB(tmpBuffer, 6 + lData, 1))'判断 CheckSum 是否正确If CheckSum2 <> CheckSum Then GetData = vbInvalidData: Exit Function'所有检测通过则返回正确数据Buffer = tmpBufferGetData = vbSuccessEnd Function'------------------------------------------------------------------------------------------------Public Function SendData(Addr As Byte, Cmd As Byte, Optional Datas As String = "", Optional ByVal Timeout As Long = 1) As CommResultCheckComm '检测 CommControl 对象If Not CommControl.PortOpen Then '如果端口还未打开,返回SendData = vbPortNotOpenedExit FunctionEnd If'定义变量Dim BinData() As Byte, i As Long, lData As LongDim CheckSum As LonglData = LenB(Datas)ReDim BinData(1 To 8 + lData) '将数据转储到<字节数组>BinData(1) = SOIBinData(2) = VERBinData(3) = AddrDefAddr = AddrBinData(4) = CmdBinData(5) = lDataCheckSum = BinData(2) + BinData(3) + BinData(4) + BinData(5) '算出收到数据的 CheckS umFor i = 6 To lData + 5BinData(i) = AscB(MidB(Datas, i - 5, 1))CheckSum = CheckSum + BinData(i)NextBinData(i) = CheckSum And &HFFBinData(i + 1) = (CheckSum \ &H100) And &HFFBinData(i + 2) = EOICommControl.Output = BinData '发送数据Dim Response As String '定义回应数据缓冲区SendData = GetData(1, Response, , Timeout) '接收回应数据If SendData = vbSuccess Then '接收回应:等于 0 - 成功不等于 0 - 失败 SendData = IIf(AscB(MidB(Response, 6, 1)) = 0, vbSuccess, vbInvalidData) 'End IfEnd Function'------------------------------------------------------------------------------------------------Private Sub CheckComm()'检测 CommControl 对象If CommControl Is Nothing ThenErr.Raise -1, , "请先设置 CommControl 对象的引用,格式为" & vbCrLf & vbCrLf & _" Set CommControl = 窗体名.MSComm控件名" & vbCrLf & vbCrLf & _"如 Set CommControl = Form1.MSComm1"End IfEnd Sub'------------------------------------------------------------------------------------------------Public Function ErrMsg(nErr) As StringErrMsg = Choose(nErr + 1, "成功", "端口忙", "端口打开失败", "通信超时", "数据有误", "端口还未打开")End Function'------------------------------------------------------------------------------------------------;=========================================================================================== ======;单片机与微机间串行通信AT89C52单片机部分程序 (单片机晶振振荡频率 11.0592MHZ)RT_CONTROL BIT P3.2 ;RS-485串口通信控制(接收低电平,发送高电平);----------------------------------------------------------------------------;变量定义RD_ADDRESS EQU 5FH ;接收PC数据地址指针PCBUF EQU 60H ;PC读写数据缓冲区:60H-DFH,128BYTESTD_ADDRESS EQU 60H ;PC发送数据首址SOI_PC EQU 60H ;开始位 [地址]VER_PC EQU 61H ;版本号 [地址]ADR_PC EQU 62H ;地址位 [地址]CMD_PC EQU 63H ;命令位 [地址]LEN_PC EQU 64H ;数据长度[地址]DATBUF_PC EQU 65H ;数据首 [地址];----------------------------------------------------------------------------;数据赋值SP_ADDRESS EQU 0E0H ;堆栈指针值SOI_DATA EQU 0AAH ;开始位VER_DATA EQU 10H ;硬件版本:1.0ADR_DATA EQU 01H ;从机地址:1EOI_DATA EQU 0BBH ;结束位;----------------------------------------------------------------------------;设定程序入口地址ORG 0000HLJMP MAIN_INITORG 0023HLJMP UARTI;============================================================================;主程序MAIN_INIT: ;主程序初始化MOV SP,#SP_ADDRESS ;设定栈基址MOV TMOD,#20H ;TIMER1工作在MODE2MOV TH1,#0FDH ;波特率9600MOV TL1,#0FDH ;SETB TR1 ;启动TIMER1计时MOV SCON,#50H ;UART工作在MOWE1,SM1=1,REN=1;-------------------------------------------------------MOV IE,#10010000B ;UART中断激活;-------------------------------------------------------CLR RT_CONTROL ;允许RS-485接收; .;============================================================================; 中断服务子程序UARTI: CLR EA ;关中断PUSH A ;保护现场PUSH PSWMOV PSW,#00010000B ;使用三区寄存器MOV A,#05H ;接收数据数量 SOI-VER-ADR-CMD-LEN =[5 BYTE] MOV RD_ADDRESS,#PCBUF ;设置接收PC数据地址指针LCALL R_DATA ;调用接收数据子程序MOV A,SOI_PCCJNE A,#SOI_DATA,UARTI_B_E ;SOI不正确,则转移MOV A,VER_PCCJNE A,#VER_DATA,UARTI_B_E ;VER不正确,则转移MOV A,ADR_PCCJNE A,#ADR_DATA,UARTI_B_E ;ADR不正确,则转移MOV A,LEN_PC ;判断LEN,再接收 nDATA-CHK-EOIADD A,#03H ;接收数据数量MOV RD_ADDRESS,#DATBUF_PC ;设置接收PC数据地址指针LCALL R_DATA ;调用接收数据子程序LCALL CHECKSUM ;调用CHECKSUM子程序JNZ UARTI_B_E ;CHECKSUM不正确,则转移MOV DATBUF_PC,#00H ;接收数据正确,则返回#00HLCALL T_PC_BACK ;调用回应子程序LCALL CHK_R_DATA ;调用接收数据处理子程序AJMP UARTI_OUTUARTI_B_E:MOV DATBUF_PC,#0FFH ;接收数据不正确,则返回#0FFHLCALL T_PC_BACK ;调用回应子程序UARTI_OUT:POP PSW ;恢复现场POP ACLR RT_CONTROL ;允许RS-485接收SETB EA ;开中断RETI;;============================================================================; 接收数据子程序R_DATA: CLR RT_CONTROL ;允许RS-485接收MOV R0,A ;接收数据数量装入R0MOV R1,RD_ADDRESS ;接收数据首址装入R1MOV R2,#00HMOV R3,#00HR_WAI: JBC RI,R_JMP ;检测SCON的RI是否为1?是则表示接收到8位数据DJNZ R3,$DJNZ R2,R_WAILJMP R_OUT ;R_JMP: MOV A,SBUF ;SBUF装入AMOV @R1,AINC R1 ;地址加一CLR RI ;清除RIDJNZ R0,R_WAIR_OUT: RET ;;-------------------------------------------------------; 发送数据子程序T_DATA: SETB RT_CONTROL ;允许RS-485发送MOV R0,A ;发送数据数量装入R0MOV R1,#TD_ADDRESS ;发送数据首址装入R1T_LOOP: MOV A,@R1 ;MOV SBUF,A ;数据装入SBUFMOV R2,#00HMOV R3,#00HT_WAI: JBC TI,T_JMP ;检测SCON的TI是否为0?是则表示已发送8位数据DJNZ R3,$DJNZ R2,T_WAILJMP T_OUTT_JMP: INC R1 ;地址加一DJNZ R0,T_LOOP ;T_OUT: CLR RT_CONTROL ;允许RS-485接收RET ;;=========================================================================================== ======。