历史上的今天
返回首页

历史上的今天

今天是:2025年01月07日(星期二)

正在发生

2018年01月07日 | 基于Modbus协议的串口通讯程序_RS485总线系统应用

2018-01-07 来源:互联网

本文在遵循Modbus协议的基础上,阐述了Modbus的两种传输模式和串口通讯程序的设计实例,并给出了VB语言的程序清单。

基于Modbus协议的串口通讯程序----Modbus协议简介

MODBUS协议支持传统的RS-232、RS-422、RS-485和以太网设备。许多工业设备,包括PLC,DCS,智能仪表等都在使用Modbus协议作为他们之间的通讯标准。

Modbus 协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。Modbus 协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一控制器请求访问其它设备的过程,如果回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。

基于Modbus协议的串口通讯程序----RS485总线简介

rs-485采用半双工工作方式,支持多点数据通信。rs-485总线网络拓扑一般采用终端匹配的总线型结构。即采用一条总线将各个节点串接起来,不支持环形或星型网络。rs-485采用平衡发送和差分接收,因此具有抑制共模干扰的能力。加上总线收发器具有高灵敏度,能检测低至200mv的电压,故传输信号能在千米以外得到恢复。 有些rs-485收发器修改输入阻抗以便允许将多达8倍以上的节点数连接到相同总线。rs-485最常见的应用是在工业环境下可编程逻辑控制器内部之间的通信。

串口通讯程序设计实例

为了便于理解,下面列举一种采用RTU模式通讯的应用实例。这个实例的硬件由一台计算机和分布在10个房间的10块温湿度表组成RS485网络架构。温湿度表的地址分别设定为01H至0AH。计算机读各温湿度表数据的命令消息帧包含8个字节:被点名的温湿度表接收到上述命令消息后,向计算机发送温湿度数据,该消息帧包含11个字节:

VB语言设计的上述实例的串口通讯程序清单

Private Declare FuncTIon TImeGetTIme Lib “winmm.dll” () As Long

Public btLoCRC As Byte, btHiCRC As Byte, t0 As Long, t1 As Long, t2 As Long, t3 As Long

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

Dim TemperatureData(10), HumidityData(10)

Private Sub Form_Load()

Me.Height = 6660

Rnumber = 10 ‘房间数量(每个房间装1块温湿度表)

ReadT = 10 ’每10秒读一轮温湿度表数据

If MSComm1.PortOpen = True Then MSComm1.PortOpen = False ‘如果串口1是打开状态则关闭它

With MSComm1 ’设置串口参数

.CommPort = 1 ‘指定使用串口1

.SetTIngs = “9600,N,8,1” ’波特率9600bit/s,无校验,8个数据位,1个停止位

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

.InputLen = 50 ’从接收缓冲区中可一次性读取的数据个数

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

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

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

.InBufferSize = 512 ’设置接收缓存区容量

.OutBufferSize = 512 ‘设置发送缓存区容量

MSComm1.PortOpen = True ’打开串口1

End With

Timer1.Interval = 100 ‘定时器1定时100毫秒

Timer1.Enabled = True ’定时器1开始计时

End Sub

Private Sub Timer1_Timer() ‘定时发送(读数据的)命令

Timer1.Enabled = False ’定时器1停止计时

t0 = timeGetTime ‘从系统取得当前 (开始读温湿度表) 时刻

Dim tbisend(7) As Byte ’定义发送数据的数组

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(0)~tbisend(5)的CRC校验值

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 + 100 ’延时等待100毫秒,以便有足够时间接收从机发来的数据

DoEvents

Wend

Text1(k - 1).Value = TemperatureData(k) ‘显示温度值

Text2(k - 1).Value = HumidityData(k) ’显示湿度值

Next k

End If

t2 = timeGetTime ‘从系统取得当前 (结束读温湿度表) 时刻

t3 = t2 - t0 ’算出读温湿度表的耗时

Timer1.Interval = ReadT * 1000 - t3 ‘定时器1定时,如果不减去T3,会使读周期变长

Timer1.Enabled = True ’定时器1开始计时

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) ’计算收到数据的CRC校验值

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

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

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

CRC16Lo = &HFF

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

CL = &H1

For i = 1 To No

CRC16Lo = CRC16Lo Xor Data(i - 1) ‘将被校验的每个字节数据依次与CRC校验寄存器进行异或

For j = 1 To 8 ’8次移位

SaveHi = CRC16Hi

SaveLo = CRC16Lo


CRC16Hi = CRC16Hi \ 2 ‘高位右移一位

CRC16Lo = CRC16Lo \ 2 ’低位右移一位

If ((SaveHi And &H1) = &H1) Then ‘如果高位字节最右一位为1,则低位字节最左位补1,否则补0

CRC16Lo = CRC16Lo Or &H80

End If

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

CRC16Hi = CRC16Hi Xor CH

CRC16Lo = CRC16Lo Xor CL

End If

Next j

Next i

End Function

推荐阅读

史海拾趣

AMICC [AMIC TECHNOLOGY]公司的发展小趣事

随着产品线的不断丰富和技术实力的不断提升,AMICC开始积极拓展国内外市场。公司通过与大型电子企业建立战略合作关系,成功打入国际市场。同时,AMICC还积极参加各类行业展会和交流活动,提升品牌知名度和影响力。在市场拓展的过程中,AMICC始终坚持客户至上的原则,为客户提供优质的产品和服务,赢得了客户的信任和好评。

FCT electronic公司的发展小趣事

