新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 基于RS-485总线的温湿度监测系统——(RS485总线系统应用之5)

基于RS-485总线的温湿度监测系统——(RS485总线系统应用之5)

作者:时间:2016-12-15来源:网络收藏
1.前言

伴随着计算机技术的进步,计算机与智能化仪器仪表之间的串行通讯接口也得到了同步发展。众所周知,早期的RS-232接口,只能完成单点对单点的单向通讯。后来诞生的RS-422接口,可以完成单点对多点的单向通讯。再后来诞生的RS-485接口,可以完成单点对多点的双向通讯。由于RS-485接口的先进性,迅速在工农业各领域得到了普及应用。本文介绍的温湿度监测系统,就是在RS-485总线架构下,由计算机主机和若干个带RS-485接口的温湿度表构成的。该系统可以对32至128点的温湿度进行实时监测。

本文引用地址:http://www.eepw.com.cn/article/201612/330199.htm

2.硬件系统的设计

2.1硬件系统设备的选型

作为硬件系统的主角——计算机,应选择奔腾4以上的台式计算机,操作系统应选择安装Windows2000或Windows XP或更高。温湿度表应选择壁挂式且带RS-485接口的,最好是220V交流供电。如选用电池供电的,需要经常检查和更换电池,还会频发因电解质泄漏而腐蚀电路的故障,增加应用时期的维护工作量。此外,还需要一个RS-232/485转换器组网用的电缆线应采用带屏蔽线的RS-485专用双绞线电缆。

2.2基于485总线的硬件系统结构

由RS-485接口设备构成的网络,一般应采用一线到底的总线结构,不支持星形或树形等复杂的网络。各温湿度表安装地点与485总线的距离应尽量短。否则,将增加分支引线中的反射信号对总线信号的影响,造成通讯数据出错。由于计算机只配备1~2个RS-232串行接口,需要在RS-232接口处串接一个RS-232/485转换器。如果总线的长度大于300米时,应在485总线的起点和终点处的AB两线之间并接120Ω电阻,以实现总线的阻抗匹配

普通的带RS-485接口的设备,接入485总线的数量通常不能大于32个,带加强型芯片的设备可以接入128个或更多。图1是由32个设备组成的温湿度监测系统的组网结构图。

图1

3.软件系统的设计

软件系统采用VB6设计。为了保证软件系统能够不断升级,在设计系统框架时,应该对今后可能需要增加的功能模块留出扩充余地。本系统的框架结构如下所示:


3.1软件系统各界面的设计

软件系统启动时,首先显示一个欢迎界面,停留若干秒后自动转入主程序界面。如图2、图3所示。


图2



图3

各功能模块的显示界面主要有“查询温湿度数据”界面、“系统参数设置”界面和“串口调试”界面,参见图4、图5、图6。


图4


图5、图6

3.2定时读写各温湿度表数据的程序设计

在软件系统各功能模块中,最核心的部分就是定时读写各温湿度表的温湿度数据。因此,下面将该模块的程序清单详细列出。

Private Declare Function timeGetTime Lib "winmm.dll" () As Long

Public btLoCRC As Byte, btHiCRC As Byte, t1 As Long

Public WPath1 As String, WPath2 As String, WFilename1 As String, WFilename2 As String, WFilename3 As String

Public RoomNumber As String, CommNumber As String, Baudrate As String, ReadT As String, WriteT As String

Public IntMinute1 As Integer, IntMinute2 As Integer, ReadTval As Integer, WriteTval As Integer

Public Rnumber As Integer, ii As Integer, i As Integer, j As Integer, k As Integer, Crc

Dim RoomAddress(32), Roomname(32) As String, TemperatureData(32), HumidityData(32)

Private Sub ReadFiles()’读系统运行参数子程序

Open "D:Program FilesTmeasurewsboot.txt" For Input As #1 Len = 32

Input #1, WPath1, WPath2

Input #1, WFilename1, WFilename2, WFilename3

Input #1, RoomNumber, CommNumber, Baudrate, ReadT, WriteT

For i = 1 To Val(RoomNumber)

