发表于:2005-08-21 16:10:00
楼主
请教例子Tip041B(Modbus RTU)的问题
西门子的程序例子Tip041B(S7-214做从站Modbus RTU)中,程序说明中VB3300-VB3359为通信缓冲区,VB3560-VB3575为MODBUS的临时存储器,VB3580-VB4095为CRC数据库。
请教:VB3300-VB3359为通信缓冲区是不是说由它们来存储主机发送来的请求和从机应答的数据?它们在程序中那儿被指定的?具体是如何分配的?VW3302为请求的功能号,VW3304为请求位或字的起始地址,VW3306为请求的位或字的个数,那么VW3300中是不是应该为请求的从机地址呢?
程序如下:
---------------------------------------------------------------------
MAIN
Network 1
LD SM0.1
CALL SBR50
Network 2
LD M31.7 // 如果有Modbus请求出现
CALL SBR51 // 则调用处理程序
R M31.7, 1 // 清除请求标志(M31.7=0)
Network 3 // 主程序结束// MEND
---------------------------------------------------------------------
SBR_50 初始化 Modbus RTU 驱动器
初始化Modbus驱动器通信口0,注意:由于要初始化CRC表,这段初始化子程序需要大约690ms,执行时间不要报警!初始化不同数据类型的存储器极限注意:存储的最大值必须比实际极限大1,例如:允许32个输出,那就设定33
Network 1
// SBR 50
Network 2
LD SM0.0 // SM0.0总为1
MOVW +65, VW3290 // 最大值IR = 64 位
MOVW +1001, VW3292 // 最大 V 字= 2000 字节(1000)字
MOVW +17, VW3294 // 最大AI字= 16 字
MOVD &VB2000, VD3296 // V存储器的AI字首址
MOVW +8, VW3574 // Load a constant value = 8 to be
// used in mathmatical operations.
MOVB 1, VB4095 // Modbus 地址= 1.
MOVB 16#49, SMB30 // 9600波特,每个符8位,偶校验
CALL SBR62 // 初始化CRC表
R M31.7, 1 // 信息到达标志复位(M31.7=0)
ENI // 允许中断
MOVB 6, SMB34 // 设定静止线定时器>5ms
ATCH INT120, 10 // 开始寻找静止线,若静止线定时器到时,
//则调用中断程序INT 120
ATCH INT121, 8 // 在寻找静止线期间,如果收到一个字符,
// 那就执行中断程序INT121
---------------------------------------------------------------------
SBR_51 处理 Modbus 请求和传送响应
该子程序在正常的梯形图扫描周期内处理Modbus请求。计算收到信息的CRC。由于收到信息中的CRC包含在计算之内,若没有接收错误,那么计算结果总是0。
Network 1 // SBR 51
Network 2
LD SM0.0 // SM0.0总为1
MOVW VW3300, AC0 // 取缓冲区长度存入AC0
MOVD &VB3302, AC1 // 取缓冲区地址存入AC1,用于CRC检查
CALL SBR63 // 计算 CRC.
Network 3
LDW= +0, AC2 // 如果(计算CRC不等于0)
NOT // 那就表示有接收错误
JMP 255 // 跳转到LBL255
Network 4
// 信息正常,决定哪个Modbus功能被请求。// 再调用返回后总是执行紧随调用之后的跳步指令。// 因为返回前子程序总设定TOS 为1
LD SM0.0 // SM0.0总是1
MOVB VB3303, AC0 // 从请求缓冲区中取功能号存入AC0
Network 5
LDB= 1, AC0 // 是功能1?
CALL SBR52 // 是,执行功能1
JMP 254 // 然后跳到结束(LBL 254)
Network 6
LDB= 2, AC0 // 是功能2?
CALL SBR52 // 是,执行
JMP 254 // 然后跳到结束
Network 7
LDB= 3, AC0 // 是功能3?
CALL SBR53 // 是,执行
JMP 254 // 然后跳到结束
Network 8
LDB= 4, AC0 // 是功能4?
CALL SBR53 // 是,执行
JMP 254 // 然后跳到结束
Network 9
LDB= 5, AC0 // 是功能5?
CALL SBR54 // 是,执行
JMP 254 // 然后跳到结束
Network 10
LDB= 6, AC0 // 是功能6?
CALL SBR55 // 是,执行
JMP 254 // 然后跳到结束
Network 11
LDB= 15, AC0 // 是功能15?
CALL SBR56 // 是,执行
JMP 254 // 然后跳到结束
Network 12
LDB= 16, AC0 // 是功能16?
CALL SBR57 // 是,执行
JMP 254 // 然后跳到结束
Network 13
LD SM0.0 // 如果上面都不成立
MOVW +3, VW3300 // 装入错误响应长度
ORW 16#80, VW3302 // 把功能MS位置1,表示出错
MOVB 1, VB3304 // 装入"功能不支持"代码(VB3304=1)
Network 14 // 功能服务,首先计算响应的CRC,然后发送响应。根请求一样,把响应
// 的长度也放在缓冲区的第一个字中。该长度不包括CRC的2个字节长度,因此在调用发送指令之前必须将长度增加2。
LBL 254 // 标签254(跳转入口)
Network 15
LD SM0.0 // SM0.0总为1
MOVW VW3300, AC0 // 取信息长度存入AC0
MOVD &VB3302, AC1 // 取缓冲区起始地址存入AC1,用于CRC检验
CALL SBR63 // 计算CRC,
MOVD &VB3302, AC3 // 取缓冲区起始地址
+I VW3300, AC3 // 指向缓冲区尾
MOVW AC2, *AC3 // 把CRC放到缓冲区
+I +2, VW3300 // 加CRC的两字节
XMT VB3301, 0 // 发送响应
ATCH INT125, 9 // 当发送完成时执行中断程序INT125
CRET // 返回
Network 16 // CRC或长度出错处理// 在下列情况下,如CRC出错,或者没有收到足够字节的处理信息,除了通信复位外,寻找下一段信息,且使主机到时。
LBL 255 // 标签255(跳转入口)
Network 17
LD SM0.0 // SM0.0总为1
ATCH INT120, 10 // 开始寻找静止线,此期间
ATCH INT121, 8 // 如果收到字符,那就执行中断程序INT121
Network 18 // 返回// RET
-------------------