当前位置:  技术问答>linux和unix

使用ST16C2552IJ扩展linux串口收发数据不全问题.谁遇到这现象.

    来源: 互联网  发布时间:2016-08-31

    本文导语:  测试过程如下: 测试用电脑标准串口给arm-linux开发扳发送gps数据 例如:$GPRMC,022920.567,A,2233.6433,N,11405.4822,E,13.36,338.74,100604,,*3C 在linux中收到: 没有中间一不部分数据: $GPRMC,015503.56*35   有时也会连续收到两条没尾巴的数...

测试过程如下:
测试用电脑标准串口给arm-linux开发扳发送gps数据
例如:$GPRMC,022920.567,A,2233.6433,N,11405.4822,E,13.36,338.74,100604,,*3C

在linux中收到:

没有中间一不部分数据:
$GPRMC,015503.56*35  

有时也会连续收到两条没尾巴的数据:
$GPRMC,020341.56    
$GPRMC,020342.5638,E


发送5条数据,才会接收成功接收一条完整的数据.

不知道怎么搞的。 

我这个串口使用的是ST16C2552IJ芯片扩展的Linux串口,难道是因为使用了扩展芯片的原因吗?不过我想不会这么不可靠吧.


难道是我程序问题,贴两个关键函数,一个打开串口和接收串口数据函数.
/**
*@brief 设置串口数据位,停止位和效验位并打开串口
*@param sTTYName  串口文件描述符
*@param speed     串口波特率
*@param databits  数据位 取值 为 7 或者8
*@param stopbits  停止位 取值为 1 或者2
*@param parity    效验类型 取值为N,E,O,,S
*@param fl        标志位1表示使用异步方式打开,0表示用阻塞方式打开串口
*@return          成功返回打开串口指针,失败返回-1
*@explam          OpenDev("/dev/ttyS0",B9600,8,1,'N',1)
*/
int OpenDev(const char *sttyname,int speed,int databits,int stopbits,int parity,char fl)
{
int i = 0; 
int status = 0; 
int fd = 0;                  //打开串口指针
int flage = 0;               //打开标志位
struct termios Opt;      //串口设置结构
struct termios t_mybuf;
bzero(&Opt,sizeof(Opt));
bzero(&t_mybuf,sizeof(t_mybuf));

flage = fl?O_RDWR|O_NOCTTY|O_NONBLOCK:O_RDWR|O_NOCTTY;

fd = open(sttyname,flage);    //通过串口设备名打开串口

if(fd == -1){
perror("open"); 
return -1;

}

if(tcgetattr(fd,&Opt) == -1){      //获取当前串口设置
perror("tcgetattr"); 
return -1;
}

if(cfsetispeed(&Opt,speed) == -1){ //设置串口波特率
perror("cfsetispeed"); 
return -1;
}

if(cfsetospeed(&Opt,speed) == -1){
perror("cfsetospeed"); 
return -1;
}

/*取消一些设置*/
Opt.c_cflag &= ~CSIZE; /*需要设置字符大小*/
Opt.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG); 
Opt.c_oflag &= ~OPOST;                    /*选择原始输出*/

/*一些必须设置的项*/
Opt.c_cflag |=  CLOCAL | CREAD | O_NDELAY; 
Opt.c_iflag |= IGNPAR;  //忽略奇偶校验错误给数据放行

/*设置数据位数*/
switch(databits)

case 7: 
Opt.c_cflag |= CS7;    //设置7位一字节
break;
case 8: 
Opt.c_cflag |= CS8;    //设置8位一字节
break; 
default: 
printf(" no set databits !n");
return -1;
}

/*设置校验方式*/
switch(parity) 

case 'n':
case 'N':                   /*无校验*/
Opt.c_cflag &= ~PARENB;
Opt.c_iflag &= ~INPCK;    /*INPCK用于设置奇偶位校验位是否有效*/
break; 
case 'o': 
case 'O':                    /*奇校验*/
Opt.c_cflag |= (PARODD | PARENB);
Opt.c_iflag |= INPCK;
break; 
case 'e': 
case 'E':                  /*偶校验*/
Opt.c_cflag |= PARENB;
Opt.c_cflag &= ~PARODD; 
Opt.c_iflag |= INPCK; 
break;
case 'S': 
case 's':                 /*无*/ 
Opt.c_cflag &= ~PARENB;
Opt.c_cflag &= ~CSTOPB;
break; 
default: 
printf(" no set parity !n");
return -1;


/* 设置停止位*/
switch (stopbits)

case 1: 
Opt.c_cflag &= ~CSTOPB; 
break; 
case 2: 
Opt.c_cflag |= CSTOPB; 
break;
default: 
printf(" no set parity !n");
return -1;
}

Opt.c_cc[VTIME] = 1;
Opt.c_cc[VMIN] = 0; 

tcflush(fd,TCIFLUSH);  //清空缓冲区

if(tcsetattr(fd,TCSANOW,&Opt) == -1){   
perror("tcsetattr"); 
}

