历史上的今天
今天是:2025年04月07日(星期一)
2020年04月07日 | linux系统与51单片机实现串口数据交互
2020-04-07 来源:eefocus
// 以下是 用于 linux IO INPUT AND OUT PUT
参考代码详细 参考一下网站 写得都很详细 其中函数代码和所遇问题测试摘自一下网站,感谢他们提供的函数资源
大家可以先去看看函数模型以及方法 个人觉得他们归纳的比较好
//http://www.cnblogs.com/meronzhang/archive/2012/11/24/2786165.html
//http://www.cnblogs.com/meronzhang/archive/2012/11/24/2786166.html
//http://www.doc88.com/p-9045754154843.html
以下是代码 其中,mian函数和51函数为自己写的测试代码 测试通过,不过仍有bug,就是数据没清空,导致数据一直在接收
#include #include #include #include #include #include #include #include #include #define TRUE 1 #define FALSE -1 int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, }; int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, }; struct termio { unsigned short c_iflag; /* 输入模式标志 */ unsigned short c_oflag; /* 输出模式标志 */ unsigned short c_cflag; /* 控制模式标志*/ unsigned short c_lflag; /* local mode flags */ unsigned char c_line; /* line discipline */ unsigned char c_cc[NCC]; /* control characters */ }; /** *@brief 设置串口通信速率 *@param fd 类型 int 打开串口的文件句柄 *@param speed 类型 int 串口速度 *@return void */ void set_speed(int fd, int speed) { int i; int status; struct termios Opt; tcgetattr(fd, &Opt); for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) { if (speed == name_arr[i]) { /** * tcflush函数刷清(抛弃)输入缓存(终端驱动程序已接收到,但用户程序尚未读)或输出缓存(用户程序已经写,但尚未发送)。queue参数应是下列三个常数之一: * TCIFLUSH刷清输入队列。 * TCOFLUSH刷清输出队列。 * TCIOFLUSH刷清输入、输出队列。 */ tcflush(fd, TCIOFLUSH);//设置前flush cfsetispeed(&Opt, speed_arr[i]); cfsetospeed(&Opt, speed_arr[i]); //通过tcsetattr函数把新的属性设置到串口上。 //tcsetattr(串口描述符,立即使用或者其他标示,指向termios的指针) status = tcsetattr(fd, TCSANOW, &Opt); if (status != 0) { perror("tcsetattr fd1"); return; } tcflush(fd,TCIOFLUSH); //设置后flush } } } /**** *@brief 设置串口数据位,停止位和效验位 *@param fd 类型 int 打开的串口文件句柄 *@param databits 类型 int 数据位 取值 为 7 或者8 *@param stopbits 类型 int 停止位 取值为 1 或者2 *@param parity 类型 int 效验类型 取值为N,E,O,,S */ int set_Parity(int fd, int databits, int stopbits, int parity) { struct termios options; if (tcgetattr(fd, &options) != 0) { perror("SetupSerial 1"); return (FALSE); } options.c_cflag &= ~CSIZE; switch (databits) /*设置数据位数*/ { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr,"Unsupported data sizen"); return (FALSE); } switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; /* Clear parity enable */ options.c_iflag &= ~INPCK; /* Enable parity checking */ break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'e': case 'E': options.c_cflag |= PARENB; /* Enable parity */ options.c_cflag &= ~PARODD; /* 转换为偶效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'S': case 's': /*as no parity*/ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; break; default: fprintf(stderr,"Unsupported parityn"); return (FALSE); } /* 设置停止位*/ switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr,"Unsupported stop bitsn"); return (FALSE); } /* Set input parity option */ if (parity != 'n') options.c_iflag |= INPCK; tcflush(fd, TCIFLUSH); options.c_cc[VTIME] = 50; /* 设置超时5 seconds*/ options.c_cc[VMIN] = 0; /* Update the options and do it NOW */ if (tcsetattr(fd, TCSANOW, &options) != 0) { perror("SetupSerial 3"); return (FALSE); } return (TRUE); } void main() { int fd; struct termios Opt; //struct termios Opt; // ttyUSB0 是usb转串口数据线 有时为ttyUSB0 驱动是ch340 百度 有linux CH340驱动 或者虚拟机会自动安装驱动 fd=open("/dev/ttyUSB0",O_RDWR|O_NOCTTY); //|O_NOCTTY //用文件描述符打开 struct timeval timeout; //构造串口机构体 if(-1==fd) //打开是否成功 { perror("IO error"); } int set_fd; set_fd=set_Parity(fd,8,1,'n'); //设置串口传输数据模式 Opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/ Opt.c_oflag &= ~OPOST; /*Output*/ set_speed(fd,4800); //以下代码注释代码属于测试代码 并未实现 不需要可除去 已经有函数体实现 原始模式除外 //tcgetattr(fd, &Opt); //cfsetispeed(&Opt,B4800); // cfsetospeed(&Opt,B4800); //tcsetattr(fd,TCSANOW,&Opt); // tcgetattr(fd,B4800); // cfsetospeed(&Opt,B4800); // tcsetattr(fd,TCSANOW,&Opt); char IO_read_buf[10]= {0}; int read_fd=-1; int write_fd=-1; int fork_fd=-1; fork_fd=fork(); //while(1) { /*****采用进程创建的方法 一个读,一个写, 亦可以用多线程方法。 ****/ //读操作 if(fork_fd>0) { while(1) { read_fd=read(fd,IO_read_buf,10-1); //printf("%d data=%sn",read_fd,IO_read_buf); if(read_fd>0) { if(IO_read_buf[0]!='




