搜索
bottom↓
回复: 15

请教,MODBUS通讯中,超时定时器是否一直开启? 【恢复】

[复制链接]

出0入0汤圆

发表于 2008-10-24 12:04:11 | 显示全部楼层 |阅读模式
 由于MODBUS-RTU 要求每帧信息中的数据间隔时间不得超过1.5字符的静止时间。

  因此:

   (1)、当串口产生接收中断后,立即重装“超时定时器”的初始值。(注:超时定时器的初始值和波特率有关)

  问题如下: 

   (a)、由于要求在串口接收中断中重装超时定时器初始值,那么,该超时定时器就只能采用“溢出模式”,而不能采用“CTC模式”

   (b)、超时定时器必须在程序初始化时就一直开启。

  我的理解对吗?

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2008-10-25 13:59:37 | 显示全部楼层
这里有个SPI串口扩展芯片uCSU122P,内置MODBUS引擎,DIP28,或许对你有用点击此处下载 ourdev_468312.pdf(文件大小:328K) (原文件名:ucmu2_dat_v122.pdf) 

出0入0汤圆

 楼主| 发表于 2008-10-25 12:07:25 | 显示全部楼层
上面就是解决以下两个问题的方法

  (1)、当前帧两个字节之间的1.5字符静止时间

  (2)、两帧之间3.5字符的静止时间

出0入0汤圆

 楼主| 发表于 2008-10-25 12:05:41 | 显示全部楼层
                可靠地判断帧结束,防止通信停滞



  利用单独的软件定时器,来判断一帧接收报文结束,可以防止若报文接收不完整,该帧通信任务无法结束而影响下一帧的接收。

  由于一帧报文中字节与字节之间的时间间隔和帧与帧之间的时间间隔相比要小得多,因此每当接收一个新字节,就启动软件定时器开始计时,定时器的时间设定为帧与帧的最小时间间隔。波特率不同,该时间间隔也不同。若不到预定的时间内又接收到下一个字节,则说明一帧报文未结束,定时器重新计时;若定时器顺利计数到预定时间,就会触发相应的中断号,在该定时器中断子程序中设定帧结束标志字节,表明一帧报文接收完毕。当主程序内检测到一帧报文接收完毕后,会通过核查从方地址及循环冗余校验字节是否正确来判断该帧的有效性。若确定接收到的是一帧发送给已方的正确报文,则会根据报文内的功能码对该帧命令进行相应的处理,并准备发送帧。

出0入0汤圆

发表于 2008-10-24 12:11:29 | 显示全部楼层
接收到每个字节的时候,初始化定时器就行,最后一个字节后,定时器就溢出了,,,,

出0入0汤圆

 楼主| 发表于 2008-10-24 12:06:46 | 显示全部楼层
  (2)两帧之间的3.5字符的静止时间该如何实现呢?

出0入0汤圆

发表于 2009-3-17 13:23:53 | 显示全部楼层
学习!

出0入0汤圆

发表于 2009-3-17 14:35:46 | 显示全部楼层
其实这个时间不用这么准确啦,因为是问答式的协议,你可以以某个定时时间查询串口缓冲区字符的长度,如果两次读入的长度一样就认为一帧结束了,这个查询间隔根据波特率微调,就是3.5个字符时间。

出0入0汤圆

发表于 2009-5-3 19:39:40 | 显示全部楼层
7楼的做法不严格,如果第一次定时查询的时候正在收最后一个字节,第二次查显然收完了,第三次查数据不变,那么就导致了7个字符的间隔,如果对方在3.5~7字符之间又来了数据,就麻烦了;

T1.5和T3.5最严格的方法还是开定时器,但是可以灵活一点;低波特率(<19200)的时候严格定时,和波特率相关;高波特率(>19200)的时候就固定定时(T1.5=750us,T3.5=1750us),这样降低了CPU中断响应的负担。

出0入0汤圆

发表于 2009-5-15 17:00:47 | 显示全部楼层
自己顶一下

出0入0汤圆

发表于 2010-1-12 18:46:24 | 显示全部楼层
回复【楼主位】ba_wang_mao
-----------------------------------------------------------------------

有具体的超时的例子吗?

出0入0汤圆

发表于 2010-2-8 17:05:07 | 显示全部楼层
给你这个程序片段应该可以解决你的问题,我的程序经过严格的测试,高扫描周期、波特率19200下连续运行了一个星期,没出一个错误


#pragma interrupt_handler Timer1:iv_TIMER1_OVF
void Timer1(void)
{
  unsigned short CRC;
  TCNT1=65525-51*11;//65535-(11*(ubbr+1)) 波特率9600  
  if(CNT<8)
  {
     CNT++;             
     if(CNT==4)
     {
            ModBusQueryDataLong=IsrCount;
            IsrCount=0;
     }
     else if(CNT==8)
     {   
            if(ModBusQueryDataLong>2)
                {
                  
               CRC=CRC16((unsigned char *)&ModbusFunctionUnion,ModBusQueryDataLong-2);
                   if((ModbusFunctionUnion.Data[ModBusQueryDataLong-2]==MSB(CRC))&&
                  (ModbusFunctionUnion.Data[ModBusQueryDataLong-1]==LSB(CRC)))
                        {  
                      FrameStatu=1;
                    }                  
            }                  
     }
  }  
}
#pragma interrupt_handler UART_isr:iv_USART0_RX
void UART_isr(void)
{
  CNT=0;
  while(!(UCSR0A&(1<<RXC0)));
  ModbusFunctionUnion.Data[IsrCount++]=UDR0;
}

出0入0汤圆

发表于 2010-7-1 15:51:09 | 显示全部楼层
不错,正需要这点知识

出0入0汤圆

发表于 2010-7-1 16:59:03 | 显示全部楼层
正在考虑这个问题

出0入0汤圆

发表于 2010-7-1 18:08:19 | 显示全部楼层
3楼的讲解很有针对性,但是我还有些问题想请您讲一下,
1.就是你上面讲:“若定时器顺利计数到预定时间,就会触发相应的中断号,在该定时器中断子程序中设定帧结束标志字节,表明一帧
  报文接收完毕。”我的疑问是如果就根据超时时间到,确定一个帧的结束,会不会出现一个帧的数据发送的中间出现了一会中断,这
  样也认为一帧结束了,即这样会不会判断一个不完整的帧结束。
2.你这里只判断了桢与帧之间3.5个字符的超时,为什么一帧之内字符与字符之间的1.5个字符超时就不用判断了,如果出现超时间>1.5
  个字符,又<3.5个字符的情况该怎么处理。
我理解的不是很好,可能表达的不对,但是很想请您解释一下我的这些疑问,谢谢。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 09:36

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表