解决Linux串口查询一次只能返回8位的问题

问题描述:

项目中有定时查询传感器并将查询到的数据记录下来的需要,在做的时候发现通过whlie循环配合select监测串口上的数据,然后将数据保存在数组的过程中,read函数的第三个参数即选择读取的字节数,在大于8的情况下返回的个数仍然为8,而传感器返回的数据包一般都是十几位,无法一次性返回,就需要记录好几次。更为严重的是,如果数据包的字节数大于16的情况下,第二次返回8个字节的同时,会将第一次的返回的8个字节覆盖掉,从而导致记录的数据不完整。

解决思路:

串口每次查询只能返回8位受制于缓冲的大小,一般情况下无法改变,那么应该着手通过对返回的数据包进行处理,不要每次返回都进行记录,而是在一次数据包返回完整之后,再将它传递给用于存储的数组进行记录。
程序修改前如下:


int receive(char *str , unsigned int length)

{     	
	fd_set fs_read;
	struct timeval time;
	FD_ZERO(&fs_read);
	FD_SET(fd,&fs_read);
	time.tv_sec=0;
	time.tv_usec=0;
 	unsigned int i_counter=0;
	int len=0;     

      while(select(fd+1,&fs_read,NULL,NULL,&time) > 0 )
      {
		if((len=read(fd,str,128))<0)
			{
			perror("read");
			return -1;
			}

              else{ 
 		i_counter+= len;
		 }

       }
       return i_counter;

}

上述代码中的str会传递到另外一个记录数据包的函数里面,本来以为将read的第三个参数设为128就可以完全满足需要,返回全部的数据长度,但是实际上一次最多只能返回8位,如果总的字节数大于16位,还会将前面的数据刷新掉,而只能够记录到最后小于16个字节的包。
程序修改后如下:

unsigned int i_counter=0;
int receive (char *str,unsigned int length)
{
	int len=0;
	unsigned char str_house[2056]={0};
	fd_set fs_read;
	struct timeval time;
	FD_ZERO(&fs_read);
	FD_SET(fd,&fs_read);
	time.tv_sec=0;
	time.tv_usec=0;
	int j_count=0;
	while(select(fd+1,&fs_read,NULL,NULL,&time)>0){
		if((len=read(fd,str_house,8))<0)
		{
			perror("read");
			return -1;
		}
		else{
			i_counter+=len;
			if(i_counter>length)
			{
				i_counter=8;
			}
			printf("len is %d counter is %d\n",len,i_counter);
			if(len==8)
			{
				for(j_count=0;j_count<8;j_count++)
				{
					str[i_counter-8+j_count]=str_house[j_count];
				}
			}
			else if(len<8)
			{
				for(j_count=0;j_count<len;j_count++)
				{
					str[i_counter-len+j_count]=str_house[j_count];
				}
			}
		}
	}
	return i_counter;
}


上述程序中,i_counter用来记录当前已经收到的数据包中元素的个数,如果放在函数内部的话,每次调用该函数来查询,该值都会被初始化为零,起不到计数的作用,所以应该作为全局变量,但是当它计数超过我们本次查询返回字节的最大值之后,会被清零,否则会一直无限增长下去,然后就可以创建一个暂时存放数据包的仓库,即数组str_house,每次读八位并记录,直到它读到的字节大于零且小于八,说明它返回的是最后几个字节,这几个字节存完之后,这一条查询指令所返回的数据包就全部存放到str_house这个数组里了,该数组通过被其他写函数调用,就可以存放到SD卡或者SATA硬盘等存储设备,从而解决Linux下串口查询一次只能返回8位的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值