跪求解决串口485通讯丢字节的问题,各位高手救命呀!人命关天呀

wangdajunxx 2003-12-17 04:42:59
我的程序通过串口(485协议的)读取电度表里面的数据,数据读得出来,但是总是有丢字节的现象,比如我的报文是如下格式:
1 aa b 10 4 cf 0 0 0 99 d
但是发送过来的时候有的时候就会发生丢字节现象:
1 aa b 10 4 0 0 0 99 d
并且是有的时候丢有的时候不丢,这个问题已经憋了我一年了,请问各位高手怎么解决的呀?是不是我的串口初始化设置有问题呀?应该是哪部分问题呢?应该怎么样解决呢?问题解决了可以再加分!在线等!
...全文
1177 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangdajunxx 2003-12-25
  • 打赏
  • 举报
回复
问题解决了,谢谢大家,就是更改一下串口设置!
rakei 2003-12-22
  • 打赏
  • 举报
回复
我也遇到了同样的问题,首先对软件算法做足够的优化,
也就是说你在收到某一个数据包,然后对收到的数据包的处理过程中,检查串口是否有
新的数据到。
此外,我还发现select不太好使啊,
select没有for(;;){usleep(1);}效率高,当然是指对本进程而言。
不过即使这样,我们还是丢了数据,原因是串口硬件用来接受数据的缓存大小只有8个字节,
而发送方最多一下子发过来40个字节...
解决方法我们也在想,哪有有比较成熟的方案麻烦帮我们一把,感激不尽。
目前可行的是:
1。换一个缓存大小大的串口
2。加流控
wangdajunxx 2003-12-20
  • 打赏
  • 举报
回复
1 aa 1 10 4 85 a 0 52 d 0 //丢字节
1 aa 10 10 4 0 0 0 0 cf d //没有丢字节

我要取的是6-9位,四个字节,第10个字节是校验位,11位是结束符D,您看看第一行,结束符整往前串了一位,所以就是在6-9位之间缺了一位,1-5位是协议的固定格式,第四位4是表示有4个数据位(6-9),
daidai_____DD 2003-12-19
  • 打赏
  • 举报
回复
我看出来了,我理解了。
我在想,你的接收速度是不是和对方的发送速度差不多,甚至慢了那么一点点,导致缓冲区溢出,丢了字节
daidai_____DD 2003-12-19
  • 打赏
  • 举报
回复
还有,不怎么理解你的丢字节,最好抓两行出来好好解释一下。
我想这个应该不是很难的问题
daidai_____DD 2003-12-19
  • 打赏
  • 举报
回复
大哥,你能不能解释一下你的数据啊?
pd是长度?kl是序号?
还有那些大于255或者小于0的数据是什么意思?
你的接收缓冲区是定义成unsighed char类型的吗?
wangdajunxx 2003-12-18
  • 打赏
  • 举报
