|
问题如下:
主站A和从站B之间通过标准的MODBUS协议进行通讯。
我目前要做的工作是:
在主站和从站之间强行接入一个“自己开发的MODBUS设备X”, 称之为中转站。(由于特殊原因,主站的寄存器地址和从站的寄存器“不是一一对应的”,因此中转站主要的工作是翻译寄存器地址)
(a)、主站到从站的请求包,必须通过设备X(中转站)翻译后,再送给(从站)
(b)、从站到主站的应答包,必须通过设备X(中转站)翻译后,再送给(主站)
主站 自己开发的中转站 从站
|------------------ 翻译 ---------------------- ----------------------
| 设备A | ---------> | 设备X | ---------------> | 设备B |
| | <----------- | | <-------------- | |
|------------------ 翻译 ----------------------- ----------------------- 数据流向示意图
例如:主站上0X寄存器数量 = 5 , 地址为 0:0012,0:0013,0:0014,0:0015,0:0016
从站上0X寄存器数量 = 5 , 地址为 0:0001,0:0002,0:0003,0:0004,0:0005
主站(组态软件)读取0X寄存器的请求包为:
1 1 00 0B 00 05 CRCHi CRCLo
设备地址 功能码 起始地址=12 寄存器数量 CRC16
中转站接收到上述请求包后, 翻译成如下的包,然后发送给从站
1 1 00 00 00 05 CRCHi CRCLo
设备地址 功能码 起始地址=1 寄存器数量 CRC16
程序比较简单:
使用外部晶体振荡器=11.0592MHZ,波特率=38400,主站每隔150ms给中转站发送一帧请求包。
我的模块的接收中断和发送中断采用中断+缓冲区方式,汇编代码非常短。
溢出中断用于判断是否接收完成一帧数据包,只有两条赋值语句,汇编代码也非常短。
主程序只是用于处理接收到的数据包,没有其它代码。
(1)、两个溢出中断 T0,T2
进入串口0中断服务程序后,开启T0;进入T0溢出中断服务程序后,关闭T0。
进入串口1中断服务程序后,开启T2;进入T2溢出中断服务程序后,关闭T2。
注:MODBUS 协议依据3.5字符静止时间,判断是否一帧数据包接收完成。即进入串口接收中断后,开启定时器,当定时器溢出后,认为一帧数据包接收完成。
(2)、两个接收中断
采用中断+缓存方式接收数据。
(3)、两个发送中断
采用中断+缓存方式发送数据。
(4)、两个数据包解析函数
(5)、两个接收计数器
USART0_RECV = 串口0接收指针
USART1_RECV = 串口1接收指针
现在存在的问题是:
中转站接收“主站”的请求包完全正确。
中转站接收“从站”的应答包(至少14个字节),99.999%的时间接收正常,只是0.001%的时候接收错误出现如下问题,而且原因是固定的。
错误原因: 进入T2溢出中断后,USART1_RECV = 1; 说明这个应答包“中转站”只接收了1个字节。
这种原因,如何解决? |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|