VB中串口通讯的实现
- 格式:doc
- 大小:37.00 KB
- 文档页数:7
vb中怎样用mscomm控件实现串口通信本问分两部分均来自第一部分jessezappy(晶晶)================================================================================== If MSComm1.PortOpen Then MSComm1.PortOpen = FalsemPort = 1 '假定是用COM1口' 设定传输速率等,可依照您的需求更改MSComm1.Settings = "9600,N,8,1"MSComm1.PortOpen = True'---------初始化Modem-------------MSComm1.Output = "ATZ"MSComm1.Output = "AT&F"MSComm1.Output = "ATE0"MSComm1.Output = "ATM1"MSComm1.Output = "ATQ0"MSComm1.Output = "ATV0"'--------------------------拨号-------------MSComm1.Output ="ATDT163" '拨163'---------------------------接通后MSComm1.Output ="SDFJDKSJLKFA" '发送字符串'---------------------Private Sub MSComm1_OnComm() '用串口事件捕捉数据..If MSComm1.InBufferCount Then' 通讯埠中假如有资料的话, 则读取进来InStringB = InStringB & MSComm1.Input' 如果资料中有Chr(13) 和Chr(10) 的话, 则显示出来If InStr(InStringB, vbCrLf) Theninstring = instring & InStringBAddText Text3, InStringB, FalseInStringB = ""End IfEnd IfEND SUB'-------------------------挂断--------MSComm1.PortOpen = False '这个挂断方法不能适用所有MODEM,我正在研究...通用办法================================================================================================第二部分:===========================================================================最后借你一篇文章看,作者不是我,里面的不一定都对..'-----------------------------------------------------------VB Mscomm控件应用江苏戚墅堰机车车辆厂设计处(213011) 李秉璋--------------------------------------------------------------------------------Visual Basic 6.0(以下简称VB) 是一种功能强大、简单易学的程序设计语言。
VB6.0环境下利用Mscomm控件实现串行通信Use Mscomm Control Component to Implement Serial Communication under Visual Basic摘要: 本文简要介绍了VB6.0中Mscomm通信控件的属性和使用方法,并结合具体实例给出了基本的通信程序。
主题词:串行通信Visual Basic Mscomm .vbx控件Abstract: This paper briefly introduces the principle and method of Mscomm object of Visual basic 6.0, and with a real example basic program codes are given.Key Words:Serial Communication; Visual Basic; Mscomm .vbx control component随着计算机技术的飞速发展及其广泛应用,远程控制以及数据采集系统多采用上位机和下位机的主从工作方式,由于串行通信具有高效可靠、价格便宜,遵循统一的标准等特点,因而成为主要的通信手段。
微机的分析处理能力较强,有很好的人机界面和大容量的多种存储方式,所以上位机一般采用微机。
而单片机具有价格低,功能强,抗干扰能力好,温限宽和面向控制等特点,所以下位机采用单片机来构成主从式多机工作模式。
在需要对采集的数据进行分析处理或在远程需要对控制对象的控制过程进行统计或有条件控制时,采用数据库访问技术能有效地解决这类问题。
Visual Basic 6.0以其强大的功能、使用简单、能在短时间内开发出高效的通信程序而成为Windows系统开发的主要编程语言。
首先表现在VB可直接使用户自定义控件VBX或OCX文件;其次表现在VB可通过调用动态链接库(DLL,dynamic link library)来加快应用程序关键部分的执行速度。
1 设计用户界面第一新建一个“标准EXE”工程,然后选择“工程/部件”菜单项,在“部件”对话框当选择Microsoft Comm 即可添加MsComm控件;再在窗体中依次布置如下控件并设置其属性。
控件名称name属性Caption属性Form form1空Frame1frame1空Frame2frame2空Frame3frame3空Command1comd1确定Command2comd2退出Command3comd3确定Command4comd4退出Command5comd5做完退出MSComm msc1空Label 1lab1RS-232接口功能检测Label 2lab2请输入被检仪器程控码控制仪器功能Label 3lab3请输入被检仪器程控码读取仪器数据Text1txt1空Text2txt2空完成后的界面如图1所示图1 用户界面2 编写程序代码编写的程序代码如下:PriVate Sub Form_Load()=1 ’ 使用串行口1’波特率9600,偶校验,8个数据位,1个停止位Msc =“9600,E,8,1”’当使用Msc 时,每次从接收缓冲区取一个字节。
=0 ’读取整个接收缓冲区内码或消除=True ’ 打开串行口End SubPrivate Sub Comd1_Click()On Error Resume Next ’简单的错误处理If = "" Thenx = MsgBox("被检仪器程控码不能为空值", 16)Exit SubEnd If= + Chr$(13)’发送程控码For i = 1 ToNextEnd SubPrivate Sub Comd2_Click()= ""End SubPrivate Sub Comd3_Click()Dim instring As stringinstring == + Chr$(13)DoDoEventsLoop Until >= 20instring = ’ 从接收队列中读入字符串= ""= instring ’ 显示读入的字符串End SubPrivate Sub Comd4_Click()= ""End SubPrivate Sub Comd5_Click()= False ’ 关闭串行口EndEnd Sub3 程序简要说明上述程序设置的端口通信协议为:9600波特率,偶校验,8个数据位,1个停止位。
在VB中利用API进行串口通信一般来说,在VB中编写串口通讯程序,首先考虑到是使用MSComm控件,可是该控件不能设置超时,而且对许多内部的参数进行了隐藏,从而不能满足有些具体的工作。
而使用API进行串口通信,大多是使用VC,很少见到完整的VB代码,为此,我编写了这个模块。
同时,由于串口通信是基于字节流的,为方便程序设计,还编写了三个简单的辅助函数,并写了一个详细的测试代码。
Option ExplicitOption Base 0Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As LongPrivate Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As LongPrivate Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As LongPrivate Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Private Const GENERIC_READ = &H80000000Private Const GENERIC_WRITE = &H40000000Private Const OPEN_EXISTING = 3Private Const INVALID_HANDLE_VALUE = -1Private Declare Function GetCommState Lib "kernel32" (ByVal nCid As Long, lpDCB As DCB) As LongPrivate Declare Function SetCommState Lib "kernel32" (ByVal hCommDev As Long, lpDCB As DCB) As LongPrivate Declare Function SetCommTimeouts Lib "kernel32" (ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As LongPrivate Declare Function SetupComm Lib "kernel32" (ByVal hFile As Long, ByVal dwInQueue As Long, ByVal dwOutQueue As Long) As LongPrivate Declare Function PurgeComm Lib "kernel32" (ByVal hFile As Long, ByVal dwFlags As Long) As LongPrivate Const PURGE_TXABORT = &H1 ' Kill the pending/current writes to the comm port.Private Const PURGE_RXABORT = &H2 ' Kill the pending/current reads to the comm port.Private Const PURGE_TXCLEAR = &H4 ' Kill the transmit queue if there. Private Const PURGE_RXCLEAR = &H8 ' Kill the typeahead buffer if there. Private Type DCBDCBlength As LongBaudRate As LongfBitFields As Long 'See Comments in Win32API.TxtwReserved As IntegerXonLim As IntegerXoffLim As IntegerByteSize As ByteParity As ByteStopBits As ByteXonChar As ByteXoffChar As ByteErrorChar As ByteEOFChar As ByteEvtChar As BytewReserved1 As Integer 'Reserved; Do Not UseEnd TypePrivate Type COMMTIMEOUTSReadIntervalTimeout As LongReadTotalTimeoutMultiplier As LongReadTotalTimeoutConstant As LongWriteTotalTimeoutMultiplier As LongWriteTotalTimeoutConstant As LongEnd TypePrivate Declare Function SafeArrayGetDim Lib "oleaut32.dll" (ByRef saArray() As Any) As Long'串口操作演示Sub Main()Dim hComm As LongDim szTest As String'打开串口1hComm = OpenComm(1)If hComm <> 0 Then'设置串口通讯参数SetCommParam hComm'设置串口超时SetCommTimeOut hComm, 2, 3'向串口写入字符串123szTest = "123"WriteComm hComm, StringToBytes(szTest)'读串口szTest = BytesToString(ReadComm(hComm))Debug.Print szTest'关闭串口CloseComm hCommEnd IfEnd Sub'打开串口Function OpenComm(ByVal lComPort As Long) As LongDim hComm As LonghComm = CreateFile("COM" & lComPort, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)If hComm = INVALID_HANDLE_VALUE ThenOpenComm = 0ElseOpenComm = hCommEnd IfEnd Function'关闭串口Sub CloseComm(hComm As Long)CloseHandle hCommhComm = 0End Sub'读串口Function ReadComm(ByVal hComm As Long) As Byte()Dim dwBytesRead As LongDim BytesBuffer() As ByteReDim BytesBuffer(4095)ReadFile hComm, BytesBuffer(0), UBound(BytesBuffer) + 1, dwBytesRead, 0 If dwBytesRead > 0 ThenReDim Preserve BytesBuffer(dwBytesRead)ReadComm = BytesBufferEnd IfEnd Function'写串口Function WriteComm(ByVal hComm As Long, BytesBuffer() As Byte) As LongDim dwBytesWriteIf SafeArrayGetDim(BytesBuffer) = 0 Then Exit FunctionWriteFile hComm, BytesBuffer(0), UBound(BytesBuffer) + 1, dwBytesWrite, 0 WriteComm = dwBytesWriteEnd Function'设置串口通讯参数Function SetCommParam(ByVal hComm As Long, Optional ByVal lBaudRate As Long = 9600, _Optional ByVal cByteSize As Byte = 8, Optional ByVal cStopBits As Byte = 0, _Optional ByVal cParity As Byte = 0, Optional ByVal cEOFChar As Long = 26) As BooleanDim dc As DCBIf hComm = 0 Then Exit FunctionIf GetCommState(hComm, dc) Thendc.BaudRate = lBaudRatedc.ByteSize = cByteSizedc.StopBits = cStopBitsdc.Parity = cParitydc.EOFChar = cEOFCharSetCommParam = CBool(SetCommState(hComm, dc))End IfEnd Function'设置串口超时Function SetCommTimeOut(ByVal hComm As Long, Optional ByVal dwReadTimeOut As Long = 2, _Optional ByVal dwWriteTimeOut As Long = 3) As BooleanDim ct As COMMTIMEOUTSIf hComm = 0 Then Exit Functionct.ReadIntervalTimeout = dwReadTimeOut '读操作时,字符间超时ct.ReadTotalTimeoutMultiplier = dwReadTimeOut '读操作时,每字节超时ct.ReadTotalTimeoutConstant = dwReadTimeOut '读操作时,固定超时(总超时=每字节超时*字节数+固定超时)ct.WriteTotalTimeoutMultiplier = dwWriteTimeOut '写操作时,每字节超时ct.WriteTotalTimeoutConstant = dwWriteTimeOut '写操作时,固定超时(总超时=每字节超时*字节数+固定超时)SetCommTimeOut = CBool(SetCommTimeouts(hComm, ct))End Function'设置串口读写缓冲区大小Function SetCommBuffer(ByVal hComm As Long, Optional ByVal dwBytesRead As Long = 1024, _Optional ByVal dwBytesWrite As Long = 512) As BooleanIf hComm = 0 Then Exit FunctionSetCommBuffer = CBool(SetupComm(hComm, dwBytesRead, dwBytesWrite))End Function'清空串口缓冲区Sub ClearComm(ByVal hComm As Long, Optional ByVal InBuffer As Boolean = True, Optional ByVal OutBuffer As Boolean = True)If hComm = 0 Then Exit SubIf InBuffer And OutBuffer Then '清空输入输出缓冲区PurgeComm hComm, PURGE_TXABORT Or PURGE_RXABORT Or PURGE_TXCLEAR Or PURGE_RXCLEARElseIf InBuffer Then '清空输入缓冲区PurgeComm hComm, PURGE_RXABORT Or PURGE_RXCLEARElseIf OutBuffer Then '清空输出缓冲区PurgeComm hComm, PURGE_TXABORT Or PURGE_TXCLEAREnd IfEnd Sub'辅助函数:BSTR字符串转换为CHAR字符串Function StringToBytes(ByVal szText As String) As Byte()If Len(szText) > 0 ThenStringToBytes = StrConv(szText, vbFromUnicode)End IfEnd Function'辅助函数:CHAR字符串转换为BSTR字符串Function BytesToString(bytesText() As Byte) As StringIf SafeArrayGetDim(bytesText) <> 0 ThenBytesToString = StrConv(bytesText, vbUnicode)End IfEnd Function'辅助函数:获得CHAR字符串长度Function Byteslen(bytesText() As Byte) As LongIf SafeArrayGetDim(bytesText) <> 0 Then Byteslen = UBound(bytesText) + 1 End IfEnd Function。
VB中串口通讯的实现在VB中实现串口通讯需要借助于SerialPort类,该类提供了一系列方法和属性用于串口的配置和通讯操作。
接下来,定义一个SerialPort对象和一个字节数组,用于接收和发送数据。
在窗体加载事件中初始化SerialPort对象,并设置串口的一些属性,如波特率、数据位、校验位等,根据实际需求进行配置。
还可以设置数据接收和发送的事件处理函数。
例如,下面的代码演示了如何配置串口:```vbImports System.IO.PortsPublic Class Form1Dim serialPort As New SerialPortDim receiveBuffer(255) As BytePrivate Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load'配置串口属性serialPort.PortName = "COM1"serialPort.BaudRate = 9600serialPort.DataBits = 8serialPort.Parity = Parity.NoneserialPort.StopBits = StopBits.One'数据接收事件处理函数AddHandler serialPort.DataReceived, AddressOfSerialPort_DataReceived'打开串口serialPort.OpenEnd SubPrivate Sub SerialPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs)'接收数据Dim bytesToRead As Integer = serialPort.BytesToReadDim bytesRead As Integer = serialPort.Read(receiveBuffer, 0, bytesToRead)'处理接收到的数据If bytesRead > 0 ThenDim receivedData As String =Encoding.ASCII.GetString(receiveBuffer, 0, bytesRead) '显示接收到的数据UpdateReceivedData(receivedData)End IfEnd SubPrivate Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click'发送数据Dim sendData As String = txtSendData.TextDim sendBuffer As Byte( = Encoding.ASCII.GetBytes(sendData) serialPort.Write(sendBuffer, 0, sendBuffer.Length)'清空发送框txtSendData.Text = ""End SubPrivate Sub UpdateReceivedData(data As String)'更新接收数据的显示If Me.InvokeRequired Then ' 跨线程调用控件Me.Invoke(Sub( UpdateReceivedData(data))ElselblReceivedData.Text = dataEnd IfEnd SubEnd Class```在上述代码中,我们主要关注Form1_Load事件处理函数和btnSend_Click事件处理函数。
界面如下:代码如下:Private Sub Form_Load()If MSComm1.PortOpen = True Then MSComm1.PortOpen = False ElseEnd IfCombo1.AddItem "COM1"Combo1.AddItem "COM2"Combo1.AddItem "COM3"Combo1.AddItem "COM4"Combo1.AddItem "COM5"Combo1.AddItem "COM6"Combo1.AddItem "COM7"Combo1.AddItem "COM8"Combo1.AddItem "COM9"Combo1.AddItem "COM10" Combo1.AddItem "COM11" Combo1.AddItem "COM12"Combo1.AddItem "COM13"Combo1.AddItem "COM14"Combo1.AddItem "COM15"Combo1.AddItem "COM16"Combo1.ListIndex = 2Combo2.AddItem "256000"Combo2.AddItem "128000"Combo2.AddItem "115200"Combo2.AddItem "57600"Combo2.AddItem "38400"Combo2.AddItem "28800"Combo2.AddItem "19200"Combo2.AddItem "14400"Combo2.AddItem "12800"Combo2.AddItem "11520"Combo2.AddItem "9600"Combo2.AddItem "4800"Combo2.AddItem "2400"Combo2.AddItem "1200"Combo2.AddItem "600"Combo3.AddItem "无None"Combo3.AddItem "奇Odd"Combo3.AddItem "偶Even"Combo4.AddItem "4"Combo4.AddItem "5"Combo4.AddItem "6"Combo4.AddItem "7"Combo4.AddItem "8"Combo5.AddItem "1"Combo5.AddItem "2"mPort = Combo1.ListIndex + 1 MSComm1.Settings = "9600,n,8,1"ComOpen.Caption = "打开串口"Shape1.FillColor = &HFFFFC0End SubPrivate Sub ComOpen_Click()On Error GoTo uerror '发现错误跳转到错误处理If ComOpen.Caption = "关闭串口" ThenMSComm1.PortOpen = FalseComOpen.Caption = "打开串口" '按钮文字改变Shape1.FillColor = &HFFFFC0 '灯颜色改变ElseMSComm1.PortOpen = TrueComOpen.Caption = "关闭串口"Shape1.FillColor = &HFFEnd IfExit Subuerror:msg$ = "无效端口号" '错误显示Title$ = "串口调试助手"X = MsgBox(msg$, 48, Title$) '48标示显示警告图标End SubPrivate Sub MSComm1_OnComm()Dim BytReceived() As ByteDim strBuff As StringDim i As IntegerSelect Case mEvent '事件发生Case 2ClsMSComm1.InputLen = 0 '读入缓冲区全部内容strBuff = MSComm1.Input '读入到缓冲区Label10.Caption = Label10.Caption + Len(strBuff) '接收计数If MSComm1.InputMode = comInputModeBinary ThenBytReceived() = strBuff '如果是二进制接收模式则进行数据处理,否则直接显示字符串For i = 0 To UBound(BytReceived)If Len(Hex(BytReceived(i))) = 1 ThenstrData = strData & "0" & Hex(BytReceived(i)) & " " '如果只有一个字符,则前补0,如F显示0F,最后补空格Else '方便显示观察如:00 0F FEstrData = strData & Hex(BytReceived(i)) & " "End IfNextTextReceive = TextReceive & strDatastrData = ""ElseTextReceive = TextReceive & strBuffEnd IfEnd SelectEnd SubPrivate Sub ComSend1_Click() '手动发送Dim Temp(0) As ByteDim strBuff As StringIf Option1.Value = True Then '如果显示16进制发送则进行16进制处理,这里只发送一个Temp(0) = "&H" & TextSendMSComm1.Output = Temp '发送一个16进制ElsestrBuff = TextSendEnd IfIf MSComm1.PortOpen = False ThenMsgBox "请打开串口"End IfOn Error GoTo uerrorMSComm1.Output = strBuffLabel11.Caption = Label11.Caption + Len(strBuff) '发送计数uerror:End SubPrivate Sub ComSend2_Click()If ComSend2.Caption = "自动发送" ThenComSend2.Caption = "关闭自动发送"Timer1.Interval = TextTime.TextTimer1.Enabled = TrueElseComSend2.Caption = "自动发送"Timer1.Enabled = FalseEnd IfEnd SubPrivate Sub ComClean1_Click()TextSend.Text = "" '清空发送窗口End SubPrivate Sub Option3_Click()MSComm1.InputMode = comInputModeBinary '选择接收方式End SubPrivate Sub Option4_Click()MSComm1.InputMode = comInputModeText '选择接收方式End SubPrivate Sub Timer1_Timer()Call ComSend1_Click '定时调用手动发送End SubPrivate Sub Timer2_Timer()If Combo3 = "无None" ThenMSComm1.Settings = Str(Combo2) + "N" + Str(Combo4) + Str(Combo5) ElseIf Combo3 = "奇Odd" ThenMSComm1.Settings = Str(Combo2) + "O" + Str(Combo4) + Str(Combo5) ElseIf Combo3 = "偶Even" ThenMSComm1.Settings = Str(Combo2) + "E" + Str(Combo4) + Str(Combo5) End IfEnd SubPrivate Sub Combo1_Click()If MSComm1.PortOpen = True Then '如果串口打开先关闭后再进行其他操作MSComm1.PortOpen = FalseEnd IfmPort = Combo1.ListIndex + 1 '读取com口号End SubPrivate Sub ComClean3_Click()Label10.Caption = 0Label11.Caption = 0End SubPrivate Sub ComClean2_Click()TextReceive.Text = "" '接收窗口End Sub功能上:实现了字符串的发送和接收,8位数据的十六进制发送和接收,有端口,波特率等设置。
现有电子秤一台,使用串口与计算机进行通讯。
编写VB程序来访问串口,达到读取电子秤上显示的数据。
该电子秤为BE01型仪表,输出为RS-232C标准接口,波特率为300-9600、偶校验、7个数据位、2个停止位。
所有字符现有电子秤一台,使用串口与计算机进行通讯。
编写VB程序来访问串口,达到读取电子秤上显示的数据。
该电子秤为BE01型仪表,输出为RS-232C标准接口,波特率为300-9600、偶校验、7个数据位、2个停止位。
所有字符均发送11位ASCII码,一个起始位。
在VB中与串口通讯需要引入控件MSComm串口通讯控件(在Microsoft Comm Control 6.0中)。
具体程序如下:控件简称:MSCDim Out(12) As Byte '接收var中的值Dim var As Variant '接收MSC.input中的数值Dim nRece As Integer '计算MSC.inputbuffer的个数Dim i As Integer, j As Integer '随即变量,计算循环************************************************************************** **Private Sub Form_Load()ClearTextWith MSC.CommPort = 1 '设置Com1为通信端口.Settings = "9600,E,7,2" '设置通信端口参数 9600赫兹、偶校验、7个数据位、2个停止位.(这里需要进一步说明的是:.Setting=”BBBB,P,D,S”。
含义是:B:Baud Rate(波特率);P:Parity(奇偶);D:Data Bit;S:Stop Bit).InBufferSize = 40 '设置缓冲区接收数据为40字节.InputLen = 1 '设置Input一次从接收缓冲读取字节数为1.RThreshold = 1 '设置接收一个字节就产生OnComm事件End WithEnd Sub************************************************************************** **Private Sub ClearText()Text3.Text = ""Text2.Text = "5"Text1.Text = ""End SubPrivate Sub Command1_Click()ClearText' nRece = 0 '计数器清零With MSC.InputMode = comInputModeBinary '设置数据接收模式为二进制形式.InBufferCount = 0 '清除接收缓冲区If Not .PortOpen Then.PortOpen = True '打开通信端口End IfEnd WithEnd SubPrivate Sub MSC_OnComm()DelayTime ‘用来延续时间ClearTextWith MSCSelect Case .CommEvent '判断通信事件Case comEvReceive: '收到Rthreshold个字节产生的接收事件SwichVar 1If Out(1) = 2 Then '判断是否为数据的开始标志.RThreshold = 0 '关闭OnComm事件接收End IfDoDoEventsLoop Until .InBufferCount >= 3 '循环等待接收缓冲区>=3个字节' nRece = nRece + 1For i = 2 To 12SwichVar iText1.Text = Text1.Text & Chr(Out(i))NextText1.Text = LTrim(Text1.Text)Text2.Text = Text2.Text & CStr(nRece).RThreshold = 1 '打开MSComm事件接收Case Else' .PortOpen = FalseEnd SelectEnd WithEnd Sub************************************************************************** **Private Sub DelayTime()Dim bDT As BooleanDim sPrevious As Single, sLast As SinglebDT = TruesPrevious = Timer (Timer可以计算从子夜到现在所经过的秒数,在Microsoft Windows中,Timer函数可以返回一秒的小数部分)Do While bDTIf Timer - sPrevious >= 0.3 Then bDT = FalseLoopbDT = True(通信传输速率为9600bps,则最快速度1.04ms发送一个字节,仪表每秒发送50帧数据,每帧数据有4个字节,即每秒发送200个字节,平均5.0ms 发送一个字节,连续读取串口数据时要在程序中添加循环等待程序)Private Sub SwichVar(ByVal nNum As Integer)DelayTimevar = Nullvar = MSC.InputOut(nNum) = var(0)End Sub(设置接收数据模式采用二进制形式,即 InputMode=comInputModeBinary,但用Input 属性读取数据时,不能直接赋值给 Byte 类型变量,只能通过先赋值给一个 Variant 类型变量,返回一个二进制数据的数组,再转换保存到Byte类型数变量中。
VB 串口通信程序设计典型实例利用 VB 开发串口通信程序既可以使用 MSComm 控件也可以调用 Windows API 函数实 现。
不过,只要 MSComm 控件可以被选用,我们推荐选择此控件实现,因为 MSComm 控 件的功能和 API 调用一样强,甚至比它还好且使用起来更加简单。
在本章提供的串口通信程序设计中,除了 PC 与 PC 串口通信外,PC 与单片机、PC 与 智能仪表、PC 与 PLC、PC 与 GSM 短信模块等串口通信任务的实现均采用 MSComm 控件。
6.1 PC 与 PC 串口通信程序设计当两台串口设备通信距离较近时,可以直接连接,最简单的情况,在通信中只需 3 根线 (发送线、接收线、信号地线)便可实现全双工异步串行通信。
本设计通过两台 PC 串口 3 线连接,介绍了利用 API 函数和 MSComm 控件设计串口通 信程序的方法,包括字符与文件的发送与接收。
6.1.1 PC 与 PC 串口通信程序设计目的(1)掌握 PC 与 PC 串口通信的线路连接方法。
(2)利用 MSComm 控件和 API 函数实现 PC 与 PC 串口通信的程序设计方法。
6.1.2 PC 与 PC 串口通信程序设计用软、硬件本设计用到的硬件和软件清单如表 6-1 所示。
表 6-1 序 1 2 3 号 PC 或 IPC 串口通信线(三线制) Visual Basic 6.0 设计用软、硬件 名 称 数 2 1 1 量6.1.3 PC 与 PC 串口通信程序硬件线路图线路说明,在计算机通电前,按图 6-1 所示将两台 PC 通过串口线连接起来:计算机 A 串口 COM1 端口的 TXD 与计算机 B 串口 COM1 端口的 RXD 相连, 计算机 A 串口 COM1 端 口的 RXD 与计算机 B 串口 COM1 端口的 TXD 相连, 计算机 A 串口 COM1 端口的 GND 与 计算机 B 串口 COM1 端口的 GND 相连。
利用VB如何进行串口读写在VB中,可以使用SerialPort类来进行串口读写操作。
以下是使用VB进行串口读写的一般步骤:1. 引用System.IO.Ports命名空间:在代码文件的顶部,添加Imports System.IO.Ports命名空间,以便可以使用SerialPort类。
2. 创建SerialPort对象:在代码中创建SerialPort对象,并设置串口的各种属性,如端口名称、波特率、数据位、校验位、停止位等。
例如:```vbDim serialPort As New SerialPortserialPort.PortName = "COM1"serialPort.BaudRate = 9600serialPort.Parity = Parity.NoneserialPort.DataBits = 8serialPort.StopBits = StopBits.One```3. 打开串口:使用serialPort.Open(方法打开串口,并检查串口是否成功打开。
例如:```vbTryserialPort.OpenIf serialPort.IsOpen ThenMessageBox.Show("串口已打开")End IfCatch ex As ExceptionMessageBox.Show("串口打开失败:" & ex.Message)End Try```4. 读取串口数据:使用serialPort.DataReceived事件来处理接收到的数据。
例如:```vbPrivate Sub serialPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles serialPort.DataReceived Dim receivedData As String = serialPort.ReadExisting'处理接收到的数据End Sub```5. 写入串口数据:使用serialPort.Write(方法向串口写入数据。
VB中串口通讯的实现福建李铭陈春美一、概述串口通讯作为一种古老而又灵活的通讯方式,被广泛地应用于PC间的通讯以及PC和单片机之间的通讯之中。
提到串口通讯的编程,人们往往立刻想到C、汇编等对系统底层操作支持较好的编程语言以及大串繁琐的代码。
实际上,只要我们借助相关ActiveX控件的帮助,即使是在底层操作一向不被人看好的VB 中,一样能够实现串口通讯,甚至其实现方法和C、汇编相比,要更加快捷方便。
下面,笔者就介绍一下在VB中实现串口通讯的方法。
在Visual Basic中有一个名为Microsoft Communication Control(简称MSComm)的通讯控件。
我们只要通过对此控件的属性和事件进行相应编程操作,就可以轻松地实现串口通讯。
下面,笔者就简要地介绍一下MSComm控件的使用方法。
二、MSComm控件的主要属性、事件1、MSComm的属性由于MSComm控件属性很多,在此笔者仅介绍与实现串口通讯密切相关的核心属性。
Commport:设置通讯所占用的串口号。
如设成1(默认值),表示对Com1进行操作。
Setting:对串口通讯的相关参数。
包括串口通讯的比特率,奇偶校验,数据位长度、停止位等。
其默认值是“9600,N,8,1”,表示串口比特率是9600bit/s,不作奇偶校验,8位数据位,1个停止位。
Portopen:设置串口状态,值为True时打开串口,值为False时关闭串口。
Input:从输入寄存器读取数据,返回值为从串口读取的数据内容,同时输入寄存器将被清空。
Ouput:发送数据到输出寄存器。
InBufferCount:设置输入寄存器所存储的字符数,当将其值设为0时,则输入寄存器将被清空。
InputMode:设置从输入寄存器中读取数据的形式。
若值为0,则表示以文本形式读取;值为1,则表示以二进制形式读取。
OutBufferCount:设置输出寄存器所存储的字符数,当将其值设为0时,则输出寄存器将被清空。
RThreshold:设置在MSComm控件设置CommEvent属性为comEvReceive并产生OnComm事件之前要接受的字符数。
CommEvent属性:返回最近的通讯事件或错误。
通过对它具体属性值的查询,我们就可以获得通讯事件和通讯错误的完整信息。
当其值是comEvReceive时表示接收到数据。
2、MSComm的事件除了公共事件之外,MSComm只有一个OnComm事件。
当CommEvent属性值变化时将发生OnComm事件,指示发生一个通讯事件或错误。
当我们设置Rtheshold属性值为0时,将使得捕获comEvReceive事件无效。
三、串口通讯编程实例在完成了对MSComm控件的简要介绍之后,笔者就以实际程序为例,介绍一下串口通讯的具体实现方法。
1、PC机间的串口通讯(1)、实现方法:A、新建一个窗体,在上面放两个Text控件、两个CommandButton控件和两个Label控件(如图1.bmp所示)。
具体见下表:控件类型名称Caption属性作用-------------------------------------------------------------------------------Text Text1 ------- 输入所要发送的信息Text Text2 ------- 显示接收到的信息CommandButton Command1 发送---------CommandButton Command2 退出---------Label Label1 发送的数据提示Label Label2 接收的数据提示B、在控件工具箱中的空白处点击鼠标右键,在弹出的菜单中选择“部件”,在弹出的窗口中的控件列表中找到“Microsoft Comm Control”,将其选中,在点击“应用”、“关闭”,在控件工具栏中就会出现一个电话的小图标。
C、用串口线将两台电脑连接起来。
您可以使用Com1对Com1的对应连接,也可以使用Com1和Com2的交叉连接。
本程序使用的是Com1对Com1的连接。
D、输入以下代码:Private Sub Command1_Click()'...发送数据MSComm1.OutBufferCount = 0 '...清空输出寄存器MSComm1.Output = Text1.Text '...发送数据End SubPrivate Sub Command2_Click()'...退出Unload MeEnd SubPrivate Sub Form_Load()'...初始化mPort = 1 '...使用Com1口MSComm1.Settings = "9600,n,8,1" '...设置通讯参数MSComm1.PortOpen = True '...打开串口End SubPrivate Sub Mscomm1_Oncomm()'...通讯事件发生Select Case mEventCase comEvReceive '...有接受事件发生Text2.Text = MSComm1.Input '...接受显示数据MSComm1.InBufferCount = 0 '...清空输入寄存器End SelectEnd Sub2、PC机与单片机之间的通讯PC机与单片机之间的通讯被广泛的用于工业、医疗测控等领域之中。
在应用中,我们通常将单片机作为“感受器”和“效应器”,负责数据采集、响应计算机发出的指令对电路进行控制,有时也进行一些简单的运算,最后再将执行数据反馈给计算机处理。
本程序将实现在PC机上输入一个0-255之间的整数,将此数据发送到单片机,单片机接收到数据后,将数据在显示管上显示,再将此数除以2,将得数返回给PC机。
(运行效果如图 3.BMP所示)其实现方法如下:A、同PC机间通讯的实现方法A-B。
B、连接电脑和单片机。
注意!由于PC机端的RS232电平与单片机端TTL的并不不匹配,故应注意电平转换。
C、在VB中输入以下代码:Private Sub Mscomm1_Oncomm()'...通讯事件发生Dim indata As VariantDim bte(0) As ByteSelect Case mEventCase comEvReceive '...有接受事件发生indata = MSComm1.Input'...注意!要通过MSComm控件发送或接收二进制数据必须用Variant类型的变量对二进'...制Byte类型的变量进行转换!bte(0) = AscB(indata)Text2.Text = bte(0)MSComm1.InBufferCount = 0 '...清空输入寄存器End SelectEnd SubPrivate Sub Command1_Click()'...发送数据Dim Num As IntegerDim outbte(0) As ByteNum = Val(Text1.Text)outbte(0) = CByte(Num)MSComm1.OutBufferCount = 0 '...清空输出寄存器MSComm1.Output = outbte(0) '...发送数据End SubPrivate Sub Command2_Click()'...退出Unload MeEnd SubPrivate Sub Form_Load()'...初始化mPort = 1 '...使用Com1口MSComm1.Settings = "9600,n,8,1" '...设置通讯参数MSComm1.PortOpen = True '...打开串口End SubD、单片机工作方式置于1,比特率设为9600bit/s。
在单片机上,我们只得使用汇编语言编写,并且调用中断实现对串口数据的收发工作。
源代码如下:PUSH PSW ;将程序状态字压入堆栈PUSH ACC ;将累加器压入堆栈CLR EA ;关闭系统中断CLR RI ;清除中断标志位MOV A,SBUF ;从接收寄存器中读取数据MOV 70H,A ;分解数据百、十、个位并显示MOV B,#100DIV ABMOV 52H,A ;分解百位,送入存储器52HMOV A,BMOV B,#10DIV ABMOV 51H,A ;分解十位,送入存储器51HMOV 50H,B ;分解个位,送入存储器50HMOV A,70HMOV B,#2DIV AB ;将接受的数据除以2MOV SBUF,A ;将得数发送到输出寄存器ACALL DL1 ;延时保证数据完整发送ACALL DL1CLR RI ;清除中断标志位SETB EA ;打开系统中断POP ACC ;累加器出栈POP PSW ;程序状态字出栈RETI ;中断程序返回3、编程环境以上程序在Windows 2000 Professional,Visual Basic 6.0企业版,AT89C52型单片机下调试通过。
四、总结从以上程序可以看出,在VB中利用MSComm控件,可以快速开发出串口通讯程序,从而大大提高编程效率。