比如,串口要给你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 异常信息
希望能够帮到你
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)