本帖最后由 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的波特率,开了串口中断,数据接收时不应该出现超时的现象才对啊,真弄不清哪里出了问题?
|