打印
[51单片机]

热心人帮忙看一下,虚拟串口传输数据出问题!

[复制链接]
1381|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
space005|  楼主 | 2014-9-2 18:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 space005 于 2014-9-2 18:30 编辑

   写了一段AT89C52的C51程序进行MODBUS-RTU数据传输,我是利用KEIL V3.3,MODSCAN32,虚拟串口VSPD这三个软件在电脑上进行程序模拟的。
   传输采用2400波特率,MODSCAN32发送数据,KEIL接收,由于MODBUS数据帧与帧之间必须大于3.5个字符的间隔时间,所以程序中采用了2ms定时器中断,定时中断程序中有计数变量n,程序中开了串口中断(中断优先级高于定时器中断),当单片机有接收中断(即RI=1),n就清0,否则当n大于10时(相当于20ms,大概4个字符的间隔时间),判断为有新数据帧传输,标志寄存器_time4为超时标志,为1时表示超时。
  可是在调试时,发现KEIL接收数据时,计数变量要远大于10时,才能保证数据被正确接收,这里采用了一个数据组receivedata[k]来接收MODSCAN32传输过来的数据,否则,传输过来的数据没法完全接收,数据中字节与字节之间时间间隔大于计数变量10的,数据就被程序忽略了,我程序中n的值都设到300了,但还是偶然会发生上述传输超时的问题?下面是程序中的字节接收和接收中断程序。
void recebyte(void)//字节接收
{            
        if(标志寄存器_time4==1)         
         {
         temp[0]=SBUF;
         RI=0;
         标志寄存器_time4=0;
         n=0;
         if(temp[0]==fzdz)//如果接收数据等于分站地址
        {
         receivedata[0]=temp[0];
         标志寄存器_dztg=1;//地址验证通过标志置1        
         k=1;//k置1,表示接收了第一个字节数据
        }
        }        
    else if(标志寄存器_time4==0)//不超时,表示有数据传输
        {
         if(标志寄存器_dztg==1)//如果地址通过,则继续接收数据
         {
          temp[0]=SBUF;
          RI=0;
         receivedata[k]=temp[0];        
         k++;//接收字节计数器加1
         }
        else
        RI=0;
        n=0;//总线上有数据传输,2ms计数清零        
        }                                                                                          
}

void comRi(void) interrupt 4
{
if(RI)
recebyte();//接收一个字节数据
} 本人觉得2400的波特率,开了串口中断,数据接收时不应该出现超时的现象才对啊,真弄不清哪里出了问题?





相关帖子

沙发
cjseng| | 2014-9-3 01:02 | 只看该作者
虚拟串口VSPD不管波特率的。

使用特权

评论回复
板凳
bluesky001| | 2014-9-4 12:34 | 只看该作者
没用过modbus。可以尝试用示波器分析一下。
(1)每个定时器中断讲某个端口信号取反,用示波器测量该信号,分析定时是否准确。
(2)用示波器分析Modbus信号,看看数据传输到底花了多少时间。

使用特权

评论回复
地板
gx_huang| | 2014-9-4 12:53 | 只看该作者
对软件模拟不感兴趣,这个也仿真,什么时候才做实际的产品呢。

使用特权

评论回复
5
dengm| | 2014-9-26 17:10 | 只看该作者
void comRi(void) interrupt 4
{
   if(RI) {
     recebyte();//接收一个字节数据
   RI=0; }  //   ***** RI 一定要清零!!!!!  }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

16

帖子

0

粉丝