Modbus协议规范V1.01_第1页
Modbus协议规范V1.01_第2页
Modbus协议规范V1.01_第3页
Modbus协议规范V1.01_第4页
Modbus协议规范V1.01_第5页
免费预览已结束,剩余31页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

目录Modbus协议介绍1主从机状态图及编程2存储的数据结构及地址分配12具体帧格式描述13具体功能代码描述14后续待完善问题30参考文献30附录30Modbus协议介绍Modbus串行链路协议是一个主-从协议。在同一时刻,只有一个主节点连接于总线,一个或多个子节点 (最大编号为 247 ) 连接于同一个串行总线。Modbus通信总是由主节点发起。子节点在没有收到来自主节点的请求时,不会发送数据。子节点之间也不会互相通信。如果从机之间要求通信,只能通过主机进行转送传输。本协议不支持该模式,即不容许从机间通信(以后可以进行改进)。主节点在同一时刻只会发起一个Modbus事务处理。Modbus协议有两只两种串行传输模式:RTU 模式 和 ASCII 模式。RTU模式在相同的波特率下比ASCII 模式有更高的吞吐率。本协议采用RTU模式。主机向从机请求有两种请求模式:广播模式和单播模式。广播模式下从机不返回响应。单播模式下主机发送请求,被寻址从机在处理该请求后返回响应。占用的硬件资源从机:串行通信口1个、8位或16位定时器1个、RTC或秒定时器1个。主机:串行通信口1个、8位或16位定时器2个、RTC或秒定时器1个。帧的简单描述Modbus协议定义了一个与基础通信层无关的简单协议数据单元(PDU)。在特定总线或网络上的Modbus协议映射能够在应用数据单元(ADU)上引入一些附加域。本协议无附加域。图 1 通用Modbus协议帧地址域包含要寻址的从机地址,也可为广播地址。功能代码表示从机要执行何种操作,数据段为操作提供数据。差错校验码可以提高通信的可靠性。一般为CRC校验。通信模式:查询回应周期 Modbus没有握手机制,主机直接发送操作代码,从机立刻回应。(1)查询查询消息中的功能代码告之被选中的从机要执行何种功能。数据段包含了从机要执行功能的任何附加信息。例如功能代码03是要求从机读保持寄存器并返回它们的内容。数据段必须包含要告之从机的信息:从何寄存器开始读及要读的寄存器数量。错误检测域为从机提供了一种验证消息内容是否正确的方法。(2)回应如果从机产生一正常的回应,在回应消息中的功能代码是在查询消息中的功能代码的回应。数据段包括了从机收集的数据:像寄存器值或状态。如果有错误发生,功能代码将被修改以用于指出回应消息是错误的,同时数据段包含了描述此错误信息的代码。错误检测域允许主机确认消息内容是否可用。正常的通信如图2所示。图2 无差错事务处理如果从机收到异常信息,则返回从机地址、 差错码(设置该原始功能码的最高有效位为逻辑1)及异常码,具体见图3图3 异常事务处理在主机中应有定时控制,如果主机在1秒内没有收到相应从机的响应,则主机再重复发送两次相同请求代码,三次都没有相应响应则报告通信异常(三次收到数据但CRC校验错误也报告通信异常)。对于主机而言,事先应约定好地址范围,将并地址放到地址池中。如果不知道从机地址范围,则地址池中地址的从1到247都有。对于报告通信异常的地址可以将其从地址池中剔除,以后不再寻址该从机。(需要考虑的一点为在主机在寻址某个从机时刚好该从机故障或断电,无法应答,之后从机恢复,但主机会无法跟该从机通信,因地址池中无该从机地址)。主从机状态图及编程主机状态图图 4 主节点状态图对上面的状态图的一些解释:u 状态“空闲”=无等待的请求。这是电源上电后的初始状态。只有在“空闲”状态请求才能被发送。发送一个请求后,主节点离开“空闲”状态,没有回到“空闲”时不能发送第二个请求。u 当单播请求发送到一个子节点,主节点将进入等待应答 状态,同时一个临界超时定时启动。这个超时称为“响应超时”。它避免主节点永远处于“等待应答”状态。如果出现响应超时,则再次发送上一次信息。连续三次出现响应超时,则报告通信异常。响应超时为1s。u 当收到一个应答时,主节点在处理数据之前检验应答。在某些情况下,检验的结果可能为错误。如收到来自非期望的子节点的应答,或接收的帧错误。在收到来自非期望子节点的应答时,响应超时继续计时;当检测到帧错时,可以执行一个重试。u 帧错误包括1) 对每个字符的奇偶校验;2) 对整个帧的CRC校验。u 在单播方式,响应超时必须设置到足够的长度以使任何子节点都能处理完请求并返回响应。而广播转换延迟必须有足够的长度以使任何子节点都能只处理完请求而可以接收新的请求。因此,转换延迟应该比响应超时要短。u 当广播请求发送到串行总线上,没有响应从子节点返回。主节点需要进行延迟以便使子节点在接收新的请求处理前完成当前请求。该延迟被称作“转换延迟”。因此,主节点在返回 “空闲”状态之前,应先到“等待转换延迟”状态。转换延迟为200ms。u 两次发送请求的时间间隔必须大于T3.5。u 连续出现三次通信异常则提示与某从机通信错误,并将该从机从地址池中删除。一次通信成功则将通信异常计数器清零。通信异常包括:响应超时,帧检测错误。u 如果收到异常功能代码,在上位机应显示相应提示。但该次通信被认为是成功的。从机状态图图 5 从机状态图对上面的状态图的一些解释:u 状态“空闲”= 没有等待的请求。这是电源上电后的初始状态。在响应完应答后也回到“空闲”状态。u 如果子节点在接收到的帧中检测到错误(奇偶校验错误,CRC校验错误,图中表示为请求数据有错), 则没有响应返回到主节点。u 当收到一个请求时,子节点在处理请求中要求的动作前检验报文包。当检测到错误时(注意跟上面的错误相区别,图中表示为处理时出错),必须向主节点发送应答。不同的错误可以发生于:请求的格式错,非法动作, 具体的可能错误见功能代码异常类型介绍。u 当要求的动作完成后,单播报文要求必须格式化一个应答并发往主节点。如果要求的动作完成时间超过响应超时,则应发送确认异常码。确认异常码介绍见。u 如果在广播模式下,要求在收到请求后完成处理的时间在转换延迟时间内。u 为防止非寻址从机在接收中断中停留过长时间,从机每次进入接收中断先判断是否寻址本机,不是则快速退出中断。具体流程图见接收中断流程图。u 更为具体的程序流程图见附录。从机事务处理流程图图6 从机事务处理流程图对上面的状态图的一些解释:u 只有从机在奇偶校验、CRC校验通过了才进行该处理请求处理,为确保操作的正确进行,对该处理进行了一些判断,出现异常则响应相应的异常代码。u 根据处理结果,可以建立两种类型响应:l 正常响应:响应功能码 = 请求功能码l 异常响应(参见第6.14节):用来为客户机提供处理过程中与被发现的差错相关的信息;响应功能码 = 请求功能码 + 0x80;提供一个异常码来指示差错原因。u 在实际的从机事务处理中,确认操作码是在接收完一帧后马上判断的,从确认信息以后都是在相应功能代码处理中进行判断的。传输模式及定时控制图 7 传输模式状态图上面状态图的一些解释:u “空闲”是没有发送和接收报文要处理的正常状态。u 当总线没有活动的传输的时间间隔达3.5 个字符长时,通信链路被认为在 “空闲” 态。u 当总线空闲时,在总线上检测到的任何传输的字符被识别为帧起始。总线变为“活动”状态。然后,当总线上没有字符传输的时间间个达到t3.5后,被识别为帧结束。u 检测到帧结束后,完成CRC 计算和检验。然后,分析地址域以确定帧是否发往此设备,如果不是,则丢弃此帧。为了减少接收处理时间,地址域在一接收到就分析,而不需要等到整个帧结束。这样,CRC 计算只需要在帧寻址到该节点 (包括广播帧) 时进行。u 开始到“空闲”的t3.5 的定时控制不使用定时器来实现,因单片机上电初始化占用时间大于t3.5。u 在发送时,其t3.5定时由接收程序来保证,因为只有在大于t3.5时才判断为帧结束,即使马上发送也可以保证两帧之间的t3.5定时要求。u 对于从机,为减少在接收中断的停留时间,地址域可以在帧开始就分析,如果不是寻找本机,将地址匹配标志位清零,以后每次进入接收中断都马上退出。当检测到帧结束时才将地址匹配标志位置位。这样,CRC 计算只需要在帧寻址到该节点 (包括广播帧) 时进行。具体流程图接收中断程序流程图图 8 接收中断流程图上面程序流程图的一些说明:u 主程序初始化时,地址匹配标志位、帧启动标志位都是置位的。T3.5超时表示帧结束,此时关闭T1.5和T3.5定时,地址匹配标志位、帧启动标志位置位,以便下次进入接收中断对帧地址是否匹配和是否开启定时器判断。接收计数器也应在帧结束时清零。u 为减少在接收中断的停留时间,开始就对帧的地址进行判断,如果不是寻找本机,将地址匹配标志位清零,以后每次进入接收中断都马上退出。当检测到帧结束时才将地址匹配标志位置位,准备对下一帧的地址进行判断。这样,只有被寻址的从机才在接收中断中停留较长时间。u 为节约定时器,可以将T1.5和T3.5的定时采用同一个定时器,其基本定时时间为1.75个字节时间。u 定时器在帧启动时开启,T3.5超时中断中将其关闭。u 当广播时,只是将广播标志位置位,等待T3.5超时中断将帧完成标志位置位,在帧处理中处理广播。T3.5、T1.5定时中断程序流程图图9 定时器中断流程图上面程序流程图的一些说明:u 定时器只采用一个。一次基本定时为1.75个字节时间,根据接收到的字节计数器的值区别T1.5和T3.5,正常帧的在T1.5和T3.5时接收计数器的值应该是相同的。如果帧内两个字节的时间间隔超过T1.5,则在T1.5和T3.5时接收计数器的值肯定是不一样的,此时将丢弃帧标志位置位。u T3.5超时时,应将定时器关闭,否则处理完该帧在没有接受新的帧也会进入定时中断修改一些全局变量。帧长度就是此时的接收字节计数器的值。地址匹配标志位、帧启动标志位、接收字节计数器清零,为开始下一帧的接收做准备。主机帧处理中断及T3.5、T1.5定时主机与从机相同,见图8、图9。在主机中还有响应超时控制,需要共用实时时钟(RTC)或定时器来实现。图10 主机帧处理流程图上面状态图的一些解释:u 本程序流程图为主机的全部流程图,在具体实现是可以将帧动作前的相应检查作为一个函数来实现。发送部分为一个函数。u 执行帧的动作前应检查是否满足:1)帧内字节间时间小于T1.5,2)CRC校验是否正确,3)功能代码是否超限。u 功能代码范围应包括表2所示的正常代码及相应高位置1的异常代码。u 上述检查正确后,根据要求从机响应数据的要求来处理接收数据。具体实现要根据需要来编写。需要注意的一点是从机可能会返回异常代码,故每个功能代码处理时要求有异常代码的判断。u 如果上述检查错误,则推出处理程序,等待超时中断处理。u 在发送时,需要判断是广播模式还是单播模式,广播模式下要求开转换延时计数器并关闭接收中断,而单播模式不需要。u 接收处理时,广播模式从机没有数据响应,故没有广播模式的处理。超时定时中断及延迟超时中断处理 图11 超时中断处理 图12 延迟超时中断处理从机帧处理流程图:中断及T3.5、T1.5定时主机与从机相同,见图8、图9。图13 从机帧处理流程图上面状态图的一些解释:u 执行帧的动作前应检查是否满足:1)帧内字节间时间小于T1.5,2)CRC校验是否正确,3)功能代码是否超限。u 上述检查正确后,在根据功能代码执行各个操作前还应检查操作的寄存器地址范围是否超限。如果超限则返回地址异常代码。u 所有检查正确并在相应操作成功执行完成后发送响应。如果完成操作时间大于响应超时,则响应确认异常代码。u 在广播模式下,从机不响应,且执行广播的动作要求在转换延迟(200ms)内完成。u存储的数据结构及地址分配采用独立的存储地址,即每个块的数据与其他数据块的地址是分离的。数据分为四个块,分别为:开关量输入、开关量输出、保存寄存器、输入寄存器,见图14。图14 数据结构及存储地址分配其中,开关量的输入只是输入量,即它是只读的。开关量输出为可读可写,读表示现在当前开关量输出的状态,写为开关量的输出。输入寄存器为模拟量的输入,保持寄存器读为各配置变量的寄存器的值,写则对各变量进行配置。表1 数据类型及说明类型操作数据类型访问类型备注开关量输入单字节只读开关量的输入开关量输出单字节读写读为当前开关量的的状态(线圈状态),写为开关量的输出保持寄存器2字节读写模拟量、单片机内部寄存器的、单片机内部变量的配置输入寄存器2字节只读模拟量的输入、各种不可配置的输入量对于模拟采集板卡,其地址作以下约定:u 输入寄存器的地址0x0180-0x01A0为16路模拟量的原始的采集值。每个地址对应两个字节数据,每路模拟量的占用两个地址,其采样值为32位(高位不足用0填充),高16位占用第一个地址,低16位占用第二个地址,每个地址的数据也是高位在前。例如,某路模拟量的采集值为0x123456,则发送为0x00,0x12,0x34,0x56。在软件中保证每次模拟量的地址是偶数,如果出现奇数(不管是起始地址还是地址个数),则响应数据地址异常代码。u 保持寄存器地址分配为:0x01000x010F为16路模拟量通道配置,每路模拟量对应一个地址,可以对该地址写表示配置该通道,读则返回该通道现有配置值。其余应用可以根据具体需要自定义地址。具体帧格式描述单个字符传输:1个起始位(0),8个数据位,1个奇偶校验位(用停止位填充),1个停止位(1)。图15 单字节比特流帧格式:图 16 帧格式地址、功能代码、数据的发送都采取大端模式,当一个数据大余两个字节时,都是高位在前,低位在后。CRC校验码是低位在前,高位在后。地址:地址0 保留为广播地址。主机没有地址。每个从机分配一个地址(范围1-247),该地址必须在 Modbus串行总线上唯一。在该串行总线上最多可以挂载247个从机。功能代码:Modbus包括三类功能代码:公共的,用户自定义的及保留的。在本协议中只采用部分公共功能代码。具体的见P14的具体功能代码描述。CRC(循环冗余校验)校验:为保证帧的可靠传输,采用CRC校验。CRC 域检验整个帧的内容。不管报文有无奇偶校验,均执行此检验。(奇偶校验为一个字节的内部的校验,一般为单片机内部硬件完成)。每次发送节点在发送前将将该帧的所有字节进行CRC计算,将16位结果放到该帧的结尾(低位在前),接收节点在接收到该帧后对除CRC校验码的所有字节进行CRC计算,再将该结果与接收帧中的CRC码进行比较,如果一致则传输无误,进行接收处理。如果不一致则什么也不做,等待接收下一帧数据。具体的CRC校验原理及算法见附录。帧间定时控制:每一帧之间的时间间隔应大于T3.5(3.5个字符时间)。如果小于T3.5,则认为还是上一帧的数据。只有在总线空闲时间大于T3.5时,才判定该帧结束,可以对该帧进行处理。帧内的两个字符之间的间隔应小于T1.5(1.5个字符时间)。如果大于T1.5,则该帧被认为不完整帧,应该被接收节点丢弃,但此时接收节点还是继续接收该帧的数据,直到出现T3.5超时才将该帧丢弃,并准备接收下一帧数据。图17 帧间定时控制具体功能代码描述表2 功能代码表功能功能码(十六进制)页数据访问单字节访问物理离散量输入读输入离散量020216内部比特读线圈010114或写单个线圈050521物理线圈写多个线圈150F24双字节访问输入存储器读输入寄存器040420内部存储器或物理输出存储器读多个寄存器030318写单个寄存器060623写多个寄存器161026异常代码单字节访问包含异常错误信息具体见表3具体见表3具体见表328l 01 (0x01)读线圈在一个远程设备中,使用该功能码读取线圈的1至2000连续状态。请求PDU详细说明了起始地址,即指定的第一个线圈地址和线圈编号。从零开始寻址线圈。因此寻址线圈1-16为0-15。根据数据域的每个比特将响应报文中的线圈分成为一个线圈。指示状态为1= ON 和0= OFF。第一个数据字节的LSB(最低有效位)包括在询问中寻址的输出。其它线圈依次类推,一直到这个字节的高位端为止,并在后续字节中从低位到高位的顺序。如果返回的输出数量不是八的倍数,将用零填充最后数据字节中的剩余比特(一直到字节的高位端)。字节数量域说明了数据的完整字节数。请求PDU功能码1个字节0x01起始地址2个字节0x0000 至0x007F线圈数量2个字节1至2000(0x7D0)响应PDU功能码1个字节0x01字节数1个字节N*线圈状态N个字节nN或N+1*N输出数量/8,如果余数不等于0,那么 N = N+1错误功能码1个字节功能码0x80异常码1个字节01或02或03或04这是一个请求读离散量输出20-38的实例:请求响应域名(十六进制)域名(十六进制)功能01功能01起始地址Hi00字节数03起始地址Lo13输出状态27-20CD输出数量Hi00输出状态35-286B输出数量Lo13输出状态38-3605将输出27-20的状态表示为十六进制字节值CD,或二进制1100 1101。输出27是这个字节的MSB,输出20是LSB。通常,将一个字节内的比特表示为MSB位于左侧,LSB位于右侧。第一字节的输出从左至右为27至20。下一个字节的输出从左到右为35至28。当串行发射比特时,从LSB向MSB传输: 20 . . . 27、28 . . . 35等等。在最后的数据字节中,将输出状态38-36表示为十六进制字节值05,或二进制0000 0101。输出38是左侧第六个比特位置,输出36是这个字节的LSB。用零填充五个剩余高位比特。注:用零填充五个剩余比特(一直到高位端)。图18 读线圈状态图l 02 (0x02)读离散量输入在一个远程设备中,使用该功能码读取离散量输入的1至2000连续状态。请求PDU详细说明了起始地址,即指定的第一个输入地址和输入编号。从零开始寻址输入。因此寻址输入1-16为0-15。根据数据域的每个比特将响应报文中的离散量输入分成为一个输入。指示状态为1= ON 和0= OFF。第一个数据字节的LSB(最低有效位)包括在询问中寻址的输入。其它输入依次类推,一直到这个字节的高位端为止,并在后续字节中从低位到高位的顺序。如果返回的输入数量不是八的倍数,将用零填充最后数据字节中的剩余比特(一直到字节的高位端)。字节数量域说明了数据的完整字节数。请求PDU功能码1个字节0x02起始地址2个字节0x0080至0x00FF输入数量2个字节1至2000(0x7D0)响应PDU功能码1个字节0x02字节数1个字节N*输入状态N*1个字节*N输出数量/8,如果余数不等于0,那么 N = N+1错误差错码1字节0x82异常码1字节01或02或03或04这是一个请求读取离散量输入197-218的实例:请求响应域名(十六进制)域名(十六进制)功能02功能02起始地址Hi00字节数03起始地址LoC4输入状态204-197AC输出数量Hi00输入状态212-205DB输出数量Lo16输入状态218-21335将离散量输入状态204-197表示为十六进制字节值AC,或二进制1010 1100。输入204是这个字节的MSB,输入197是这个字节的LSB。将离散量输入状态218-213表示为十六进制字节值35,或二进制0011 0101。输入218位于左侧第3比特,输入213是LSB。注:用零填充2个剩余比特(一直到高位端)。图19:读离散量输入的状态图l 03 (0x03)读保持寄存器在一个远程设备中,使用该功能码读取保持寄存器连续块的内容。请求PDU说明了起始寄存器地址和寄存器数量。起始寻址寄存器是从0x0100开始。将响应报文中的寄存器数据分成每个寄存器有两字节,在每个字节中直接地调整二进制内容。对于每个寄存器,第一个字节包括高位比特,并且第二个字节包括低位比特。请求功能码1个字节0x03起始地址2个字节0x0100至0x017F寄存器数量2个字节1至125(0x7D)响应功能码1个字节0x03字节数1个字节2N*寄存器值N*2个字节*N寄存器的数量错误差错码1个字节0x83异常码1个字节01或02或03或04这是一个请求读寄存器0x0108-0x010A的实例:请求响应域名(十六进制)域名(十六进制)功能03功能03高起始地址01字节数06低起始地址08寄存器值Hi(108)02高寄存器编号00寄存器值Lo(108)2B低寄存器编号03寄存器值Hi(109)00寄存器值Lo(109)00寄存器值Hi(110)00寄存器值Lo(110)64将寄存器0x108的内容表示为两个十六进制字节值02 2B,或十进制555。将寄存器0x109-0x10A的内容分别表示为十六进制00 00和00 64,或十进制0和100。图20:读保持寄存器的状态图l 04(0x04)读输入寄存器在一个远程设备中,使用该功能码读取1至大约125的连续输入寄存器。请求PDU说明了起始地址和寄存器数量。从零开始寻址寄存器。因此,寻址输入寄存器1-16为0-15。将响应报文中的寄存器数据分成每个寄存器为两字节,在每个字节中直接地调整二进制内容。对于每个寄存器,第一个字节包括高位比特,并且第二个字节包括低位比特。请求功能码1个字节0x04起始地址2个字节0x0180至0x01FF输入寄存器数量2个字节0x0001至0x007D响应功能码1个字节0x04字节数1个字节2N*输入寄存器N*2个字节*N输入寄存器的数量错误差错码1个字节0x84异常码1个字节01或02或03或04这是一个请求读输入寄存器0x0189的实例:请求响应域名(十六进制)域名(十六进制)功能04功能04起始地址Hi01字节数02起始地址Lo89输入寄存器Hi00输入寄存器数量Hi00输入寄存器Lo0A输入寄存器数量Lo0A将输入寄存器0x0109的内容表示为两个十六进制字节值00 0A,或十进制10。图21:读输入寄存器的状态图l 05 (0x05)写单个线圈在一个远程设备上,使用该功能码写单个输出为ON或OFF。请求数据域中的常量说明请求的ON/OFF状态。十六进制值FF 00请求输出为ON。十六进制值00 00请求输出为OFF。其它所有值均是非法的,并且对输出不起作用。请求PDU说明了强制的线圈地址。从零开始寻址线圈。因此,寻址线圈1为0。线圈值域的常量说明请求的ON/OFF状态。十六进制值0XFF00请求线圈为ON。十六进制值0X0000请求线圈为OFF。其它所有值均为非法的,并且对线圈不起作用。正常响应是请求的应答,在写入线圈状态之后返回这个正常响应。请求功能码1个字节0x05输出地址2个字节0x0080至0x00FF输出值2个字节0xFF00响应功能码1个字节0x05输出地址2个字节0x0080至0x00FF输出值2个字节0xFF00错误差错码1个字节0x85异常码1个字节01或02或03或04这是一个请求写线圈0x0083为ON的实例:请求响应域名(十六进制)域名(十六进制)功能05功能05输出地址Hi00输出地址Hi00输出地址Lo83输出地址LoAC输出值HiFF输出值HiFF输出值Lo00输出值Lo00图22:写单个输出状态图l 06 (0x06)写单个寄存器在一个远程设备中,使用该功能码写单个保持寄存器。请求PDU说明了被写入寄存器的地址。从零开始寻址寄存器。因此,寻址寄存器1为0。正常响应是请求的应答,在写入寄存器内容之后返回这个正常响应。请求功能码1个字节0x06寄存器地址2个字节0x0180至0x01FF寄存器值2个字节0x0000至0xFFFF响应功能码1个字节0x06寄存器地址2个字节0x0180至0x01FF寄存器值2个字节0x0000至0xFFFF错误差错码1个字节0x86异常码1个字节01或02或03或04这是一个请求将十六进制00 03写入寄存器0x0189的实例:请求响应域名(十六进制)域名(十六进制)功能06功能06寄存器地址Hi01输出地址Hi01寄存器地址Lo89输出地址Lo89寄存器值Hi00输出值Hi00寄存器值Lo03输出值Lo03图23:写单个寄存器状态图l 15 (0x0F) 写多个线圈在一个远程设备中,使用该功能码强制线圈序列中的每个线圈为ON或OFF。请求PDU说明了强制的线圈参考。从零开始寻址线圈。因此,寻址线圈1对应的地址为0x0080(注意这是绝对地址)。请求数据域的内容说明了被请求的ON/OFF状态。域比特位置中的逻辑“1”请求相应输出为ON。域比特位置中的逻辑“0”请求相应输出为OFF。正常响应返回功能码、起始地址和强制的线圈数量。请求PDU功能码1个字节0x0F起始地址2个字节0x0080至0x00FF输出数量2个字节0x0001至0x07B0字节数1个字节N*输出值N*1个字节*N输出数量/8,如果余数不等于0,那么 N = N+1响应PDU功能码1个字节0x0F起始地址2个字节0x0000至0xFFFF输出数量2个字节0x0001至0x07B0错误差错码1个字节0x8F异常码1个字节01或02或03或04这是一个请求从地址0x0085开始写入10个线圈的实例:请求的数据内容为两个字节:十六进制CD 01 (二进制1100 1101 0000 0001)。使用下列方法,二进制比特对应输出。比特: 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1地址(HEX):8B 8A 89 88 87 86 85 8D 8C传输的第一字节(十六进制CD)寻址为输出0x0085-0x008B,在这种设置中,最低有效比特寻址为最低输出(0x0085)。传输的下一字节(十六进制01)寻址为输出0x008D-0x008C,在这种设置中,最低有效比特寻址为最低输出(0x008C)。应该用零填充最后数据字节中的未使用比特。请求响应域名(十六进制)域名(十六进制)功能0F功能0F起始地址Hi00起始地址Hi00起始地址Lo85起始地址Lo85输出数量Hi00输出数量Hi00输出数量Lo0A输出数量Lo0A字节数02输出值HiCD输出值Lo01图24:写多个输出的状态图l 16 (0x10) 写多个寄存器在一个远程设备中,使用该功能码写连续寄存器块(1至约120个寄存器)。在请求数据域中说明了请求写入的值。每个寄存器将数据分成两字节。正常响应返回功能码、起始地址和被写入寄存器的数量。请求PDU功能码1个字节0x10起始地址2个字节0x0000至0xFFFF寄存器数量2个字节0x0001至0x0078字节数1个字节2N*寄存器值N*2个字节数据*N寄存器数量响应PDU功能码1个字节0x10起始地址2个字节0x0000至0xFFFF寄存器数量2个字节1至123(0x7B)错误差错码1个字节0x90异常码1个字节01或02或03或04这是一个请求将十六进制00 0A和01 02写入以0x0182开始的两个寄存器的实例:请求响应域名(十六进制)域名(十六进制)功能10功能10起始地址Hi01起始地址Hi00起始地址Lo82起始地址Lo01寄存器数量Hi00寄存器数量Hi00寄存器数量Lo02寄存器数量Lo02字节数04寄存器值Hi00寄存器值Lo0A寄存器值Hi01寄存器值Lo02图25:写多个寄存器状态图l 异常代码:当主机向从机发送请求时,主机希望一个正常响应。从站在事务处理过程中可能会出现下列四种可能事件之一:l 如果从机接收到无通信错误的请求,并且可以正常地处理询问,那么从机将返回一个正常响应。l 如果由于通信错误,从机没有接收到请求,那么不能返回响应。主机程序将最终处理请求的超时状态。l 如果从机接收到请求,但是检测到一个通信错误(奇偶校验、LRC、CRC、.),那么不能返回响应。主机程序将最终处理请求的超时状态。l 如果从机接收到无通信错误的请求,但不能处理这个请求(例如,如果请求读一个不存在的输出或寄存器),从机将返回一个异常响应,通知用户错误的本质特性。异常响应报文有两个与正常响应不同的域:功能码域:在正常响应中,从机利用响应功能码域来应答最初请求的功能码。所有功能码的最高有效位(MSB)都为0(它们的值都低于十六进制80)。在异常响应中,从机设置功能码的MSB为1。这使得异常响应中的功能码值比正常响应中的功能码值高十六进制80。通过设置功能码的MSB,主机的应用程序能够识别异常响应,并且能够检测异常码的数据域。数据域:在正常响应中,从机可以返回数据域中数据或统计表(请求中要求的任何报文)。在异常响应中,从机返回数据域中的异常码。这就定义了产生异常的从机状态。主机请求和从机异常响应的实例:请求响应域名(十六进制)域名(十六进制)功能01功能81起始地址Hi04异常码02起始地址LoA1输出数量Hi00输出数量Lo01在这个实例中,客户机对从机寻址请求。功能码(01)用于读输出状态操作。它将请求地址1245(十六进制04A1)的输出状态。值得注意的是,象输出域(0001)号码说明的那样,只读出一个输出。如果在从机中不存在输出地址,那么从机将返回异常码(02)的异常响应。这就说明从站的非法数据地址。从下页开始异常码的列表。表3 异常代码表MODBUS异常码代码名称含义01非法功能对于从机来说,询问中接收到的功能码是不可允许的操作。这也许是因为功能码仅仅适用于新设备而在被选单元中是不可实现的。同时,还指出从机在错误状态中处理这种请求,例如:因为它是未配置的,并且要求返回寄存器值。02非法数据地址对于从机来说,询问中接收到的数据地址是不可允许的地址。特别是,参考号和传输长度的组合是无效的。对于带有100个寄存器的控制器来说,带有偏移量96和长度4的请求会成功,带有偏移量96和长度5的请求将产生异常码02。03非法数据值对于从机来说,询问中包括的值是不可允许的值。这个值指示了组合请求剩余结构中的故障,例如:隐含长度是不正确的。并不意味着,因为MODBUS协议不知道任何特殊寄存器的任何特殊值的重要意义,寄存器中被提交存储的数据项有一个应用程序期望之外的值。04从站设备故障当从机正在设法执行请求的操作时,产生不可重新获得的差错。05确认与编程命令一起使用。从机已经接受请求,并切正在处理这个请求,但是需要长的持续时间进行这些操作。返回这个响应防止在主机中发生超时错误。从机可以继续发送轮询程序完成报文来确定是否完成处理。06从属设备忙与编程命令一起使用。服务器(或从站)正在处理长持续时间的程序命令。张从机空闲时,主机应该稍后重新传输报文。后续待完善问题主机程序流程图有待验证。提高从机的响应速度。目前从机的响应时间有32300ms,不够快。可以发送浮点数,该数据格式满足IEEE754标准。最好是用16位的浮点数。参考文献1. Modbus协议规范(修改稿)2. Modbus protocol-c.doc附录CRC16校验循环冗余校验 (CRC) 域为两个字节,包含一个二进制 16 位值。附加在报文后面的CRC 的值由发送设备计算。接收设备在接收报文时重新计算 CRC 的值,并将计算结果于实际接收到的CRC 值相比较。如果两个值不相等,则为错误。主机的请求信息和从机的响应信息必须都进过CRC校验。CRC 的计算, 开始对一个16位寄存器预装全1. 然后将报文中的连续的8位子节对其进行后续的计算。只有字符中的8个数据位参与生成CRC 的运算,起始位,停止位和校验位不参与 CRC 计算。CRC 的生成过程中, 每个 8位字符与寄存器中的值异或。然后结果向最低有效位 (LSB) 方向移动(Shift) 1位,而最高有效位 (MSB) 位置充零。 然后提取并检查 LSB:如果LSB 为1, 则寄存器中的值与一个固定的预置值异或;如果LSB 为 0, 则不进行异或操作。这个过程将重复直到执行完8次移位。完成最后一次(第8次)移位及相关操作后,下一个8位字节与寄存器的当前值异或,然后又同上面描述过的一样重复8次。当所有报文中子节都运算之后得到的寄存器中的最终值,就是CRC.生成 CRC 的过程为:1. 将一个 16位寄存器装入十六进制 FFFF (全1). 将之称作 CRC 寄存器.2. 将报文的第一个8位字节与16位CRC寄存器的低字节异或,结果置于CRC 寄存器.3. 将 CRC 寄存器右移1位 (向 LSB 方向), MSB 充零. 提取并检测 LSB.4. (如果LSB 为 0): 重复步骤 3 (另一次移位).(如果LSB 为1): 对CRC 寄存器异或多项式值 0xA001 (1010 0000 0000 0001).5. 重复步骤 3 和 4,直到完成 8 次移位。当做完此操作后,将完成对8位字节的完整操作。6. 对报文中的下一个字节重复步骤2 到5,继续此操作直至所有报文被处理完毕。7. CRC 寄存器中的最终内容为CRC 值.8. 当放置CRC 值于报文时,如下面描述的那样,高低字节必须交换。在程序空间足够的情况下,推荐使用查表方式的实现。该方便比单个位计算速度快得多。将 CRC 放置于报文当16位 CRC (2 个 8 位字节) 在报文中传送时,低位字节首先发送,然后是高位字节。例如, 如果 CRC 值为十六进制1241 (0001 0010 0100 0001):图 26CRC 字节序列图 27 CRC计算流程图XOR = 异或N = 字节的信息位POLY = CRC 16 多项式计算 = 1010 0000 0000 0001(生成多项式 = 1 + x2 + x 15 + x 16)在 CRC 16 中, 发送的第一个字节为低字节.程序代码:单个位计算方式:unsigned int Get_CRC(uchar *pBuf, uchar num) unsigned i,j; unsigned int wCrc = 0xFFFF;for(i=0; inum; i+)wCrc = (unsigned int)(pBufi);for(j=0; j= 1; wCrc = 0xA001; elsewCrc = 1; return wCrc;查询方式:unsigned short CRC16 (unsigned char *puchMsg,unsigned short usDataLen )/*函数unsigned short类型返回 CRC */* puchMsg 用于计算 CRC 的报文*/* usDataLen报文中的字节数*/unsigned char uchCRCHi = 0xFF ;/* CRC 的高字节初始化 */unsigned char uchCRCLo = 0xFF ;/* CRC 的低字节初始化 */unsigned uIndex ;/* CRC 查询表索引 */while (usDataLen-)/* 完成整个报文缓冲区 */uIndex = uchCRCLo *puchMsgg+ ;/* 计算 CRC*/uchCRCLo = uchCRCHi auchCRCHiuIndex ;uchCRCHi = auchCRCLouIndex ;return (uchCRCHi 8 | uchCRCLo) ;高字节表/* 高位字节的CRC 值 */const unsigned char auchCRCHi256 = 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论