📄 16.txt
字号:
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通信事件
Case comEvReceive
'收到Rthreshold个字节产生的接收事件
Buffer = .Input
Arr = Buffer
'读取一个接收字节
' Text1.Text = Arr(0)
If Arr(0) = &H1B Then
.RThreshold = 0
Do
DoEvents
Loop Until .InBufferCount >= 4
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,000")
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)
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
我晕,第三次回答同样的问题了
....首先,串口所发的数据是有码制变化的。。分为2种情况,字符串和16进制发送。
两种方式的发送和接受方法是不同的。
先说16进制的
Dim sData() As Byte
Dim bData(1 To 6) As Byte
Dim strBuff As String
MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,1"
MSComm1.RThreshold = 1
MSComm1.PortOpen = True
bData(1) = &HE0
bData(2) = &H0
bData(3) = &H3F
bData(4) = &H0
bData(5) = &H0
bData(6) = &H1F
MSComm1.InputMode = comInputModeBinary
必须把数据先存进一个字符数组中。
下面是接收的代码
Private Sub MSComm1_OnComm()
If MSComm1.CommEvent = 2 Then
MSComm1.InputLen = 0
strBuff = MSComm1.Input
sData() = strBuff
For i = 0 To UBound(sData)
If Len(Hex(sData(i))) = 1 Then
strdata = strdata & "0" & Hex(sData(i))
Else
strdata = strdata & Hex(sData(i))
End If
Next
Text1.Text = strdata
If Text1.Text <> Text2.Text Then
Text2.Text = Text1.Text
List1.AddItem (Text2.Text)
End If
End If
End Sub
下面是发送的代码
MSComm1.Output = bData
好了16进制就是这样。
如果是字符串发送方式就简单了。。直接发送,不用存到数组中。MSComm1.Output = "abcd" 接收只需要把strBuff = MSComm1.Input放在循环中判断就行了。
说明。。一般设备控制多用字符串方法就可以了。。如投影机的控制等。而单片机的控制多用于16进制传输的方法。先要搞清楚用的什么方式。
再说编码的问题。。一般都是 明码转成ascII码再转成16进制码。然后再发送。
再解释一下用数组的理由:
单片机接受数据一般的都是一串16进制值的组合。如1f 00 00 1e ff 2c等等。。要一次发送出一个组合的数据,必须用数组存这些数据后发送这个数组!
PLC主程序
网络1
// 设置控制方式为自由口通信方式,启动接收字符中断 //
PLC首次扫描
自由口通信,波特率为9600,数据位8,停止位1,无校验
初始化RCV,允许RCV,有结束符,检查空闲时间
结束符为 A
空闲时间为5MS
一次接收的最大字符为6个
启动通信口,接收完成中断
全局允许中断
接收数据
LD SM0.1
MOVB 16#09, SMB30
MOVB 16#B0, SMB87
MOVB 16#0A, SMB89
MOVB 6, SMB94
ATCH INT_0, 23
ENI
RCV VB199, 0
网络2
// 检测温度送VW0 //
转换成实际温度值
从工作站编号送到输出缓冲区
检测温度送输出缓冲区
LD SM0.0
MOVW AIW0, VW0
/I +54, VW0
MOVW AIW2, VW2
/I +54, VW2
MOVW 1, VW300
MOVW VW0, VW302
MOVW VW2, VW304
网络3
// 设置温度控制上限和下限//
LD SM0.0
MOVW +350, VW4
MOVW +450, VW6
网络4
// 检测温度低于下限,则输出加温 //
LDW< VW0, VW4
A SM0.5
S Q0.0, 1
网络5
// 检测温度高于上限,则输出降温 //
LDW> VW0, VW6
A SM0.5
R Q0.0, 1
网络6
//准备传送参数 //
发送字节数据,送VB99
发送检测温度数据,送VW100
发送工作站编号数据,送VW102
LD SM0.0
MOVB 6, VB99
MOVW VW300, VW100
MOVW VW302, VW102
MOVW VW304, VW104
网络7
// 传送数据 //
LD SM0.5
XMT VB99, 0
中断程序
网络1
//通信口接收数据完成后的中断 //
// SMB86 等于16#20,表示PLC收到结速符 //
收到结束符,把收到的数据传到VB400
中断有条件返回
否则继续接收
LDB= SMB86, 16#20
MOVB VB200, VB400
CRETI
NOT
RCV VB199, 0
\\*******************************\\
VB源程序
Dim x1, k1, k2
Dim p11, p22 '定义变量
Dim aa() As Byte '定义数组
Private Sub Command1_Click() '开始监控,定时器1有效
Timer1.Enabled = True
End Sub
Private Sub Command2_Click() '退事程序,定时器1无效
Timer1.Enabled = False
Cls '清屏
Unload Me
End Sub
Private Sub Form_Load() '初始化
Timer1.Enabled = False '定时器1无效
Timer1.Interval = 100 '定时器1时间为0.1S
Timer2.Enabled = True '定时器2有效
Timer2.Interval = 1000 '定时器2时间为1S
Picture1.ScaleMode = 0 '定义纵横坐标
MSComm1.CommPort = 1 '设定端口号
MSComm1.Settings = "9600,n,8,1" '设定通讯波特率
MSComm1.InputLen = 6 '输入缓冲区为6个字符
MSComm1.InBufferSize = 256 '接收缓冲器大小
MSComm1.OutBufferSize = 256 '输出缓冲器大小
MSComm1.InputMode = comInputModeBinary '以二进制传输
MSComm1.OutBufferCount = 0 '清空发送缓冲区
MSComm1.InBufferCount = 0 '清空接收缓冲区
End Sub
Private Sub Timer1_Timer() '定时器1有效,触发接收事件
MSComm1.PortOpen = True '打开端口
ReDim aa(0 To 5) '定义动态数组
k1 = 0 '识别PLC站号,为1
If k1 = 0 Then MSComm1.Output = "1" + Chr(10) + Chr(13) '发送
Do While MSComm1.InBufferCount = 0 '准备接收数据
Loop
aa = MSComm1.Input '接收数据存入数组
If aa(0) > 64 Then GoTo xxx:
k2 = Int(aa(0) * 255 + aa(1) * 1)
Select Case k2
Case 1
p11 = Int(aa(2) * 255 + aa(3) * 1)
p22 = Int(aa(4) * 255 + aa(5) * 1)
Case Else
End Select
k1 = k1 + 1
If k1 > 2 Then k1 = 0
xxx:
MSComm1.PortOpen = False
End Sub
Private Sub Timer2_Timer() '绘制各中频炉的温度曲线
x1 = x1 + 1 '时间增加为1S
Picture1.PSet (x1, p11), vbRed '绘制1#炉的温度曲线,为红色
Picture1.PSet (x1, p22), vbBlue '绘制2#炉的温度曲线,为黄色
Text1.Text = Str(p11) '输出1#炉温度值
Text2.Text = Str(p22) '输出2#炉温度值
Text3.Text = Str(x1) '输出监控时间
End Sub
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -