谁能帮我设计一下这个串口问题

chailang326 2008-07-24 02:59:41
题目要求是从下面的要求中把O2的数据读出来,有关串口一直不会,不知道如何下手。
请各位高手帮我设计一下,比如要用到什么控件;大体怎样设计函数;有关细节方面。


概叙:
1. 本协议数据,均为16进制数据。如 "46"为十六进制的[70]
2. [xx]为单字节数据(无符号,0-255);(xx)为双字节数据,有符号(-32768至+32767),高字节在前。"――"后面为注解。
3. 所有数据均为整数,可能与实际显示数据之间有(100,10,1)倍的对应关系(与具体仪器有关)。如某仪器四组分SO2,CO2,CO,O2分别显示为899PPM ,2.000% ,010.0% , 20.80%.则仪器返回的数据分别除以1, 1000 ,10 , 100 为仪器显示值
4. 整个命令的字节长度 [LB]+3.
通信格式:
发送: [IP] [LB] [CMD] [DF] [CS]
[IP] 地址(固定为11)。
[LB] 紧接字节长度不包括CS
[CMD] 命令号
[DF] 命令所带参数项,可选项
[CS] CS= -(IP +LB+CMD +DF)

应答:
1.当指令得到正确执行时,应答
[ACK] [LB] [CMD] [DF] [CS]
[ACK] = 0X16 命令正确
[LB] 紧接字节长度不包括CS
[CMD] 命令号
[DF] 所带参数项,可选项
[CS] CS=-(ACK +LB+CMD+DF)

2.当指令没有得到正确执行时,应答
[NAK] [LB] [CMD] [EC] [CS]
[NAK] = 0X06 命令没有被正确执行
[LB] = 2 紧接字节长度不包括CS
[CMD] 命令号
[EC] 命令没有被执行的错误的代码
[CS] CS= -(NAK +LB+CMD+DF)


[EC]
01 命令长度不对或不能被正确解析
02 没有此命令
03 当前状态不能执行本命令



功能表

编号 功能名称 CMD 功能描述
1. 查询测量结果 0x01 除了返回测量结果外,还可以返回一些状态信息
2. 调零
3. 气体标定 用来气体校准


详细描叙
1. 查询测量结果
发送:11 01 01 ED
应答:[ACK] 05 01 (CO) (CO2) (CH4) (O2) [ST1] [ST2] [CS]
功能:查询测量结果
说明:
1. (CO) (CO2) (CH4) (O2) 为16 bit的有符号整数,最高位为符号位。在使用的过程中,可能出现负数,如:“0xFF,0xFF”(十进制:-1),这是由于仪器在使用的过程中,可能出现零点漂移,其中也会出现负向漂移。当漂移没有超出允许范围的时候,可以认为负数为“0”;当漂移超过范围,表明要进行“用户校正”。这里的负数仅仅是起进行“调零”或“用户校正”指示作用。整数 (CO) (CO2) (CH4) (O2) 与仪器测量的气体浓度有一个“倍数”关系,“倍数”和每台仪器的量程有关。例如:仪器量程为xxxx PPM时,“倍数”为1;仪器量程为 xxx.x%时,倍数为10;仪器量程为xx.xx%时候,“倍数”为100;当仪器量程为x.xxx%时候,“倍数”为1000。
2. [ST] 系统状态位,暂时保留。
2.N2调零
发送:11 01 03 EB
应答:[ACK] 01 03 [CS]
功能:
说明:
仪器接受到调零命令,将仪器的气体(CO) (CO2) (CH4)数据矫正到零点,O2不变,在命令发送后,仪器中还必须通入零气120s以上。

3.O2调零
发送:11 01 04 E6
应答:[ACK] 01 04 [CS]
功能:
说明:
仪器接受到调零命令,将仪器的O2数据矫正到20.90 %, (CO) (CO2) (CH4)不变,在命令发送后,仪器中还必须通入零气120s以上。

