免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2460 | 回复: 2
打印 上一主题 下一主题

[Linux] s3c2416串口每次只能接收8个字节 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-07-29 14:56 |只看该作者 |正序浏览
本帖最后由 dallas48 于 2015-07-30 10:23 编辑

每次我从另外一块板子发送12个字符  它会截成8+4分2次接收 不知道哪里出问题了

串口用sp3232芯片与cc2530链接

是否和驱动有关?如何修改呢?

请哪位帮忙看下  灰常感谢!

//串口应用
  1. struct timeval tv;  
  2.         int i=0, j=0;
  3.         fd_set rdfds;
  4.         int maxfd = -1;
  5.         int ret;
  6.         char buf[512];
  7.         tv.tv_sec = 5;
  8.         tv.tv_usec = 0;   
  9.        
  10.         uchar tx_buf[MAX_TX_SIZE];

  11.         struct ZSTACK_PACKET zstack_packet;
  12.         struct DATA_PACKET data_packet;

  13.        
  14.         printf("Input > ");
  15.         fflush(stdout);
  16.         while(1)
  17.         {
  18.                 FD_ZERO(&rdfds);   
  19.                 FD_SET(0,&rdfds);
  20.                 maxfd = maxfd>0?maxfd:0;
  21.                 FD_SET(fd, &rdfds);
  22.                 maxfd = maxfd > fd ? maxfd:fd;
  23.                 ret = select(maxfd + 1, &rdfds, NULL, NULL, &tv);               
  24.                 if(ret < 0)
  25.                 {
  26.                                 perror("Select fail\n");
  27.                                 return -1;
  28.                 }
  29.                 else if(ret == 0)
  30.                 {
  31.                         continue;
  32.                 }
  33.                 else
  34.                 {  
  35.                         if(FD_ISSET(fd, &rdfds))
  36.                         {      
  37.                                 memset(buf, 0, 512);
  38.                                 i = 0;
  39.                                 j = 0;

  40.                                 while(((j = (read(fd,&buf[i],16))) > 0) && (i<495) )
  41.                                 {
  42.                                         i = i+j;
  43.                                 }
  44.                                 printf("--------------------------------Rev from 串口2: ");
  45.                                
  46.                                 for(j = 0; j<i; j++)
  47.                                 {
  48.                                         printf("%02x ", buf[j]);
  49.                                 }
  50.                                
  51.                                 printf("\nInput > ");
  52.                                 fflush(stdout);
  53.                         }
  54.                  }
复制代码
//串口初始化如下
fd = uart_init(fd, BAUD_115200, DATA_BITS_8, STOP_BIT_1, PARITY_NONE);

//串口初始化函数如下
  1. int uart_init(int ufd, int speed, int bits, int stop, int event)
  2. {
  3.         struct termios opts;

  4.         if((ufd = open(DEV, O_RDWR|O_NOCTTY|O_NDELAY)) == -1)
  5.         {
  6.                 printf("---Open serial device %d fail!\n", (int)DEV);
  7.                 return -1;
  8.         }
  9.         else
  10.         {
  11.                 printf("---Open serial device %d success!\n", (int)DEV);
  12.         }


  13.         tcgetattr(fd, &opts);

  14.         opts.c_cflag |= (CLOCAL | CREAD);
  15.        
  16.         opts.c_iflag &= ~(IGNCR | INLCR | ICRNL | IXON);        //IGNCR 忽略输入中的回车
  17.                                                                                                                 //INLCR 将输入中的 NL 翻译为 CR
  18.                                                                                                                 //ICRNL 将输入中的回车翻译为新行
  19.                                                                                                                 //IXON        启用输出的 XON/XOFF流控制
  20.         opts.c_lflag &= ~(ICANON|ECHO|ISIG);        //ECHO 回显
  21.                                                                                         //ICANON启用标准模式 (canonical mode)。
  22.                                                                                         //      允许使用特殊字符 EOF, EOL, EOL2, ERASE,
  23.                                                                                         //                KILL, LNEXT, REPRINT, STATUS, 和 WERASE,以及按行的缓冲
  24.                                                                                         //ISIG 当接受到字符 INTR, QUIT, SUSP, 或 DSUSP 时,产生相应的信号);
  25.         opts.c_oflag &= ~OPOST;//关闭输出处理功能
  26.        
  27.         //设置波特率
  28.         switch(speed)
  29.         {
  30.                 case 1200:
  31.                         cfsetispeed(&opts, B1200);
  32.                         cfsetospeed(&opts, B1200);
  33.                         break;
  34.                 case 2400:
  35.                         cfsetispeed(&opts, B2400);
  36.                         cfsetospeed(&opts, B2400);
  37.                         break;
  38.                 case 4800:
  39.                         cfsetispeed(&opts, B4800);
  40.                         cfsetospeed(&opts, B4800);
  41.                         break;
  42.                 case 9600:
  43.                         cfsetispeed(&opts, B9600);
  44.                         cfsetospeed(&opts, B9600);
  45.                         break;
  46.                 case 19200:
  47.                         cfsetispeed(&opts, B19200);
  48.                         cfsetospeed(&opts, B19200);
  49.                         break;
  50.                 case 38400:
  51.                         cfsetispeed(&opts, B38400);
  52.                         cfsetospeed(&opts, B38400);
  53.                         break;
  54.                 case 115200:
  55.                         cfsetispeed(&opts, B115200);
  56.                         cfsetospeed(&opts, B115200);
  57.                         break;
  58.                 default:
  59.                         cfsetispeed(&opts, B9600);
  60.                         cfsetospeed(&opts, B9600);
  61.                         break;
  62.         }
  63.        
  64.         //设置数据位
  65.         opts.c_cflag &= ~CSIZE;
  66.        
  67.         if(8 == bits)
  68.                 opts.c_cflag |= CS8;
  69.         else if(7 == bits)
  70.                 opts.c_cflag |= CS7;
  71.         else if(6 == bits)
  72.                 opts.c_cflag |= CS6;
  73.         else if(5 == bits)
  74.                 opts.c_cflag |= CS5;
  75.         else
  76.                 opts.c_cflag |= CS8;

  77.         //设置校验位
  78.         switch(event)
  79.         {
  80.                 case 0:
  81.                         opts.c_cflag &= ~PARENB;
  82.                         break;
  83.                 case 1:
  84.                         opts.c_cflag |= PARENB;
  85.                         opts.c_cflag |= PARODD;
  86.                         opts.c_iflag |= (INPCK | ISTRIP);
  87.                         break;
  88.                 case 2:
  89.                         opts.c_cflag |= PARENB;
  90.                         opts.c_cflag &= ~PARODD;
  91.                         opts.c_iflag |= (INPCK | ISTRIP);
  92.                         break;
  93.                        
  94.                 default:
  95.                         opts.c_cflag &= ~PARENB;
  96.                         break;
  97.         }
  98.        
  99.         opts.c_iflag &= ~ISTRIP;
  100.        
  101.         //停止位
  102.         if(1 == stop)
  103.                 opts.c_cflag &= ~CSTOPB;
  104.         else
  105.                 opts.c_cflag |= CSTOPB;
  106.        
  107.         opts.c_cc[VTIME] = 10;
  108.         opts.c_cc[VMIN] = 64;

  109.         tcflush(ufd, TCIFLUSH);// TCIFLUSH刷清输入队列。
  110.                             // TCOFLUSH刷清输出队列。
  111.                             //TCIOFLUSH刷清输入、输出队列
  112.         if((tcsetattr(ufd, TCSANOW, &opts)) != 0)
  113.         {
  114.                 perror("COM set error!\n");
  115.                 return -1;
  116.         }

  117.         return ufd;

  118. }
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2015-07-31 21:19 |只看该作者
回复 1# dallas48


    首先不要设置O_NDELAY属性,否则是非阻塞状态,有数据过来,立刻能被读到,及时是连续发过来的,也有可能被read多次;
    其次,不设置O_NDELAY属性时,超时由c_cc[VTIME]和c_cc[VMIN]决定,你可以看看这两个参数怎么起作用,像你现在设置的,效果会变为,有数据且长于10字节时,read立刻返回,否则,判断read的传递参数的长度,如果底层缓冲的数据小于等于要求的长度也立刻返回,否则,最多等64*100ms返回。

论坛徽章:
0
2 [报告]
发表于 2015-07-31 15:39 |只看该作者
木有人~~~~
自己顶
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP