linux串口收发程序

2019-07-13 08:36发布

最近在测试一个开发板的串口是否可以正常使用,开发板使用了linux系统,因此就写了个串口的收发程序来测试。 1.首先使用open函数打开串口,在linux中一切设备都被当做文件来看待,测试的串口所对应的文件为  /dev/ttySAC。 fd = open("/dev/ttySAC2",O_RDWR|O_NOCTTY); 得到了一个文件描述符fd。 2.然后就是对这个串口进行设置,设置其波特率、数据位、校验位、停止位。 tcgetattr(fd,&opt);

cfsetispeed(&opt,B115200);

cfsetospeed(&opt,B115200);

   opt.c_cflag |= (CLOCAL | CREAD);                  

// 无校验 8位数据位1位停止位

       opt.c_cflag &= ~PARENB;                         

       opt.c_cflag &= ~CSTOPB;

       opt.c_cflag &= ~CSIZE;

// 8个数据位

       opt.c_cflag |= CS8;

// 原始数据输入

       opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

       opt.c_oflag &= ~(OPOST);

// 设置等待时间和最小接收字符数

       opt.c_cc[VTIME]    = 0;                          

       opt.c_cc[VMIN]     = 0;  

// 处理未接收的字符

       tcflush(fd, TCIFLUSH);  
       tcsetattr(fd,TCSANOW,&opt);
其中opt的类型为 struct termios { tcflag_t c_iflag; /* 输入参数 */ tcflag_t c_oflag; /* 输出参数 */ tcflag_t c_cflag; /* 控制参数*/ tcflag_t c_ispeed; /* 输入波特率 */ tcflag_t c_ospeed; /* 输出波特率 */ cc_t c_line; /* 线控制 */ cc_t c_cc[NCCS]; /* 控制字符*/ }; 个人感觉比较重要的是对于 opt.c_cc[VTIME]    = 0;                          

 opt.c_cc[VMIN]     = 0;   的设置 MIN指定了一个read返回前的最小字节数,TIME指定等待数据到达的分秒数。 共有下面四种情形: A.MIN>0,TIME>0 注意:这个时候的TIME为字节间定时,只在第一个字节被接收时启动。在该定时器超时之前,若已接收到MIN个字节,则read返回MIN个字节。如果在接收到MIN个字节之前,定时器已经超时,则read返回MIN个字节。如果在接到MIN个字节之前,该定时器已经超时,则read返回已经接收到的字节数,因为定时器实在接收到一个字节之后开始启动,所以最少会返回一个字节。如果一只收不到数据,那么read这个函数就会一直阻塞 B.MIN=0,TIME>0 TIME指定了一个调用read时的读定时器,当接收到一个字节时或者超时后才会返回。 C.MIN>0,TIME=0 在接收到MIN个字节之前永远不会返回,有可能永远阻塞在这里。 D.MIN=0,TIME=0 如果有数据的时候,read最多会返回所要求的字节数。如果无数据,则read会立即返回0.这种情况类似于recv的最后一个option为MSG_DONTWAIT时的情形。 在这里都设置为0,说明read执行之后,如果没有读到数据,会立即返回。 3.然后就是读取和接收串口数据了 while(1)
    {        
                if(write(fd,wb,6)!=6)
                    printf("write error ");
                retv=read(fd,buf,1024);   
                
                if(retv==-1)
                    
                 printf("read failed ");
                
                if(retv>0)
                 {
                     printf("receive data is %s ",buf);
                
                 }
                 usleep(10000);
        }        
首先向串口中写入数据,然后再从串口中读取数据,这时候只需要把这个串口的发送的引脚和接收的引脚相连,那么这个串口就能接收到自己发送的数据。并且休眠10ms。 完整程序如下: #include /*标准输入输出定义*/ #include /*标准函数库定义*/ #include /*Unix 标准函数定义*/ #include #include #include /*文件控制定义*/ #include /*PPSIX 终端控制定义*/ #include /*错误号定义*/ #define FALSE -1 #define TRUE 0 int set_Parity(int fd,int databits,int stopbits,int parity); int main() { char buf[1024]; char wb[6]="hello"; int fd,flag_close,retv; struct termios opt; fd = open("/dev/ttySAC2",O_RDWR|O_NOCTTY); if(fd==-1) { printf("open failed "); exit (0); } else printf("open success "); tcgetattr(fd,&opt); cfsetispeed(&opt,B115200); cfsetospeed(&opt,B115200); opt.c_cflag |= (CLOCAL | CREAD); // 无校验 8位数据位1位停止位 opt.c_cflag &= ~PARENB; opt.c_cflag &= ~CSTOPB; opt.c_cflag &= ~CSIZE; // 8个数据位 opt.c_cflag |= CS8; // 原始数据输入 opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); opt.c_oflag &= ~(OPOST); // 设置等待时间和最小接收字符数 opt.c_cc[VTIME] = 0; opt.c_cc[VMIN] = 0; // 处理未接收的字符 tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&opt); printf("start send "); while(1) { if(write(fd,wb,6)!=6) printf("write error "); retv=read(fd,buf,1024); if(retv==-1) printf("read failed "); if(retv>0) { printf("receive data is %s ",buf); } usleep(10000); } flag_close = close(fd); if(flag_close == -1) printf("Close the Device failed "); return 0; }