各位大侠,我写了一个linux下我写了个程序验证串口接收数据情况,是个死循环read,发现串口需要分多次read

各位大侠,我写了一个linux下我写了个程序验证串口接收数据情况,是个死循环read,发现串口需要分多次read,第1张

首先,默认的串口文件的缓存方式是无缓冲。其次,串口在发送数据的时候不是连续的。

比如,串口要给你0x62,0x77。那么他就先发0x62后发0x77。而如果你在他发完0x62的时候马上就read()那就会只得到0x62.而0x77要再read一次。

如果你想一次就全读上来,那有两个方法。

1:你自己写一个读串口的函数,里面调用read;

例如:

int tipc_read_socket( int sockfd, char *buf, int len )

{

int count = 0//每次读取字节数

int pos = 0//总共读取字节数

pos = 0

do {

count = read(sockfd, &buf[pos], len - pos)

//printf("tipc_read_socket:count[%d]\n", count)

if( 0 >count )

{

if( EINTR == errno )

continue

//当设置为non block的时候,第一次把所有的数据读取完以后,第二次的结果为-1.

return( pos )

}

if( 0 == count ) break /* Nothing left! */

pos += count

} while( len >pos )

return( pos )}

2:你设置一下输入输出属性。

struct termios newtio

bzero( &newtio, sizeof( newtio ) )

newtio.c_cc[VTIME] = ***

newtio.c_cc[VMIN] = ***

tcsetattr(fd,TCSANOW,&newtio)

这个里面的VTIME,VMIN。就是读等待的时间

设置了以后,比如你读0x62的时候read,那么他会等待你设置的时间,如果在这个时间里面0x77来了,那他会把0x62和0x77一起返回给你。这个时间跟波特率有关,应该是设置为在某种波特率的情况下连续两字节的最大间隔时间。

我想楼主的意思应该是实时更新AD采集到的数据并传送到上位机吧。

我的理解是楼主所指芯片是下位机,并且只做下位机的发送工作,那么可以用标志位的方法限定发送状态。

我的一个想法:

首先设定是否全局发送标志位IfSendAdValue(这个可以设定为位变量,节省内部RAM),这里假设0代表不发送,1代表发送。

主程序main中用while循环不断比对IfSendAdValue是否为1,等于1执行发送程序Send(),等于0继续比对。

Send()函数中让IfSendAdValue等于0,表示一次发送后禁止再次发送Ad数据。

第一种、利用IO口线做一个端口按键,控制IfSendAdValue为1,表示只要端口按键响应,便发送一次Ad数据。

第二种、通过上位机回送一个应答信号,原理同IfSendAdValue。

主程序:

void main(void)

{

Ini_Uart()

while(1)

{

GetAdValue()//将Ad采样放在主循环中,表示不断采样,但不一定发送,这样保证了Ad值的实时性。

if(IfSendAdValue)

Send()

}

}

static private byte[] Write(ref SerialPort comPort, byte[] data, int timeOut, int returnLength,ref string error)

{

try

{

comPort.DiscardInBuffer()//清除串口接收缓冲区数据,避免外界干扰数据被提取

comPort.Write(data, 0, data.Length)

for (int a = 0a <timeOuta++)

{

if (comPort.BytesToRead == returnLength)

{

byte[] buf = new byte[returnLength]

comPort.Read(buf, 0, returnLength)

return buf

}

Thread.Sleep(1)

}

error = "数据响应超时."

return null

}

catch(Exception e)

{

error = e.Message

return NullByte

}

}

这是我项目中的代码,没有做任何修改

comPort 串口对象

data 要发送的数据

timeOut 读取超时时间(单位毫秒)

returnLength 返回数据的长度(因为已经知道要返回数据的长度,所以判断长度,如果不知道返回的长度,可以只设置它的超时参数)

error 异常信息

希望能够帮到你


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/6844255.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-29
下一篇 2023-03-29

发表评论

登录后才能评论

评论列表(0条)

保存