Input #1, RoomAddress(i), Roomname(i)

Form2.Frame1(i - 1).Caption = Roomname(i) & "(地址" & RoomAddress(i) & ")"

Next i

Close #1

End Sub

Private Sub Form_Load()’主窗口程序

Me.BorderStyle = 1

Me.Height = 6660’设定窗口高度

ReadFiles

Data1.DatabaseName = WPath1 & WFilename1 & WFilename2 & ".mdb"

Data1.RecordSource = "温湿度数据"

Rnumber = Val(RoomNumber)

ReadTval = Val(ReadT)

WriteTval = Val(WriteT)

IntMinute1 = Val(ReadT)

With MSComm1’打开串口

If .PortOpen = False Then

.CommPort = Val(CommNumber)’指定使用的串口

.Settings = Baudrate & "N,8,1"

.NullDiscard = False’和下一句配合使之可以发送0(零)字符

.InputMode = comInputModeBinary’发送二进制数值(=comInputModeText发送字符)

.InputLen = 8 + 1’一次性从接收缓冲区中读取所有数据(8个字节为一组)

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

.OutBufferCount = 0’清空发送缓冲区

.SThreshold = 8’设置成发送8个字节就产生OnComm事件

.RThreshold = 5 + 2 * 2’设置成接收9个字节就产生OnComm事件

.InBufferSize = 1024

.OutBufferSize = 1024

.PortOpen = True

Else

MsgBox "串口已经打开"

End If

End With

Timer1.Interval = 1000

Timer1.Enabled = True

End Sub

Private Sub Timer1_Timer()’定时读各温湿度表数据

Timer1.Enabled = False

Dim tbisend(7) As Byte

Dim strTempFile As String, m As Integer

Dim conn As New ADODB.Connection

If MSComm1.PortOpen = True Then

For k = 1 To Rnumber

ii = k

tbisend(0) = "&h" + Hex(k)’被呼叫子机的地址码

tbisend(1) = "&h" + Hex(4)’4是读寄存器的功能码

tbisend(2) = "&h" + Hex(0)’被读寄存器的起始地址高字节

tbisend(3) = "&h" + Hex(0)’被读寄存器的起始地址低字节

tbisend(4) = "&h" + Hex(0)’一次读寄存器的个数的高字节

tbisend(5) = "&h" + Hex(2)’一次读寄存器的个数的低字节

Crc = CRC16(tbisend, 6, btLoCRC, btHiCRC)

tbisend(6) = "&h" + Hex(btLoCRC)’CRC低位

tbisend(7) = "&h" + Hex(btHiCRC)’CRC高位

If MSComm1.PortOpen = False Then MSComm1.PortOpen = True

MSComm1.Output = tbisend’发送数据

t1 = timeGetTime

While timeGetTime < t1 + 40’延时的循环等待(延时40毫秒,控制精度1毫秒)

DoEvents’以便接收到被呼叫的从机发来的数据

Wend

MorphDisplay1(k - 1).Value = TemperatureData(k)

MorphDisplay2(k - 1).Value = HumidityData(k)

Next k

IntMinute2 = Val(Right(Time, 2))

If IntMinute2 < IntMinute1 Then

WriteTval = WriteTval – 1

If WriteTval = 0 Then

Data1.Refresh

If Data1.Recordset.EOF = False Then Data1.Recordset.MoveLast

If conn.State = adStateOpen Then conn.Close’向温湿度数据库文件写入测量数据

conn.ConnectionString = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " & WPath1 & WFilename1 & WFilename2 & ".mdb; Mode = ReadWrite; Persist Security Info = False"

conn.Open

s1 = "Insert Into温湿度数据(日期,时间,1温,1湿,2温,2湿,3温,3湿,4温,4湿,5温,5湿,"

s2 = "6温,6湿,7温,7湿,8温,8湿,9温,9湿,10温,10湿) Values "

s3 = "(#" & Date & "# ,#" & Time & "#," & TemperatureData(1) & "," & HumidityData(1) & ","