回复
yaxii(笑影) ,这是我返回的报文:
[root@localhost /toot]#
1 aa 1 10 4 85 a 0 52 d 0 1375734405 40 34 57 d7 //丢字节
1 aa 10 10 4 0 0 0 0 cf d 0 0 0 0 0
1 aa 6 10 4 bb a0 0 23 d 0 587243707 70 43 72 58 //丢字节
1 aa b 10 4 cf 0 0 0 99 d 207 20 0 0 0
-- pd= 48 --- k1= 1 ---
2 aa 1 10 4 98 1 0 0 5a d 408 40 0 0 0
2 aa 10 10 4 0 0 0 0 d0 d 0 0 0 0 0
2 aa 6 10 4 a9 0 0 0 6f d 169 16 0 0 0
2 aa b 10 4 2a 0 0 0 f5 d 42 4 0 0 0
-- pd= 48 --- k1= 2 ---
-- pd= 48 --- k1= 3 ---
4 aa 1 10 4 8a ce 0 1e d 0 503369354 35 69 33 50 //丢字节
4 aa 10 10 4 f 0 0 0 e1 d 15 1 0 0 0
4 aa 6 10 4 f2 0 1 0 bb d 65778 77 65 0 0
4 aa b 10 4 3a 0 0 0 7 d 58 5 0 0 0
-- pd= 48 --- k1= 4 ---
5 aa 1 10 4 7c 9b 6 0 e1 d 433020 2 33 4 0
5 aa 10 10 4 5 0 0 0 d8 d 5 0 0 0 0
5 aa 6 10 4 7c 9a 1 0 e0 d 105084 8 5 1 0
5 aa b 10 4 0 0 0 d1 d 0 -788529152 14 38 64 30 //丢字节
-- pd= 48 --- k1= 5 ---
6 aa 1 10 4 ce 2 0 0 95 d 718 71 0 0 0
6 aa 10 10 4 95 0 0 0 69 d 149 14 0 0 0
6 aa 6 10 4 86 1 0 0 51 d 390 39 0 0 0
6 aa b 10 4 d4 5 0 0 a8 d 1492 49 1 0 0
-- pd= 48 --- k1= 6 ---
7 aa 1 10 4 47 f2 6 0 5 d 455239 23 55 4 0
7 aa 10 10 4 18 0 0 0 ed d 24 2 0 0 0
7 aa 6 10 4 cc 65 2 0 fe d 157132 13 57 1 0
7 aa b 10 4 60 1 0 0 31 d 352 35 0 0 0
-- pd= 48 --- k1= 7 ---
8 aa 1 10 4 1d 0 0 0 e4 d 29 2 0 0 0
8 aa 10 10 4 0 0 0 0 d6 d 0 0 0 0 0
8 aa 6 10 4 b 0 0 0 d7 d 11 1 0 0 0
8 aa b 10 4 38 0 0 0 9 d 56 5 0 0 0
-- pd= 48 --- k1= 8 ---
9 aa 1 10 4 2e ff 5 0 fa d 393006 0 93 3 0
9 aa 10 10 4 0 0 0 0 d7 d 0 0 0 0 0
9 aa 6 10 4 ad 36 0 b3 d 0 -1291831635 66 35 31 e0 //丢字节
9 aa b 10 4 0 0 0 d5 d 0 -721420288 0 47 35 37 //丢字节
-- pd= 48 --- k1= 9 ---
10 aa 1 10 4 68 30 1 0 68 d 77928 92 77 0 0
10 aa 10 10 4 0 0 0 0 de d 0 0 0 0 0
10 aa 6 10 4 d 3b 0 0 d 0 15117 11 15 0 0
10 aa b 10 4 57 e 0 0 3e d 3671 67 3 0 0
-- pd= 48 --- k1= 10 ---
11 aa 1 10 4 67 0 0 0 37 d 103 10 0 0 0
11 aa 10 10 4 0 0 0 0 df d 0 0 0 0 0
11 aa 6 10 4 16 0 0 0 eb d 22 2 0 0 0
11 aa b 10 4 7 0 0 0 e1 d 7 0 0 0 0
-- pd= 48 --- k1= 11 ---
12 aa 1 10 4 e 85 2 0 66 d 165134 13 65 1 0
12 aa 10 10 4 0 0 0 0 e0 d 0 0 0 0 0
12 aa 6 10 4 58 b6 0 0 e4 d 46680 68 46 0 0
12 aa b 10 4 10 0 0 0 eb d 16 1 0 0 0
-- pd= 48 --- k1= 12 ---
13 aa 1 10 4 58 b8 1 0 e3 d 112728 72 12 1 0
13 aa 10 10 4 b0 0 0 0 91 d 176 17 0 0 0
13 aa 6 10 4 5 7a 0 0 56 d 31237 23 31 0 0
13 aa b 10 4 69 5 0 0 4a d 1385 38 1 0 0
-- pd= 48 --- k1= 13 ---
14 aa 1 10 4 44 64 7 0 82 d 484420 42 84 4 0
14 aa 10 10 4 0 0 0 0 e2 d 0 0 0 0 0
14 aa 6 10 4 f b5 0 9f d 0 -1627343601 69 23 76 a6 //丢字节
14 aa b 10 4 0 0 0 0 dd d 0 0 0 0 0
-- pd= 48 --- k1= 14 ---
15 aa 1 10 4 8c 21 1 0 82 d 74124 12 74 0 0
15 aa 10 10 4 8 0 0 0 eb d 8 0 0 0 0
15 aa 6 10 4 f1 8e 0 0 58 d 36593 59 36 0 0
15 aa b 10 4 f 0 0 0 ed d 15 1 0 0 0
-- pd= 48 --- k1= 15 ---
16 aa 1 10 4 0 0 0 ef d 0 -285212672 62 54 97 80 //丢字节
16 aa 10 10 4 16 0 0 0 fa d 22 2 0 0 0
16 aa 6 10 4 e 0 0 0 e8 d 14 1 0 0 0
16 aa b 10 4 2e 0 0 0 d d 46 4 0 0 0
-- pd= 48 --- k1= 16 ---
17 aa 1 10 4 75 0 0 0 4b d 117 11 0 0 0
17 aa 10 10 4 53 0 0 0 38 d 83 8 0 0 0
17 aa 6 10 4 35 16 2 0 28 d 136757 75 36 1 0
17 aa b 10 4 d 0 0 0 ed d 13 1 0 0 0
-- pd= 48 --- k1= 17 ---
18 aa 1 10 4 19 0 0 0 f0 d 25 2 0 0 0
18 aa 10 10 4 2 0 0 0 e8 d 2 0 0 0 0
18 aa 6 10 4 73 0 0 0 4f d 115 11 0 0 0
18 aa b 10 4 11 0 0 0 f2 d 17 1 0 0 0
-- pd= 48 --- k1= 18 ---
19 aa 1 10 4 f3 e5 a 0 ba d 714227 22 14 7 0
19 aa 10 10 4 0 0 0 0 e7 d 0 0 0 0 0
19 aa 6 10 4 82 43 0 0 a2 d 17282 28 17 0 0
19 aa b 10 4 b3 9 0 0 9e d 2483 48 2 0 0
-- pd= 48 --- k1= 19 ---
-- pd= 48 --- k1= 20 ---
21 aa 1 10 4 f 2 0 0 f1 d 527 52 0 0 0
21 aa 10 10 4 d7 0 0 0 c6 d 215 21 0 0 0
21 aa 6 10 4 a6 0 0 0 8b d 166 16 0 0 0
21 aa b 10 4 cd 0 0 0 b7 d 205 20 0 0 0
-- pd= 48 --- k1= 21 ---
-- pd= 48 --- k1= 22 ---
-- pd= 48 --- k1= 23 ---
-- pd= 48 --- k1= 24 ---
-- pd= 48 --- k1= 25 ---
-- pd= 48 --- k1= 26 ---
-- pd= 48 --- k1= 27 ---
-- pd= 48 --- k1= 28 ---
-- pd= 48 --- k1= 29 ---
-- pd= 48 --- k1= 30 ---
-- pd= 48 --- k1= 31 ---
-- pd= 48 --- k1= 32 ---
-- pd= 48 --- k1= 33 ---
就是这样,有的时候丢,有的时候不丢,并且还不是确定的哪个丢,请问哪有控制字符都是哪些的具体资料吗?
chenzhangf 2003-12-18
  • 打赏
  • 举报
