ba_wang_mao 发表于 2008-10-24 12:04:11

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

 由于MODBUS-RTU 要求每帧信息中的数据间隔时间不得超过1.5字符的静止时间。

  因此:

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

  问题如下: 

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

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

  我的理解对吗?

zuoyou 发表于 2008-10-25 13:59:37

这里有个SPI串口扩展芯片uCSU122P,内置MODBUS引擎,DIP28,或许对你有用点击此处下载 ourdev_468312.pdf(文件大小:328K) (原文件名:ucmu2_dat_v122.pdf) 

ba_wang_mao 发表于 2008-10-25 12:07:25

上面就是解决以下两个问题的方法

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

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

ba_wang_mao 发表于 2008-10-25 12:05:41

                可靠地判断帧结束,防止通信停滞



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

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

erxun 发表于 2008-10-24 12:11:29

接收到每个字节的时候,初始化定时器就行,最后一个字节后,定时器就溢出了,,,,

ba_wang_mao 发表于 2008-10-24 12:06:46

  (2)两帧之间的3.5字符的静止时间该如何实现呢?

apple1007 发表于 2009-3-17 13:23:53

学习!

alexmayer 发表于 2009-3-17 14:35:46

其实这个时间不用这么准确啦,因为是问答式的协议,你可以以某个定时时间查询串口缓冲区字符的长度,如果两次读入的长度一样就认为一帧结束了,这个查询间隔根据波特率微调,就是3.5个字符时间。

youpeng 发表于 2009-5-3 19:39:40

7楼的做法不严格,如果第一次定时查询的时候正在收最后一个字节,第二次查显然收完了,第三次查数据不变,那么就导致了7个字符的间隔,如果对方在3.5~7字符之间又来了数据,就麻烦了;

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

youpeng 发表于 2009-5-15 17:00:47

自己顶一下

jasonli 发表于 2010-1-12 18:46:24

回复【楼主位】ba_wang_mao
-----------------------------------------------------------------------

有具体的超时的例子吗?

yuxk2001 发表于 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==MSB(CRC))&&
                (ModbusFunctionUnion.Data==LSB(CRC)))
                        {
                      FrameStatu=1;
                  }                  
          }                  
   }
}
}
#pragma interrupt_handler UART_isr:iv_USART0_RX
void UART_isr(void)
{
CNT=0;
while(!(UCSR0A&(1<<RXC0)));
ModbusFunctionUnion.Data=UDR0;
}

longfeixue 发表于 2010-7-1 15:51:09

不错,正需要这点知识

mydows 发表于 2010-7-1 16:59:03

正在考虑这个问题

longfeixue 发表于 2010-7-1 18:08:19

3楼的讲解很有针对性,但是我还有些问题想请您讲一下,
1.就是你上面讲:“若定时器顺利计数到预定时间,就会触发相应的中断号,在该定时器中断子程序中设定帧结束标志字节,表明一帧
报文接收完毕。”我的疑问是如果就根据超时时间到,确定一个帧的结束,会不会出现一个帧的数据发送的中间出现了一会中断,这
样也认为一帧结束了,即这样会不会判断一个不完整的帧结束。
2.你这里只判断了桢与帧之间3.5个字符的超时,为什么一帧之内字符与字符之间的1.5个字符超时就不用判断了,如果出现超时间>1.5
个字符,又<3.5个字符的情况该怎么处理。
我理解的不是很好,可能表达的不对,但是很想请您解释一下我的这些疑问,谢谢。
页: [1]
查看完整版本: 请教,MODBUS通讯中,超时定时器是否一直开启? 【恢复】