我觉得是你的串口发送函数过大,或者是发送速度过快,做如下几个尝试
1)精简串口收发函数,能简则简
2)在发送方发送一个字节之后,做一个短延时,比如在pc方,一次性writefile 500个字节与whitefile 500次,每次一个字节效果是不一样的。
在中断程序中把所有的延时全部去掉。
中断程序应该越短越好,避免接收没有完下一数又到了。
void scomm() interrupt 4 using 3 //modbus RTU模式
{
if(TI)
{
TI = 0;
if(tx_count < tx_number) //是否发送结束
{
SBUF = txbuf[tx_count];
}
tx_count++;
}
if(RI)
{
rx_temp=SBUF;
if(rx_ok==FAULT) //已接收到一帧数据,在未处理之前收到的数舍弃
{
if(rx_count
rxbuf[rx_count]=rx_temp;
rx_count++;
}
TH1=0x62; //timer1 reset,count again//modbus的超时判断
TL1=0x80;
RI=0;
}
}
你用屏蔽线没有,TXD,RXD,GND 三根线要用有金属屏蔽层线,抗干扰...
硬件就不用查了,屏蔽不屏蔽在RS232和RS485通讯中根本就不重要。
看你的情况就是软件问题,应该就是中断的问题没有解决好。
串口通讯是9针的,有很多握手线,你只用3针,恐怕你的引线质量不会很高,长时间工作不出错才怪呐,不过你的出错率是有一些偏高。
解决方法之一就是软件纠错,否则为什么串口通讯要有奇偶校验位?只要出错率不是很高,用软件解决算了。我曾经用一条很烂的引线串行通讯,用和校验纠错,很可靠的。实际上,即使引线质量再高,没有软件纠错也是很危险的,除非你的任务无关紧要。
晶振不是11.0592或其倍数,波特率设置得高了,误差太大。换个晶振,波特率就是准确的,没有误差。
我的晶振是11.0592M,我是根据这个频率设定定时器1的初值的,我设的初值不对吗?27楼说的和校验该怎么写程序啊?能说具体一点吗?26楼说用串口检测硬件,该怎么检测呢?23楼的程序能给我讲讲吗?谢谢各位高手指点!
一个简单的串口程序,每接收到8个字节就发送回这8个字节
main()
{
initUart();
while(1)
{
if(rx_count==8)
{
rx_count=0;
tx_count=0;
TI=1;//启动发送
}
}
}
void serial() interrupt 4 //串口中断
{
if(TI)
{
if(tx_count < 8)
{
SBUF = rxbuf[tx_count];
tx_count++;
}
TI = 0;
}
if(RI)
{
rx_temp=SBUF;
if(rx_count < 8)
{
rxbuf[rx_count]=rx_temp;
rx_count++;
}
RI=0;
}
}
我碰到过类似的问题,当时的解决办法是:在每个发送和接收一个字节或者一个数组后都加上一个5ms左右的延时,
我判断是速度快,所以会漏掉一些bit,
楼主可以试一下
楼主这个程序的确很乱!!
我仔细看看后再来回答。另外,楼主最好将外部中断里的代码一起贴出比较好,我估计是在串口中断中等待的时候外部中断中将某些缓冲区修改了值
这个是正解;
引用: 引用楼主 cunllp 的帖子:
单片机与PC机的串口通信时,刚开始的时候传的数据是正确的,工作一段时间,传的数据就出现错误,当向PC机传固定的一个数据时,还出现时而正确,时而错误的情形,不知道这是为什么。
不过大部分情况都应该是软件的问题!
仔细看了下,没能找出问题具体原因。但肯定是中断处理程序中有问题了,而且是外部中断和串口中断相互没处理好!
楼主自己多想想2个中断的并发看看。
为了验证你的收到什么数据马上发什么数据是否有问题,我写了如下小程序:
void serial() interrupt 4
{
Uchar tmp;
if (RI == 1)
{
tmp = SBUF;
RI = 0;
SBUF = tmp;
while (TI == 0);
TI = 0;
}
else
{
//不需要处理发送中断
}
}
如果这样都发生错误的话,那就得从硬件本身找找原因了
俺估计是速度太快了,
要不就是软件设置的问题,
建议下个别人的例子,下到你的硬件里测试一下,这样可以排除是硬件问题,还是软件问题!!
这是比较正常的,不知你用的是什么单片机,因为晶振和波特率匹配还不有一个误差的,时间长了会出现误码的,如果你用的是11059200的晶振选用4800的波特率,这个误差是很小的,应该没有什么影响的。