s4 = "" & TemperatureData(2) & "," & HumidityData(2) & "," & TemperatureData(3) & ","

s5 = "" & HumidityData(3) & "," & TemperatureData(4) & "," & HumidityData(4) & ","

s6 = "" & TemperatureData(5) & "," & HumidityData(5) & "," & TemperatureData(6) & ","

s7 = "" & HumidityData(6) & "," & TemperatureData(7) & "," & HumidityData(7) & ","

s8 = "" & TemperatureData(8) & "," & HumidityData(8) & "," & TemperatureData(9) & ","

s9 = "" & HumidityData(9) & "," & TemperatureData(10) & "," & HumidityData(10) & ")"

conn.Execute s1 & s2 & s3 & s4 & s5 & s6 & s7 & s8 & s9

conn.Close

End If

WriteTval = Val(WriteT)

End If

End If

End If

Timer1.Interval = ReadTval

Timer1.Enabled = True

End Sub

Private Sub MSComm1_OnComm()’接收各温湿度表数据程序

Dim TemperatureData6 As String, HumidityData6 As String

Dim INByte() As Byte

If MSComm1.CommEvent = comEvReceive Then’如有接收事件发生则......

INByte = MSComm1.Input

If INByte(0) = ii And INByte(1) = 4 Then’如果收到的地址码=被叫从机并且功能码=读寄存器,

’则将收到的CRC码与收到数据计算出的CRC码比较

Crc = CRC16(INByte, UBound(INByte) - LBound(INByte) - 1, btLoCRC, btHiCRC)

If INByte(UBound(INByte) - 1) = btLoCRC And INByte(UBound(INByte)) = btHiCRC Then ’如校验正确则转换

TemperatureData6 = Hex(INByte(3)) & Format(Hex(INByte(4)), "00")’先转换成十六进制

HumidityData6 = Hex(INByte(5)) & Format(Hex(INByte(6)), "00")

TemperatureData(ii) = Format(Val("&H" & TemperatureData6) / 10, "##0.0")’再转换为十进制

HumidityData(ii) = Format(Val("&H" & HumidityData6) / 10, "##0.0")

End If

End If

MSComm1.InBufferCount = 0’清接收缓存

End If

End Sub

Function CRC16(Data() As Byte, No As Integer, CRC16Lo As Byte, CRC16Hi As Byte) As String’CRC校验函数

Dim CL As Byte, CH As Byte, SaveLo As Byte, SaveHi As Byte

CRC16Hi = &HFF’为16位CRC校验寄存器赋初始值FFFF

CRC16Lo = &HFF

CH = &HA0’为16位CRC校验多项式赋初始值A001

CL = &H1

For i = 1 To No

CRC16Lo = CRC16Lo Xor Data(i - 1)’每一个数据与CRC校验寄存器进行异或

For j = 1 To 8

SaveHi = CRC16Hi

SaveLo = CRC16Lo

CRC16Hi = CRC16Hi 2’高位右移一位

CRC16Lo = CRC16Lo 2’低位右移一位

If ((SaveHi And &H1) = &H1) Then’如果高位字节最右一位为1

CRC16Lo = CRC16Lo Or &H80’则低位字节最左一位补1,否则自动补0

End If

If ((SaveLo And &H1) = &H1) Then’如低位字节最右一位为1,则与CRC校验多项式异或

CRC16Hi = CRC16Hi Xor CH

CRC16Lo = CRC16Lo Xor CL

End If

Next j

Next i

End Function

4.结束语

经过对软件系统的多次修改和完善,本系统已经于2009年10月交付用户使用。受篇幅限制,以上仅扼要介绍了系统的主要设计思路与方法,未能将程序清单全部列出。如果发现本文或在应用中存在错误,欢迎指正。

参考文献:

① 《微型计算机原理与接口技术》中国科学技术大学出版社作者:周荷琴 吴秀清

② 《单片机原理及串行外设接口技术》北京航空航天大学出版社作者:李朝青等

③ 《RS-232串口通信大全》下载网址:http://download.csdn.net/source/2443662



评论


相关推荐

技术专区

关闭