4.气体校正
仪器在使用了一段时间后,由于环境等条件的改变后,需要进行校正。
零点校正 (4B)
发送:11 04 4B [TVM] [DF1] [DF2] [CS]
应答:[ACK] 01 4B [CS]
功能:对仪器进行用户零点校正
说明:
1.[TVM]为气体标定指示位。0表示标定第一组份,1表示标定第二组份,等等。例如:当仪器组份为单组份时候,[TVM]只能取0;当仪器有四个组份。[TVM]可以取值{0,1,2,3}。
2.标定气体的浓度的值=(DF1*256+ DF2)/(倍数)。
3.“倍数”说明与“查询测量结果”命令中定义一样。
4.在执行本命令前,必须在传感器通入零气,在通入气体稳定(可以借鉴结果查询命令判断或者气流稳定地通入传感器一段时间)后发送本命令。气体校正的两点必须在短时间内完成。

量程点校正 (同上) (4C)
发送:11 04 4C [TVM] [DF1] [DF2] [CS]
应答:[ACK] 01 4C [CS]
功能:对仪器进行用户量程点校正
说明:
1.[TVM]为气体标定指示位。0表示标定第一组份,1表示标定第二组份,等等。例如:当仪器组份为单组份时候,[TVM]只能取0;当仪器有四个组份。[TVM]可以取值{0,1,2,3}。
2.标定气体的浓度的值=(DF1*256+ DF2)/(倍数)。
3.“倍数”说明与“查询测量结果”命令中定义一样。
4.在执行本命令前,必须在传感器通入与浓度符合的气体,在通入气体稳定(可以借鉴结果查询命令判断或者气流稳定地通入传感器一段时间)后发送本命令。用户校正的两点必须在短时间内完成。


...全文
203 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
lllsui 2008-07-30
  • 打赏
  • 举报
回复
^^
zdingyun 2008-07-29
  • 打赏
  • 举报
回复
这个地方不知道该怎么编了。用sjsend数组表示前三项后门的[TVM] [DF1] [DF2] [CS]怎么赋值到sjsend(3)里?
[DF1] [DF2]这两项是所带参数项,可选项。怎么在程序里发送??

LZ:由于你提供的协议不明确,仅从
发送:11 04 4B [TVM] [DF1] [DF2] [CS]
命令看:
LB为04,命令字节总长4+3为7字节,所以
[DF1] [DF2] 2字节必须有,至于其值是何,我认为缺省值或许为0
你可按11 04 4B [TVM] 00 00 [CS]来组织命令调试.
chailang326 2008-07-29
  • 打赏
  • 举报
回复
4.气体校正
仪器在使用了一段时间后,由于环境等条件的改变后,需要进行校正。
零点校正 (4B)
发送:11 04 4B [TVM] [DF1] [DF2] [CS]
应答:[ACK] 01 4B [CS]
功能:对仪器进行用户零点校正
说明:
1.[TVM]为气体标定指示位。0表示标定第一组份,1表示标定第二组份,等等。例如:当仪器组份为单组份时候,[TVM]只能取0;当仪器有四个组份。[TVM]可以取值{0,1,2,3}。
2.标定气体的浓度的值=(DF1*256+ DF2)/(倍数)。
3.“倍数”说明与“查询测量结果”命令中定义一样。
4.在执行本命令前,必须在传感器通入零气,在通入气体稳定(可以借鉴结果查询命令判断或者气流稳定地通入传感器一段时间)后发送本命令。气体校正的两点必须在短时间内完成
这个地方不知道该怎么编了。用sjsend数组表示前三项后门的[TVM] [DF1] [DF2] [CS]怎么赋值到sjsend(3)里?
[DF1] [DF2]这两项是所带参数项,可选项。怎么在程序里发送??
chailang326 2008-07-26
  • 打赏
  • 举报
回复
由于设备还没来,还没法试验,不过看你的代码受益匪浅,非常感谢!!!
zdingyun 2008-07-24
  • 打赏
  • 举报
回复
查询测量结果
发送:11 01 01 ED
应答:[ACK] 05 01 (CO) (CO2) (CH4) (O2) [ST1] [ST2] [CS]
[LB]返回值应为[0B]
以下按发送:11 01 01 ED 来获取(CO) (CO2) (CH4) (O2)测量值考虑的代码,供参考:
Option Explicit
Dim strData As String
Dim sjO2 As Single
Dim sjCH4 As Single
Dim sjCO2 As Single
Dim sjCO As Single
Dim sjSend() As Byte

Private Sub Command1_Click() '查询测量结果
ReDim sjSend(3)
sjSend(0) = &H11
sjSend(1) = &H1
sjSend(2) = &H1
sjSend(3) = &HED
MSComm1.Output = sjSend
End Sub

Private Sub Form_Load()
Dim port As Integer
port = 1
MSComm1.CommPort = port 'COM端口
MSComm1.Settings = "9600,n,8,1"
MSComm1.InputMode = comInputModeBinary '采用二进制传输
MSComm1.InBufferCount = 0 '清空接受缓冲区
MSComm1.OutBufferCount = 0 '清空传输缓冲区
MSComm1.RThreshold = 1 '产生MSComm事件
MSComm1.InBufferSize = 1024
MSComm1.PortOpen = True
End Sub

Private Sub MSComm1_OnComm() '接收数据
Dim BytReceived() As Byte
Dim strBuff As String
Select Case MSComm1.CommEvent
Case 2
MSComm1.InputLen = 0
strBuff = MSComm1.Input
BytReceived() = strBuff
Dim i As Integer
For i = 0 To UBound(BytReceived) '接收数据处理为16进制
If Len(Hex(BytReceived(i))) = 1 Then
strData = strData & "0" & Hex(BytReceived(i))
Else
strData = strData & Hex(BytReceived(i))
End If
Next ' 2 2 2 4 4 4 4 2 2 2
'数据处理代码 应答:[ACK] 0B 01 (CO) (CO2) (CH4) (O2) [ST1] [ST2] [CS]
If Mid(strData, 1, 2) = "16" And Len(strData) = 2 * (Val("&H" & Mid(strData, 3, 2)) + 3) Then
Text1 = strData
sjCO = Val("&H" & Mid(strData, 7, 4)) / 10
sjCO2 = Val("&H" & Mid(strData, 11, 4)) / 1000
sjCH4 = Val("&H" & Mid(strData, 15, 4))
sjO2 = Val("&H" & Mid(strData, 19, 4)) / 100
Print sjCO, sjCO2, sjCH4, sjO2
strData = "" '为下次接收做清除
End If
End Select
End Sub



chailang326 2008-07-24
  • 打赏
  • 举报
回复
我也是不知道,给我的要求是就是这么写的,是不是写错了?
无论如何都先感谢你,有关串口的我还不会,按你写的我研究一下。
zdingyun 2008-07-24
  • 打赏
  • 举报
回复
使用MSCOMM控件,进行收发命令。接收按2进制方式。接收代码大致如下:
Option Explicit
Dim strData As String

Private Sub Form_Load()
Dim port As Integer
port = 1
MSComm1.CommPort = port 'COM端口
MSComm1.Settings = "9600,n,8,1"
MSComm1.InputMode = comInputModeBinary '采用二进制传输
MSComm1.InBufferCount = 0 '清空接受缓冲区
MSComm1.OutBufferCount = 0 '清空传输缓冲区
MSComm1.RThreshold = 1 '产生MSComm事件
MSComm1.InBufferSize = 1024
MSComm1.PortOpen = True
End Sub

Private Sub MSComm1_OnComm() '接收数据
Dim BytReceived() As Byte
Dim strBuff As String
Select Case MSComm1.CommEvent
Case 2
MSComm1.InputLen = 0
strBuff = MSComm1.Input
BytReceived() = strBuff
Dim i As Integer
For i = 0 To UBound(BytReceived) '接收数据处理为16进制
If Len(Hex(BytReceived(i))) = 1 Then
strData = strData & "0" & Hex(BytReceived(i))
Else
strData = strData & Hex(BytReceived(i))
End If
Next
Text1 = strData
'数据处理代码
End Select
End Sub

此外你叙述的协议有几点疑问:
应答:
1)当指令得到正确执行时,应答
[ACK] [LB] [CMD] [DF] [CS]
[ACK] = 0X16 命令正确
[LB] 紧接字节长度不包括CS
[CMD] 命令号
[DF] 所带参数项,可选项
[CS] CS=-(ACK +LB+CMD+DF) 此句如何解释?
2) 查询测量结果
发送:11 01 01 ED
应答:[ACK] 05 01 (CO) (CO2) (CH4) (O2) [ST1] [ST2] [CS]

01 (CO) (CO2) (CH4) (O2) [ST1] [ST2]字节总长为11
为何[LB]返回值为[05]

863

社区成员

发帖
与我相关
我的任务
社区描述
VB COM/DCOM/COM+
c++ 技术论坛(原bbs)
社区管理员
  • COM/DCOM/COM+社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