搜档网
当前位置:搜档网 › VB串口通信源程序

VB串口通信源程序

VB串口通信源程序
VB串口通信源程序

[程序宝典]VB串口通讯实例

程序匠人 2005-9-22 14:23:00 阅读全文(3939) | 回复(0) | 引用(0) | 查看《匠人的百宝箱》代理商品

VB串口通讯实例

作者:liwenzhao

高精度电压表(24bit) VB源程序

Dim PortValue As Integer '端口号选择1-4

Dim value As Double '当前一次取值

Dim value2 As Double '要显示的值

Dim valueSum As Double '和

Dim numCount As Double '算平均值是的计数个数

Dim func As Integer '功能号标志1-4

Dim valueFlag As Integer

/**********************************************

' Check1_Click()为控制Command1是否Enabled

Private Sub Check1_Click()

'自动刷新被选中则刷新按钮无效

If Check1.value Then

Command1.Enabled = False

Else

Command1.Enabled = True

Command1.SetFocus

End If

End Sub

*********************************************/

/**********************************************

Private Sub Command1_Click()

'显示

Call display

End Sub

*********************************************/

Private Sub Command2_Click() '复位

valueSum = 0 '清计数和

numCount = 1 '清计数个数

Label6.Caption = Str(numCount - 1) '显示复位

value = 0

'当前一次取值

value2 = 0

'要显示的值

valueFlag = 0

Call display

End Sub

Private Sub Form_Activate()

numCount = 1

value = 0

valueSum = 0

PortValue = 1

Text1.Visible = False

Label6.Caption = "0"

Option1(0).value = True

Option2(0).value = True

'为什么两个都是True

Command1.SetFocus

'SetFocus是什么?

Label1.Caption = Format(value2, "0.000,000")

'Format为格式输出函数

For i = 0 To 3

If Option2(i).value = True Then

func = i + 1

End If

Next i

Check1.value = 1

'Call ComPortOpen

End Sub

Public Sub ComPortOpen() '开串口

With MSComm1

.CommPort = PortValue '使用COM1 .Settings = "9600,N,8,1" '设置通信口参数 .InBufferSize = 40

'设置MSComm1接收缓冲区为40字节

'.OutBufferSize = 2

'设置MSComm1发送缓冲区为2字节

'VB中OutBufferSize是以字符为单位的???

.InputMode = comInputModeBinary

'设置接收数据模式为二进制形式

.InputLen = 1

'VB中InputLen单位是字符数

'设置Input 一次从接收缓冲读取字节数为1

'.SThreshold = 1

'VB中SThreshold单位是字符数

'设置Output 一次从发送缓冲读取字节数为1

.InBufferCount = 0 '清除接收缓冲区

'.OutBufferCount = 0 '清除发送缓冲区

'MaxW = -99

'最大值赋初值????

'MinW = 99

'最小值赋初值????

'w = 0

'数据个数计数器清零

.RThreshold = 1

On Error Resume Next

'????

'设置接收一个字节产生OnComm事件

/**********************************************

'打开串口,如打不开,则Err,出现msg……

If .PortOpen = False Then

'判断通信口是否打开

.PortOpen = True '打开通信口

If Err Then '错误处理

msg = MsgBox(" 串口 COM" & PortValue & " 无效! ", vb OKOnly, "警告")

'vbOKOnly显示确定按钮

Exit Sub

End If

End If

**********************************************/

End With

'MsgBox "端口已打开"

End Sub

Public Sub ComPortClose() '关串口

MSComm1.PortOpen = False

' MsgBox "端口已关闭"

End Sub

Private Sub MSComm1_OnComm()

Call recive

End Sub

Private Sub Option1_Click(Index As Integer)

If MSComm1.PortOpen = True Then

Call ComPortClose

End If

PortValue = Index + 1

Call ComPortOpen

End Sub

Private Sub recive() '检测起始位并接收数据

Dim Buffer As Variant

Dim Arr() As Byte

Dim inData(5) As Byte

Dim count As Integer

Dim temp As Byte

' MsgBox "OnComm"

With MSComm1

Select Case .CommEvent

'判断MSComm1通信事件 CommEvent ???

Case comEvReceive

'收到Rthreshold个字节产生的接收事件

Buffer = .Input

Arr = Buffer

'读取一个接收字节

' Text1.Text = Arr(0)

If Arr(0) = &H1B Then

' &H表示是十六进制数,1B即27???是27

.RThreshold = 0

Do

DoEvents

' DoEvents是什么?

Loop Until .InBufferCount >= 4

'这里的4是不是应该是40

For i = 1 To 4

'count = .InBufferCount

Buffer = .Input

Arr = Buffer

inData(i) = Arr(0)

Next i

If inData(4) = &HA Then

If (inData(1) Mod 64) >= 32 Then

.RThreshold = 1

Exit Sub

End If

valueFlag = 1

'0.000003814697265625

temp = inData(1) Mod 16

If temp <= 7 Then

value = inData(1) Mod 8

value = value * 256 * 256

value = value + Val(inData(2)) * 256 value = value + Val(inData(3))

value = value * 3.814697265625E-06 'Text1.Text = Format(value, "0.000,00 0")

Else

value = inData(1) Mod 8

value = value * 256 * 256

value = value + Val(inData(2)) * 256 value = value + Val(inData(3))

value = value * 3.814697265625E-06 value = 0 - value

End If

temp = inData(1) Mod 128

' test OF

If temp >= 64 Then

If value < 0 Then

value = value - 0.000004

Else

value = value + 0.000004

End If

End If

'检测自动刷新

If Check1.value Then

'valueFlag = 1

Call display

End If

Else

.RThreshold = 1

Exit Sub

End If

.InBufferCount = 0

.RThreshold = 1

End If

Case Else

End Select

End With

'Text1.Text = Text1.Text + 1

End Sub

Private Sub Option2_Click(Index As Integer)

func = Index + 1

End Sub

Public Sub display() '判断功能并显示

'功能选择

Select Case func

Case 1 '当前值

value2 = value

Case 2 '平均值

If numCount > 100000 Then

numCount = 1

valueSum = 0

End If

If valueFlag = 1 Then

valueSum = valueSum + value

value2 = valueSum / numCount

numCount = numCount + 1

valueFlag = 0

Label6.Caption = Str(numCount - 1) 'Str()为数字转换成字符串函数

End If

Case 3 '最大值

If value > value2 Then

value2 = value

End If

Case 4 '最小值

If value < value2 Then

value2 = value

End If

Case Else

End Select

'Text1.Text = Str(valueSum)

Label1.Caption = Format(value2, "0.000,000") End Sub

Private Sub Timer1_Timer()'清缓冲区

' Text1.Text = MSComm1.InBufferCount

If MSComm1.InBufferCount >= 80 Then

MSComm1.InBufferCount = 0

End If

End Sub

[编程技巧]Visual Basic串口通讯调试方法

程序匠人 2005-10-22 19:48:00 阅读全文(1192) | 回复(0) | 引用(0) | 查看《匠人的百宝箱》代理商品

Visual Basic串口通讯调试方法

现有电子秤一台,使用串口与计算机进行通讯。编写VB程序来访问串口,达到读取电子秤上显示的数据。该电子秤为BE01型仪表,输出为RS-232C标准接口,波特率为300-9600、偶校验、7个数据位、2个停止位。所有字符均发送11位A SCII码,一个起始位。在VB中与串口通讯需要引入控件MSComm串口通讯控件(在Microsoft Comm Control 6.0中)。具体程序如下:控件简称:MSC

Dim 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()

ClearText

With 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 With

End Sub

********************************************************************* *******

Private Sub ClearText()

Text3.Text = ""

Text2.Text = "5"

Text1.Text = ""

End Sub

Private Sub Command1_Click() ’复位并打开串口

ClearText

’ nRece = 0 ’计数器清零

’是不是应该把前面的’去掉啊???

With MSC

.InputMode = comInputModeBinary ’设置数据接收模式为二进制形式

.InBufferCount = 0 ’清除接收缓冲区

If Not .PortOpen Then

.PortOpen = True ’打开通信端口

End If

End With

End Sub

Private Sub MSC_OnComm()

DelayTime ‘用来延续时间

ClearText

With MSC

Select Case .CommEvent ’判断通信事件

Case comEvReceive: ’收到Rthreshold个字节产生的接收事件SwichVar 1 ’是个子过程

If Out(1) = 2 Then ’判断是否为数据的开始标志

.RThreshold = 0 ’关闭OnComm事件接收

End If

Do

DoEvents

Loop Until .InBufferCount >= 3 ’循环等待接收缓冲区>=3个字节

’ nRece = nRece + 1

For i = 2 To 12

SwichVar i

Text1.Text = Text1.Text & Chr(Out(i))

Next

Text1.Text = LTrim(Text1.Text)

’ LTrim函数是将一个字符串中最前面的所有空格去掉

Text2.Text = Text2.Text & CStr(nRece) ’ CStr同Str

.RThreshold = 1 ’打开MSComm事件接收

Case Else

’ .PortOpen = False

End Select

End With

End Sub

********************************************************************* *******

Private Sub DelayTime()

Dim bDT As Boolean ’逻辑型数据

Dim sPrevious As Single, sLast As Single ’单精度

bDT = True

sPrevious = Timer (Timer可以计算从子夜到现在所经过的秒数,在Micros oft Windows中,Timer函数可以返回一秒的小数部分)

Do While bDT

If Timer - sPrevious >= 0.3 Then bDT = False

Loop

bDT = True

End Sub

(通信传输速率为9600bps,则最快速度1.04ms发送一个字节,仪表每秒发送5 0帧数据,每帧数据有4个字节,即每秒发送200个字节,平均5.0ms 发送一个字节,连续读取串口数据时要在程序中添加循环等待程序)

Private Sub SwichVar(ByVal nNum As Integer)

DelayTime

var = Null

var = MSC.Input

Out(nNum) = var(0)

End Sub

(设置接收数据模式采用二进制形式,即 InputMode=comInputModeBinary,但用Input属性读取数据时,不能直接赋值给 Byte 类型变量,只能通过先赋值给一个 Variant 类型变量,返回一个二进制数据的数组,再转换保存到Byte类型数变量中。)

Private Sub Text1_Change()

Text3.Text = CText(Text1.Text) - CText(Text2.Text)

End Sub

********************************************************************* *******

Private Function CText(ByVal str As String) As Currency

’ ByVal是什么?

If str <> "" Then

CText = CCur(Val(str))

’ CCur是什么?

Else

CText = 0

End If

End Function

(仪表每秒发送50帧数据,微机收到一帧完整数据至少需要20 ms时间,然后再进行数据处理。如果微机在下一帧数据接收前即20ms内能将数据计算处理完毕,则接收缓冲区内只会保存有一帧数据,不会存有两帧以上数据,接收缓冲区的大小不会影响实时监测效果(接收缓冲区>4字节),这时完全可以实现实时监测或实时控制;如果微机在20ms内不能将数据计算处理完毕,接收缓冲区设置得又很大,在数据计算处理完毕前,接收缓冲区内就会保存有两帧以上数据,而且一次工作时间越长,缓冲区内滞留数据帧就越多,数据采集和数据处理之间产生逐渐增大的额外时间差,当接收缓冲区充满后,时间差不再增大,固定在某一值,部分数据因不能及时采集到接收缓冲区中,数据产生丢失现象,真实工作情况就会和微机处理结果产生较大的时间差,对实时监测和实时控制很不利,这种情况下接收缓冲区的大小就会影响实时监测效果,所以接收缓冲区设置不能过大,以保证数据处理的实时性。)小结:本文所用的仪表为梅特勒公司出产的BE01型电子秤,其输出的每个编码均为标准的ASCII码。其他的仪表存在发射的编码中含有BCD压缩码,而且分为高低位,需要接收后对其进行解码换算,之后还要将高位和低位数字进行相加,即可以将其BCD码换算成实数。另还存在误差的可能:判断最大值,仪表在刚开始工作时有干扰,会传导一些乱码,位移传感器有参数偏差,最大值一般都略大于50毫米,所以取51为极限最大值,取-51为极限最小值。暂时先写这些,当然其他的情况可以依此类推

[

|

Dim JIHAO(0) As Byte ’机号

Dim head_data(4) As Byte ’5 Byte控制字

Dim end_data(0) As Byte '1 Byte 结束字

JIHAO(0) = Val(Text3.Text)

head_data(0) = Val(Text4.Text)

head_data(2) = &HEE 'TIMH

head_data(3) = &HEE 'TIML

head_data(4) = Val(Combo1.Text) 'INMOD

end_data(0) = &HFF

If Combo2.Text = "增加" Then head_data(1) = &H99

If Combo2.Text = "清空" Then head_data(1) = &H33

If Combo2.Text = "删除" Then head_data(1) = &H32

Ready = 0: ErrCount = 0

On Error GoTo ERRORCOM ’打开错误处理

'----------------------------------------------------------

If com1.Value Then https://www.sodocs.net/doc/0e3449732.html,mPort = 1 'Use com1

If com2.Value Then https://www.sodocs.net/doc/0e3449732.html,mPort = 2 'Use com2

MSComm1.Settings = https://www.sodocs.net/doc/0e3449732.html,bo3.Text + ",M,8,2" '设定波特率和置校验和位为1

MSComm1.InputLen = 0 '

MSComm1.PortOpen = -1 'Open the port

MSComm1.OutBufferCount = 0

MSComm1.Output = JIHAO ‘发送机号

MSComm1.PortOpen = False ’关闭串口

MSComm1.Settings = https://www.sodocs.net/doc/0e3449732.html,bo3.Text + ",S,8,2" '设定波特率和置校验和位为空

MSComm1.OutBufferCount = 0

MSComm1.PortOpen = True

MSComm1.Output = head_data

MSComm1.Output = Text2.Text

MSComm1.Output = end_data

MSComm1.PortOpen = False

Text1.Text = "发送成功!" + Chr(13) & Chr(10) + "发送至" +

Text3.Text + "屏体," + "信息编号:" + Text4.Text + Chr(13) & Chr(10) + Chr(13) & Chr(10) + Text1.Text

GoTo comend

ERRORCOM:

Text1.Text = "ERROR!请重新选择COM口!" + Chr(13) & Chr(10) + Chr(13) & Chr(10) + Text1.Text

comend:

On Error GoTo 0

End Sub

[ |

Interrupt Enable, Receiver Enable and Transmitter Enable*/

x = 0; /* flush receive buffer */

USART_RxTail = x;

USART_RxHead = x;

USART_TxTail = x;

USART_TxHead = x;

}

/* 接收中断 */

void USART_RX_interrupt( void )

{

unsigned char data;

unsigned char tmphead;

data = UDR0; /* read the received data */

tmphead = ( USART_RxHead + 1 ) & USART_RX_BUFFER_MASK;/* calculate buffer index */

USART_RxHead = tmphead; /* store new index */

if ( tmphead == USART_RxTail )

{

return;/* ERROR! Receive buffer overflow, you can use

flux cortorl */

}

USART_RxBuf[tmphead] = data; /* store received data in buffer */

}

/* 发送中断 */

void USART_TX_interrupt( void )

{

unsigned char tmptail;

if ( USART_TxHead != USART_TxTail )/* check if all data is transmitted */

{

tmptail = ( USART_TxTail + 1 ) & USART_TX_BUFFER_MASK;/*

calculate buffer index */

USART_TxTail = tmptail; /* store new index */

UDR0 = USART_TxBuf[tmptail]; /* start transmition */

}

else

{

UCSR0B &= ~(1<

}

}

[编程技巧]使用VB开发Windows环境下的串行通信程序

程序匠人 2005-9-21 11:32:00 阅读全文(1936) | 回复(0) | 引用(0) | 查看《匠人的百宝箱》代理商品

使用VB开发Windows环境下的串行通信程序

随着Windows在国内的普及,特别是Windows95的推出,越来越多的微机用户转向了Windows操作系统。不过Windows应用软件的开发对于一般工程技术领域的技术人员来说并非易事,不但Windows的消息循环机制不易理解,而且要开发一个功能强、界面美观的应用软件,其编程和调试的工作量是非常大的。许多并非搞软件出身的工程技术人员对Windows编程望而生畏。然而使用微软的VisualBasic来开发这些方面的Windows应用软件就十分方便,一般工程技术人员易于掌握,设计软件界面非常方便,编程工作量相对较小,只需进行主要应用功能的编程和少量界面控制的编程。本文介绍了笔者使用VB在串行通信编程方面的一些收获,由于在报刊杂志上对Windows下串行通信编程的介绍多为用MicrosoftC++或BorlandC++,故笔者愿意就VB在该方面的应用与大家探讨。对于采用了RS-232接口进行串行通信的计算机测控系统软件的开发,具有一定的参考价值。

在该系统中使用了80C31单片机作为下位机采集惯性敏感部件的测量数据,经过一定的预处理后通过RS-232串行口将数据传送给上位PC机。在PC机上Windows环境下运行检测软件,接受串行口传来的数据,进行数据处理、显示、存盘等。数据处理结果以表格形式打印输出。在VB3.0中,有许多专业厂商提供用户定制的控件(Customcontrol),这些控件以.VBX为后缀,其中MSCOMM.VBX即是用于串行通信的控件。对于VB3.0,启动后该控件就包含于控件工具箱(toolbox)内,否则可以通过File|AddFile将该控件加入控件工具箱。然后就可以利用该控件进行串行通信的程序设计。

下面举一个简单的例子,说明了如何进行串行通信的程序设计,该程序在Windows95环境下,使用VB3.0已经实现:

1.先建立一个项目文件,其控件如下表所示:

2.代码如下:

SubForm_Load()

https://www.sodocs.net/doc/0e3449732.html,mPort=1‘使用串行口1

'波特率9600,偶校验,8个数据位,1个停止位。

comm1.Settings=“9600,E,8,1”

当使用Comm1.Input时,每次从接收缓冲区取一个字节。

comm1.InputLen=1

timer1.interval=20‘定时器的中断间隔为20ms,用于更新显示时间。

EndSub

SubcmdComm_Click()

Dimechoch%‘命令变量

Staticmaxf01&,maxf02&,minf01&,minf02&‘最大值,最小值

OnErrorResumeNext‘简单的错误处理

maxf01&=maxf02&=0‘初始化变量

minf01&=32767

minf02&=32767

label2.Captio n=comm1.Settings‘显示串行口的设置。

Ifcmdcomm.Caption=“通信”Then‘若当前命令按扭的提示为“通信”则开始发送和

cmdcomm.Caption=“停止”‘接受数据,并将命令按扭提示改为“停止”,以

cmdexit.Enabled=False‘允许停止通信。使退出命令在通信中失效。

IfNotcomm1.PortOpenThen‘若串行口没有打开,则打开串行口

comm1.PortOpen=True

EndIf

Ifcomm1.PortOpenThen

Ifecho.Text<>“”Then‘若命令输入框不空,则将其转换为十六进制数值echoch%=Val(“&H”+echo.Text)

Else

echoch%=&HF0‘否则确省命令为F0H

EndIf

comm1.Output=Chr(echoch%)‘向串行口写入一字节命令,由WINDOWS自EndIf‘动将命令发出

label3.Caption=Hex(echoch%)‘显示刚发出的命令

DoWhilecomm1.PortOpen

Ifcomm1.InBufferCount>0Then‘若comm1.InBufferCount>0表示接受缓冲ch$=comm1.Input‘区有数据,并读出一个字符,

IfAsc(ch$)=echoch%Then‘若与发出的命令相同,则退出当前循环

ExitDo‘进入下一循环

EndIf

Else

comm1.Output=Chr(echoch%)‘否则继续向下位机发命令,通知下位机

EndIf‘送数据

dummy=DoEvents()‘让系统处理其他消息

Loop

‘下位机接受到正确的命令,并回发命令正确时,进入下面循环

i=1

DoWhilecomm1.PortOpen

Ifcomm1.InBufferCount>5Then

ch$=comm1.Input

DoWhileAsc(ch$)<>echoch%‘以命令字节同步测试数据

ch$=comm1.Input

Loop

ch1$=comm1.Input‘从WINDOWS串行数据接受缓冲区读测试数据

ch2$=comm1.Input

ch3$=comm1.Input

ch4$=comm1.Input

newf01&=CLng(CLng(Asc(ch2$))*16*16+Asc(ch1$))‘合并为一个整数newf02&=CLng(CLng(Asc(ch4$))*16*16+Asc(ch3$))

ifnewf01&>maxf01&Then‘判断最大值,最小值

maxf01&=newf01&

EndIf

Ifnewf01&<minf01&Then

minf01&=newf01&

EndIf

Ifnewf02&>maxf02&Then

maxf02&=newf02&

EndIf

Ifnewf02&<minf02&Then

minf02&=newf02&

EndIf

labf01.Caption=Str(newf01&)‘显示数据

labf02.Caption=Str(newf02&)

labmaxf01.Caption=Str(maxf01&)

labminf01.Caption=Str(minf01&)

labmaxf02.Caption=Str(maxf02&)

labminf02.Caption=Str(minf02&)

Else

comm1.Output=Chr(echoch%)

EndIf

dummy=DoEvents()

Loop

Else‘在通讯过程中,按下cmdCOMM按钮则停止通信,发出停止测试

cmdcomm.Caption=“通信”‘命令,关闭串行口,使退出按钮有效。comm1.Output=Chr(&H5F)

comm1.PortOpen=False

cmdexit.Enabled=True

EndIf

EndSub

SubcmdExit_Click()

Ifcomm1.PortOpenThen‘确认关闭串行口

comm1.PortOpen=False

EndIf

End‘终止整个程序

相关主题