return fd;
}

/**
*@brief 接收串口数据
*@param s_fd  打开的串口指针
*@param buf   接收数据指针
*@return      成功返回接收到的数据长度,超时返回-1,错误返回-2
*/
int ReadDev(int s_fd,char *buf)
{
int available = 0;
static unsigned int rectimer;
         fd_set rfds;
int maxfd = 0;
int se_cnt = 0;
struct timeval timeout;
do{
  FD_ZERO (&rfds);
FD_SET(s_fd, &rfds);
timeout.tv_sec=0;
  timeout.tv_usec=1000;  //10*1000
maxfd = s_fd;
se_cnt = select(maxfd+1, &rfds, NULL, NULL, &timeout);
if(se_cnt > 0)
{
  if(FD_ISSET(s_fd, &rfds))
  {
     if((available = read(s_fd, &buf[0], 256)) != -1 ){
     return(available);
     }
    }
  }else if(se_cnt == 0 ){
   return -1;
  }
  FD_CLR(s_fd, &rfds);
}while(se_cnt  0){
buf[rd_len] = '';
printf("[%dB]%sn",rd_len,buf);   //打印输出
}

我可以通过输出自己把包拼起来,但发现好多包都是不全的.

谁知道这个现象是什么引起的呢?????

|
你读的太快了,简单的,select 成功后你sleep 一秒,就应该都能读到。
实际上,你应该循环读取,直到把所有的都读完,而不是read一下就返回回去。

    
 
 

您可能感兴趣的文章:

  • 请问是否能使用串口光驱装FC8?
  • 进程对串口读写时使用互斥机制吗?
  • 如何在linux上使用串口设备
  • linux下虚拟串口的使用
  • linux下使用虚拟串口
  • 如何使用S3C6410开发板上的串口3和4
  • 使用jlink烧写u-boot.bin完成后,串口无提示信息
  • java 中如何使用串口?
  • 请问使用SELECT()函数怎么监测串口发送数据?
  • 如何使用多串口卡
  • 如何使用select实时监听串口通信?
  • 串口使用问题
  • 如何设置可以在vamware下使用串口登录linux?在线等待!
  • 请教:多线程使用同一个socket进行数据收发会出现什么问题?
  • 请教高人:同一个套接字(做客户端)连接到server后在不同子进程里使用能否不采取互斥措施收发?
  • 客户端如果不使用多线程可以实现收发同时进行吗?
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • openssl中如何使用x509的扩展信息?
  • ubuntu linux里扩展名为tar.gz的文件怎么使用?
  • 请问加载动态snmpd扩展模块时使用的命令#./snmpd –f –L –DXXX,DLmod参数的含义是什么?
  • Jquery中扩展方法extend使用技巧
  • 使用JSP扩展标签,可否从标签内得到一个输出参数?
  • java 中如何使用串口? iis7站长之家
  • 使用vmware + demaon Tool + KNOPPIX_V3.3-2004-02-16-EN下挂接一硬盘的扩展分区,怎么读写这个硬盘?
  • Linux中使用扩展USB Hub的问题
  • centos6使用yum安装php mysql与gd扩展库的方法
  • php安装使用http扩展类的实例详解
  • Applet应用扩展--数字签名(一) 使用签名的jar包,即可实现访问沙箱之外!
  • 基于C# MBG 扩展方法类库的使用详解
  • PHP使用mysqli扩展连接MySQL数据库
  • PHP mysqli扩展库 预处理技术的使用分析
  • 在编译使用扩展标签的java文件时,得到package javax.servlet.jsp does not exist,package javax.servlet.jsp does not exist的错误
  • 几个扩展存储过程使用方法
  • ubuntu12.04使用c编写php扩展模块教程分享
  • 关于尝试开发PHP的MYSQL扩展的使用
  • 用C实现PHP扩展 Image_Tool 图片常用处理工具类的使用
  • oracle分区表之hash分区表的使用及扩展
  • C++ I/O 成员 tellg():使用输入流读取流指针
  • 在测试memset函数的执行效率时,分为使用Cash和不使用Cash辆种方式,该如何控制是否使用缓存?
  • C++ I/O 成员 tellp():使用输出流读取流指针
  • 求ibm6000的中文使用手册 !从来没用过服务器,现在急需使用它,不知如何使用! 急!!!!!
  • Python不使用print而直接输出二进制字符串
  • 请问:在使用oracle数据库作开发时,是使用pro*c作开发好些,还是使用库函数如oci等好一些啊?或者它们有什么区别或者优缺点啊?
  • Office 2010 Module模式下使用VBA Addressof
  • 急求结果!!假设一个有两个元素的信号量集S,表示了一个磁带驱动器系统,其中进程1使用磁带机A,进程2同时使用磁带机A和B,进程3使用磁带机B。
  • windows下tinyxml.dll下载安装使用(c++解析XML库)
  • c#中SAPI使用总结——SpVoice的使用方法
  • tcmalloc内存泄露优化c++开源库下载,安装及使用介绍


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3