在电子行业的初期,FCT electronic公司由一群富有远见和激情的工程师创立。他们看到了挠性电路板在未来电子产品中的巨大潜力,并致力于研发出更高效、更可靠的挠性电路板解决方案。经过数年的不懈努力,FCT electronic公司终于研发出了具有革命性意义的挠性电路板技术,这一技术为公司在行业中树立了良好的口碑,也为公司的后续发展奠定了坚实的基础。

Dongguan Jingyue Electronics Co Ltd公司的发展小趣事

在电子行业的激烈竞争中,Dongguan Jingyue Electronics Co Ltd始终将技术创新作为公司发展的核心驱动力。公司自成立之初就投入大量资源用于研发新技术和新产品。通过不断的努力,公司成功推出了一系列具有市场竞争力的电子产品,赢得了消费者的广泛认可。这些技术创新不仅提升了公司的品牌形象,也为公司带来了丰厚的利润。

EPIGAP公司的发展小趣事

EPIGAP公司的创始人李先生在半导体领域拥有深厚的技术背景。在公司初创时期,他带领研发团队成功研发出一种新型的高性能芯片,该芯片在功耗和性能上均达到了行业领先水平。这一技术突破使得EPIGAP公司在激烈的市场竞争中脱颖而出,迅速获得了众多客户的青睐。凭借这一产品,EPIGAP成功打开了市场,为后续的发展奠定了坚实的基础。

FEIG ELECTRONIC公司的发展小趣事

FEIG ELECTRONIC成立于1978年,作为德国射频识别(RFID)系统的先驱,公司从一开始就专注于RFID技术的研发与制造。在创立初期,FEIG凭借其独特的技术视角和对市场需求的敏锐洞察,成功开发了一系列RFID系统,为物流、零售等行业提供了有效的解决方案。通过不断的技术创新和市场拓展,FEIG逐渐在RFID领域崭露头角。

GeneSiC Semiconductor公司的发展小趣事

Digi-Key作为全球知名的电子元器件分销商,与FEIG ELECTRONIC建立了长期稳定的合作关系。通过这一合作,Digi-Key为FEIG提供了全球范围内的分销服务,将FEIG的产品推向了更广阔的市场。同时,Digi-Key还为FEIG的产品提供了专业的技术支持和售后服务,进一步巩固了FEIG在RFID领域的领先地位。

问答坊 | AI 解惑

鉴别真代理、假代理的方法

看它的业务介绍,如果说同时代理几家相互竞争的产品的,肯定是假的。 如网上说什么代理EMC,SONIX,十速等等的,100%是假的。…

查看全部问答>

arm开发板的调试串口能改变吗?

rt 2410的串口0是完备串口,我们想用它做别的用途 但是它默认是超级终端的调试串口, 我能不能通过修改bootloader来改变它,就是把串口0释放出来,使用串口1作为超级终端的调试串口啊? 多谢…

查看全部问答>

能具体讲下虚拟串口实现的过程不?

看了一个多星期的驱动程序开发 然后从网上下了不少资料,看了不少 现在对虚拟串口大概有个了解 但也不是很清楚,希望做过的能给个思路!~~ 注册表和驱动程序之间的联系... 是通过添加注册表实现虚拟串口,还是直接 通过驱动程序虚拟一个串口使用?…

查看全部问答>

DATA FLASH的读写程序找人开发

一个DATA FLASH的读写程序找人开发,就是通过COM口吧数据写到板子的闪存(DATAFLASH)上,,要有开发经验 详情:http://www.xinet.com.cn/123/index.html 联系13870920010张先生,QQ:123013020…

查看全部问答>

串口下载问题

我用的IAR5.4编译,j-link仿真器下载没有问题. 但用串口下载芯片能联上,万利那个说下载返回码错误,ST那个下载也不行,但我用同事另外的产品HEX文件能下载,不知是什么问题?…

查看全部问答>

ATmega169V驱动段码LCD液晶片的困惑

ATmega169V驱动段码液晶片,电压5V,取1/3Bias,60Hz, 在静态有部分显示,1/2duty、1/3duty、1/4duty都没有显示,可能是什么原因? 初始化如下: LCDCRB=0x30; LCDFRR=0x66; LCDCCR=0x0F; 。。。。。 LCDCRA=0x80;…

查看全部问答>

【求助】高频预加重电路分析

如图,求高手帮分析一下箭头所指的右边电路的工作方式,电容C2是高频信号的正向通路还是反馈网络的一部分?如果是反馈网络,那C2的作用是什么呢? R1,C1是滤波器是肯定的。…

查看全部问答>

哪位提供一下LPC810下载电路?

我已经拿到LPC810的板子了 可是在下载程序的时候遇到了一些问题; 我用的是一个232的ISP下载串口板; 软件用的是Flash Magic 读取芯片ID正常; 擦除Flash正常; 但是不能往里写入程序; 总是卡在这里,不能往下进行; 有哪个大虾遇到过这 ...…

查看全部问答>

请问ccs v5如何安装MSP-FET430UIF驱动?

得到一个写着MSP-FET430UIF的烧写器,连接到电脑显示驱动安装好了。但是我的ccs中device connection中没有显示这个,只有USB。请问如何安装使用?…

查看全部问答>

关于GPS和GSM模块的定位。

我想问下论坛的大神,我现在在把GPS的经纬度可以定位发送到GSM模块中,在手机显示是经纬度。。我想的是,可以显示当前的所在地址或者是地图的连接。。打算用GSM模块的GPRS,但感觉好像不行,因为还是要电脑操作。。请问大神们,怎么可以发送信息的 ...…

查看全部问答>