回复
我串口程序用的是国外已经封好的串口类,然后自己写了个
readv,writev,很好用。还是那句话,一次读4个字符,多读几次,然后拼起来。
daidai_____DD 2003-12-18
  • 打赏
  • 举报
回复
楼主,我强烈建议你再做一切设置之前,先
bzero(&ts0,sizeof(struct termios));
wangdajunxx 2003-12-18
  • 打赏
  • 举报
回复
这是我的读取函数
void c_db(int a)
{
tcflush(fd0,TCIOFLUSH);
g_cs(5);
ci[5]=cs;
usleep(2000);
c_s_dtr();
usleep(2000);
rc = write(fd0,ci,7);
usleep(160000);
c_e_dtr();
usleep(400000);
for(i=0;i<50;i++) { co[i]=0x0; }
rc = read(fd0,co,30);
wangdajunxx 2003-12-18
  • 打赏
  • 举报
回复
我的波特率是1200,应该可以的,我的设置如下,大家帮忙看看!
void s_s0(void)
{
fd0=open("/dev/ttyS1",O_RDWR | O_NOCTTY | O_NDELAY);
tcgetattr(fd0,&ts0);
ts0.c_cflag |= B1200 | CS8 | CLOCAL | CREAD | PARENB ;
ts0.c_cflag &= ~CRTSCTS;
ts0.c_lflag &= ~ECHO; /* | IEXTEN | ISIG); */
ts0.c_lflag &= ~ECHONL;
ts0.c_iflag &= ~(IXOFF | IXON);
ts0.c_iflag &= ~( INLCR | ICRNL);
ts0.c_cflag &= ~CSIZE;
ts0.c_cflag |= CS8;
ts0.c_cflag |= PARENB;
ts0.c_lflag &= ~ICANON;
ts0.c_oflag &= ~(ONLCR | OCRNL);
ts0.c_iflag &= ~(INLCR | ICRNL);
ts0.c_cc[VMIN] = 0;
ts0.c_cc[VTIME] = 0;
ts0.c_cflag &= ~CSTOPB;
ts0.c_iflag |= IGNBRK;
ts0.c_lflag &= ~IEXTEN;
ts0.c_lflag |= NOFLSH;
rc = cfsetospeed(&ts0,B1200);
rc = tcsetattr(fd0,TCSAFLUSH,&ts0);
daidai_____DD 2003-12-17
  • 打赏
  • 举报
回复
void initcum()
{
struct termios cum0;
unsigned char echo[6];
int handle;
handle=open(CUM0,O_RDWR|O_NOCTTY);
if (handle<0)
{printf("OPEN CUM0 ERROR!\n");exit(-1);}
tcgetattr(handle,&cum0);//不需要的。
bzero(&cum0,sizeof(struct termios));///////特别重要!一定要将结构清0。
cum0.c_cflag=B1200|~CRTSCTS|CS8|CLOCAL|CREAD;
cum0.c_cflag|=(PARENB);
cum0.c_oflag=0;
cum0.c_lflag=0;
cum0.c_cc[VMIN]=0;
cum0.c_cc[VTIME]=9;
cum0.c_iflag&=~(IXON|IXOFF);//不设置软件流控
cfsetispeed(&cum0,B1200);
cfsetospeed(&cum0,B1200);
tcsetattr(handle,TCSANOW,&cum0);
outb(0x03,0x3f8+3);//很久以前写的,不知道这句话是什么意思了。要用这句话,需要调用ioperm.
}
这是我的初始化过程,可能你用得上。
你的问题,不一定是你软件上的。你可以使用另外一台机器监测数据,看看用两台机器读取的数据是不是一样会少字节。
chenzhangf 2003-12-17
  • 打赏
  • 举报
回复
你读用无阻塞模式循环读,如果还有问题,可能是硬件问题,或者把
通信双方的波特率改小点试试。
wangdajunxx 2003-12-17
  • 打赏
  • 举报
回复
我一次读出来的是一个字节,你上面看到的是我保存下来以后显示出来的,在显示的过程中就发现少了一个字节!
chenzhangf 2003-12-17
  • 打赏
  • 举报
回复
你用的读函数有问题,在linux下一次一般只能读4-8个字节,有的平台一次只能读一个字节,
你要自己多读几次,然后把读到的数据组合起来。

23,116

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