Chinaunix

标题: Linux主机下利用交叉编译环境进行串口编程read函数死循环 [打印本页]

作者: 风云杰雨    时间: 2011-03-21 17:44
标题: Linux主机下利用交叉编译环境进行串口编程read函数死循环
哪位高手帮忙解决下问题,非常感谢!程序的代码如下所示:
#include     <stdio.h>      /* stand input and output... */
#include     <stdlib.h>     /* stand lib */
#include     <unistd.h>     /* UNIX stand function */
#include     <sys/types.h>  /**/
#include     <sys/stat.h>   /**/
#include     <fcntl.h>      /* file controle */
#include     <termios.h>    /*PPSIX terminal controle */
#include     <errno.h>      /* error */
#include        <math.h>        /**/


/************ set baud ********************/
void set_speed(int fd, int speed)
{
    int   status;
    struct termios Opt;

    tcgetattr(fd, &Opt);  // get attribute of serial port
    tcflush(fd, TCIOFLUSH);
    cfsetispeed(&Opt, speed);
    cfsetospeed(&Opt, speed);

    status = tcsetattr(fd, TCSANOW, &Opt);  // set attribute
    if  (status != 0)
    {
        perror("tcsetattr fd1");
        return;
    }
    tcflush(fd,TCIOFLUSH);
}


/*********** set data format: databits,stopbits and parity **********/
int set_data_format(int fd,int databits,int stopbits,int parity)
{
    struct termios opt;

    if( tcgetattr(fd, &opt)  !=  0)
    {
          perror("SetupSerial 1");
          return -1;
    }
    opt.c_cflag &= ~CSIZE;

    switch (databits)
    {
       
    case 5:
                  opt.c_cflag |= CS5;
                  break;
        case 6:
                  opt.c_cflag |= CS6;
                  break;
        case 7:
                  opt.c_cflag |= CS7;
                  break;
          case 8:
                opt.c_cflag |= CS8;
                break;
        default:
                fprintf(stderr,"Unsupported data size\n");
                return -1;
    }
    switch (parity)
    {
    case 'n':
    case 'N':
                opt.c_cflag &= ~PARENB;   /* Clear parity enable */
                opt.c_iflag &= ~INPCK;     /* Enable parity checking */
                break;
        case 'o':
        case 'O':
                opt.c_cflag |= (PARODD | PARENB);  /* parity checking */
                opt.c_iflag |= INPCK;      /* Disnable parity checking */
                break;
        case 'e':
        case 'E':
                opt.c_cflag |= PARENB;     /* Enable parity */
                opt.c_cflag &= ~PARODD;   /*  */  
                opt.c_iflag |= INPCK;       /* Disnable parity checking */
                break;

        default:
                fprintf(stderr,"Unsupported parity\n");
                return -1;
    }
      
    switch (stopbits)
    {
    case 1:
                  opt.c_cflag &= ~CSTOPB;
                break;
        case 2:
                opt.c_cflag |= CSTOPB;
                break;
        default:
                fprintf(stderr,"Unsupported stop bits\n");
                return -1;
    }

    /* Set input parity option */
    if (parity != 'n')
             opt.c_iflag |= INPCK;
    opt.c_cc[VTIME] = 100; // 10 seconds
    opt.c_cc[VMIN] = 0;

    tcflush(fd, TCIFLUSH); /* Update the options and do it NOW */
    if (tcsetattr(fd, TCSANOW, &opt) != 0)
    {
          perror("SetupSerial 3");
        return -1;
    }

    return 0;
}

/************* main() ********************/
int main()
{
    int fd;
    unsigned char rcv[32];
   
    fd = open("/dev/ttyS1", O_RDWR);  // read and write
    if(fd == -1)
    {
        printf("Can't open ttyS1!\n");
        exit(0);
    }
    set_speed(fd, B115200);   // set baud 115200

    if (set_data_format(fd, 8, 1, 'N')== -1)
    {
        printf("Data format Error!\n");
        exit(1);
    }

//recieve and send  
    while(1) {
        read(fd, rcv, 16);// from rs232
         printf("rcv %s\n", rcv);
       write(fd, rcv, 16);
    }


    close(fd);
        close(sd_fd);
    return(0);
}
进行while循环时,只能进行read函数,下面的printf函数不执行,write也不执行。但是用串口进行调试时,发送数据正常,发送以后也回显过来。但是把printf、write注释掉的话,也会回显发送的数据!!!小弟刚开始入手Linux,很多都不会,希望高手们帮帮忙,非常感谢!!
作者: 风云杰雨    时间: 2011-03-21 19:49
自己顶一下!!
作者: L_kernel    时间: 2011-03-21 19:57
自己顶一下!!
风云杰雨 发表于 2011-03-21 19:49
read和write的时候应该加一条判断是否成功的语句。
作者: 风云杰雨    时间: 2011-03-21 22:04
回复 3# L_kernel


    给read后面加了if语句,根本就不执行if-else语句!!更郁闷还有在read函数前面加上printf函数,printf函数也不执行,但是串口调试软件可以发字符串,也可以回显~~~
作者: L_kernel    时间: 2011-03-21 22:21
回复  L_kernel


    给read后面加了if语句,根本就不执行if-else语句!!更郁闷还有在read函数前面加 ...
风云杰雨 发表于 2011-03-21 22:04



    这样子吧,你最好用write向stdout输出,不要用printf,可能混合了标准I/O和文件I/O。
作者: guochaoguochao    时间: 2011-03-21 22:27
程序不运行或者屏蔽write还回显吗?
作者: 风云杰雨    时间: 2011-03-22 10:20
回复 6# guochaoguochao


    程序不运行就不回显,将write函数注释掉,运行程序也回显啊!!
作者: 风云杰雨    时间: 2011-03-22 10:51
回复 5# L_kernel


    要是write在read后面的话,就不会执行到write那里~~因为注释掉write也会回显回来!!要是write在read前面的话就可以回显write里的字符串!!
作者: 风云杰雨    时间: 2011-03-22 14:26
发现注释掉read以后,运行程序也是发送什么就回显什么;这样子的话就说明read函数函数没有在执行~~而是程序停留在那里了~~这又是什么原因呢?
作者: guochaoguochao    时间: 2011-03-22 21:30
你拿什么软件调试的串口啊,换个 软件试试
作者: net_robber    时间: 2011-03-23 09:01
循环是while(1)造成的,跟read和write没关系




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2