dallas48 发表于 2015-07-29 14:56

s3c2416串口每次只能接收8个字节

本帖最后由 dallas48 于 2015-07-30 10:23 编辑

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

串口用sp3232芯片与cc2530链接

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

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

//串口应用struct timeval tv;
        int i=0, j=0;
        fd_set rdfds;
        int maxfd = -1;
        int ret;
        char buf;
        tv.tv_sec = 5;
        tv.tv_usec = 0;   
       
        uchar tx_buf;

        struct ZSTACK_PACKET zstack_packet;
        struct DATA_PACKET data_packet;

       
        printf("Input > ");
        fflush(stdout);
        while(1)
        {
                FD_ZERO(&rdfds);   
                FD_SET(0,&rdfds);
                maxfd = maxfd>0?maxfd:0;
                FD_SET(fd, &rdfds);
                maxfd = maxfd > fd ? maxfd:fd;
                ret = select(maxfd + 1, &rdfds, NULL, NULL, &tv);               
                if(ret < 0)
                {
                                perror("Select fail\n");
                                return -1;
                }
                else if(ret == 0)
                {
                        continue;
                }
                else
                {
                        if(FD_ISSET(fd, &rdfds))
                        {      
                                memset(buf, 0, 512);
                                i = 0;
                                j = 0;

                                while(((j = (read(fd,&buf,16))) > 0) && (i<495) )
                                {
                                        i = i+j;
                                }
                                printf("--------------------------------Rev from 串口2: ");
                               
                                for(j = 0; j<i; j++)
                                {
                                        printf("%02x ", buf);
                                }
                               
                                printf("\nInput > ");
                                fflush(stdout);
                        }
               }//串口初始化如下
fd = uart_init(fd, BAUD_115200, DATA_BITS_8, STOP_BIT_1, PARITY_NONE);

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

        if((ufd = open(DEV, O_RDWR|O_NOCTTY|O_NDELAY)) == -1)
        {
                printf("---Open serial device %d fail!\n", (int)DEV);
                return -1;
        }
        else
        {
                printf("---Open serial device %d success!\n", (int)DEV);
        }


        tcgetattr(fd, &opts);

        opts.c_cflag |= (CLOCAL | CREAD);
       
        opts.c_iflag &= ~(IGNCR | INLCR | ICRNL | IXON);        //IGNCR 忽略输入中的回车
                                                                                                                //INLCR 将输入中的 NL 翻译为 CR
                                                                                                                //ICRNL 将输入中的回车翻译为新行
                                                                                                                //IXON        启用输出的 XON/XOFF流控制
        opts.c_lflag &= ~(ICANON|ECHO|ISIG);        //ECHO 回显
                                                                                        //ICANON启用标准模式 (canonical mode)。
                                                                                        //      允许使用特殊字符 EOF, EOL, EOL2, ERASE,
                                                                                        //                KILL, LNEXT, REPRINT, STATUS, 和 WERASE,以及按行的缓冲
                                                                                        //ISIG 当接受到字符 INTR, QUIT, SUSP, 或 DSUSP 时,产生相应的信号);
        opts.c_oflag &= ~OPOST;//关闭输出处理功能
       
        //设置波特率
        switch(speed)
        {
                case 1200:
                        cfsetispeed(&opts, B1200);
                        cfsetospeed(&opts, B1200);
                        break;
                case 2400:
                        cfsetispeed(&opts, B2400);
                        cfsetospeed(&opts, B2400);
                        break;
                case 4800:
                        cfsetispeed(&opts, B4800);
                        cfsetospeed(&opts, B4800);
                        break;
                case 9600:
                        cfsetispeed(&opts, B9600);
                        cfsetospeed(&opts, B9600);
                        break;
                case 19200:
                        cfsetispeed(&opts, B19200);
                        cfsetospeed(&opts, B19200);
                        break;
                case 38400:
                        cfsetispeed(&opts, B38400);
                        cfsetospeed(&opts, B38400);
                        break;
                case 115200:
                        cfsetispeed(&opts, B115200);
                        cfsetospeed(&opts, B115200);
                        break;
                default:
                        cfsetispeed(&opts, B9600);
                        cfsetospeed(&opts, B9600);
                        break;
        }
       
        //设置数据位
        opts.c_cflag &= ~CSIZE;
       
        if(8 == bits)
                opts.c_cflag |= CS8;
        else if(7 == bits)
                opts.c_cflag |= CS7;
        else if(6 == bits)
                opts.c_cflag |= CS6;
        else if(5 == bits)
                opts.c_cflag |= CS5;
        else
                opts.c_cflag |= CS8;

        //设置校验位
        switch(event)
        {
                case 0:
                        opts.c_cflag &= ~PARENB;
                        break;
                case 1:
                        opts.c_cflag |= PARENB;
                        opts.c_cflag |= PARODD;
                        opts.c_iflag |= (INPCK | ISTRIP);
                        break;
                case 2:
                        opts.c_cflag |= PARENB;
                        opts.c_cflag &= ~PARODD;
                        opts.c_iflag |= (INPCK | ISTRIP);
                        break;
                       
                default:
                        opts.c_cflag &= ~PARENB;
                        break;
        }
       
        opts.c_iflag &= ~ISTRIP;
       
        //停止位
        if(1 == stop)
                opts.c_cflag &= ~CSTOPB;
        else
                opts.c_cflag |= CSTOPB;
       
        opts.c_cc = 10;
        opts.c_cc = 64;

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

        return ufd;

}

羽剑天涯 发表于 2015-07-31 21:19

回复 1# dallas48


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

dallas48 发表于 2015-07-31 15:39

木有人~~~~
自己顶
页: [1]
查看完整版本: s3c2416串口每次只能接收8个字节