本篇文章为大家展示了C++中怎么实现串口通信,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
#include <stdio.h> #include <errno.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> int set_serial(int fd,int nSpeed,int nBits,char nEvent,int nStop) { struct termios newttys1,oldttys1; /*保存原有串口配置*/ if(tcgetattr(fd,&oldttys1)!=0) { perror("Setupserial 1"); return -1; } bzero(&newttys1,sizeof(newttys1)); newttys1.c_cflag|=(CLOCAL|CREAD ); /*CREAD 开启串行数据接收,CLOCAL并打开本地连接模式*/ newttys1.c_cflag &=~CSIZE;/*设置数据位*/ /*数据位选择*/ switch(nBits) { case 7: newttys1.c_cflag |=CS7; break; case 8: newttys1.c_cflag |=CS8; break; } /*设置奇偶校验位*/ switch( nEvent ) { case '0': /*奇校验*/ newttys1.c_cflag |= PARENB;/*开启奇偶校验*/ newttys1.c_iflag |= (INPCK | ISTRIP);/*INPCK打开输入奇偶校验;ISTRIP去除字符的第八个比特 */ newttys1.c_cflag |= PARODD;/*启用奇校验(默认为偶校验)*/ break; case 'E':/*偶校验*/ newttys1.c_cflag |= PARENB; /*开启奇偶校验 */ newttys1.c_iflag |= ( INPCK | ISTRIP);/*打开输入奇偶校验并去除字符第八个比特*/ newttys1.c_cflag &= ~PARODD;/*启用偶校验*/ break; case 'N': /*无奇偶校验*/ newttys1.c_cflag &= ~PARENB; break; } /*设置波特率*/ switch( nSpeed ) { case 2400: cfsetispeed(&newttys1, B2400); cfsetospeed(&newttys1, B2400); break; case 4800: cfsetispeed(&newttys1, B4800); cfsetospeed(&newttys1, B4800); break; case 9600: cfsetispeed(&newttys1, B9600); cfsetospeed(&newttys1, B9600); break; case 115200: cfsetispeed(&newttys1, B115200); cfsetospeed(&newttys1, B115200); break; default: cfsetispeed(&newttys1, B9600); cfsetospeed(&newttys1, B9600); break; } /*设置停止位*/ if( nStop == 1)/*设置停止位;若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB*/ { newttys1.c_cflag &= ~CSTOPB;/*默认为一位停止位; */ } else if( nStop == 2) { newttys1.c_cflag |= CSTOPB;/*CSTOPB表示送两位停止位*/ } /*设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时*/ newttys1.c_cc[VTIME] = 0;/*非规范模式读取时的超时时间;*/ newttys1.c_cc[VMIN] = 0; /*非规范模式读取时的最小字符数*/ tcflush(fd ,TCIFLUSH);/*tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来 */ /*激活配置使其生效*/ if((tcsetattr( fd, TCSANOW,&newttys1))!=0) { perror("com set error"); return -1; } return 0; }
SINGAL信号形式
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<sys/signal.h> #include<fcntl.h> #include<termios.h> #include<errno.h> #include <cstring> #define FALSE -1 #define TRUE 0 #define flag 1 #define noflag 0 int wait_flag = noflag; int STOP = 0; int res; 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,}; 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(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr[i]); cfsetospeed(&Opt, speed_arr[i]); status = tcsetattr(fd, TCSANOW, &Opt); if (status != 0) { perror("tcsetattr fd1"); return; } tcflush(fd, TCIOFLUSH); } } } 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 size\n"); 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 parity\n"); return (FALSE); } switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr, "Unsupported stop bits\n"); return (FALSE); } /* Set input parity option */ if (parity != 'n') options.c_iflag |= INPCK; tcflush(fd, TCIFLUSH); options.c_cc[VTIME] = 150; 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 signal_handler_IO(int status) { printf("received SIGIO signale.\n"); wait_flag = noflag; } int main() { printf("This program updates last time at %s %s\n", __TIME__, __DATE__); printf("STDIO COM1\n"); int fd; struct sigaction saio; fd = open("/dev/ttyUSB0", O_RDWR); if (fd == -1) { perror("serialport error\n"); } else { printf("open "); printf("%s", ttyname(fd)); printf(" succesfully\n"); } saio.sa_handler = signal_handler_IO; sigemptyset(&saio.sa_mask); saio.sa_flags = 0; saio.sa_restorer = NULL; sigaction(SIGIO, &saio, NULL); //allow the process to receive SIGIO fcntl(fd, F_SETOWN, getpid()); //make the file descriptor asynchronous fcntl(fd, F_SETFL, FASYNC); set_speed(fd, 9600); if (set_Parity(fd, 8, 1, 'N') == FALSE) { printf("Set Parity Error\n"); exit(0); } char buf[254]={0}; while (STOP == 0) { usleep(100000); /* after receving SIGIO ,wait_flag = FALSE,input is availabe and can be read */ if (wait_flag == 0) { memset(buf, 0, sizeof(buf)); res = read(fd, buf, 254); if ((int) buf[0] == 85) { for (int i = 0; i < 254; i++) { std::cout << std::hex << (int) buf[i] << " "; } std::cout << std::endl; } // printf("nread=%d,%s\n", res,buf); // if (res ==1) // STOP = 1; /*stop loop if only a CR was input */ wait_flag = flag; /*wait for new input */ } } close(fd); return 0; }
select阻塞形式
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<sys/signal.h> #include<fcntl.h> #include<termios.h> #include<errno.h> #include <cstring> #include <vector> #define FALSE -1 #define TRUE 0 #define flag 1 #define noflag 0 int wait_flag = noflag; int STOP = 0; int res; 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 STime stcTime; struct SAcc stcAcc; struct SGyro stcGyro; struct SAngle stcAngle; struct SMag stcMag; struct SDStatus stcDStatus; struct SPress stcPress; struct SLonLat stcLonLat; struct SGPSV stcGPSV; 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(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr[i]); cfsetospeed(&Opt, speed_arr[i]); status = tcsetattr(fd, TCSANOW, &Opt); if (status != 0) { perror("tcsetattr fd1"); return; } tcflush(fd, TCIOFLUSH); } } } 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 size\n"); 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 parity\n"); return (FALSE); } switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr, "Unsupported stop bits\n"); return (FALSE); } /* Set input parity option */ if (parity != 'n') options.c_iflag |= INPCK; tcflush(fd, TCIFLUSH); options.c_cc[VTIME] = 150; 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 signal_handler_IO(int status) { printf("received SIGIO signale.\n"); wait_flag = noflag; } class DATA { DATA(char type) { } }; int main() { std::vector<DATA> info; printf("This program updates last time at %s %s\n", __TIME__, __DATE__); printf("STDIO COM1\n"); int fd; fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { perror("serialport error\n"); } else { printf("open "); printf("%s", ttyname(fd)); printf(" succesfully\n"); } set_speed(fd, 9600); if (set_Parity(fd, 8, 1, 'N') == FALSE) { printf("Set Parity Error\n"); exit(0); } char buf; fd_set rd; int nread = 0; // char buffer[5] = {char(0xff), char(0xaa), char(0x03), char(0x05), char(0x00)}; // write(fd, buffer, 5); int lock = true; std::vector<char> data_st; while (1) { FD_ZERO(&rd); FD_SET(fd, &rd); while (FD_ISSET(fd, &rd)) { if (select(fd + 1, &rd, NULL, NULL, NULL) < 0) { perror("select error\n"); } else { while ((nread = read(fd, &buf, sizeof(buf))) > 0) { std::cout << std::hex << (int) buf << std::endl; if (lock && buf != 0x55) { lock=true; continue; } else { lock= false; // data_st.insert(data_st.begin(), (long) 0x55); data_st.push_back((long) buf); if (data_st.size() == 11) { char t_buf[11]; std::vector<char>::iterator it; int i = 0; long sum = 0; for (it = data_st.begin(); it < data_st.end(); it++) { t_buf[i] = *it; sum = (long) *it; i++; } data_st.clear(); if (sum == (2 * long(t_buf[11]))) { } switch (t_buf[1]) { case 0x51: memcpy(&stcAcc, &t_buf[2], 8); std::cout << "0x51 加速度" << " ax: " << (float) stcAcc.a[0] / 32768 * 16.0 * 9.8 << " ay: " << (float) stcAcc.a[1] / 32768 * 16.0 * 9.8 << " az: " << (float) stcAcc.a[2] / 32768 * 16.0 * 9.8 << " T: " << (float) (stcAcc.T) / 100 << std::endl; break; case 0x52: memcpy(&stcGyro, &t_buf[2], 8); break; case 0x53: memcpy(&stcAngle, &t_buf[2], 8); std::cout << "0x53 角度" << " agx: " << (float) stcAngle.Angle[0] / 32768 * 180 << " agy: " << (float) stcAngle.Angle[1] / 32768 * 180 << " az: " << (float) stcAngle.Angle[2] / 32768 * 180 << " T: " << (float) (stcAngle.T) / 100 << std::endl; break; case 0x54: memcpy(&stcMag, &t_buf[2], 8); std::cout << "0x54 磁场" " cx: " << (float)stcMag.h[0] << " cy: " << (float)stcMag.h[1] << " cz: " << (float)stcMag.h[2] << " cT: " << (float)stcMag.T/100 << std::endl; break; case 0x55: memcpy(&stcDStatus, &t_buf[2], 8); std::cout << "0x55" << std::endl; break; case 0x56: memcpy(&stcPress, &t_buf[2], 8); std::cout << "0x56" << std::endl; break; case 0x57: memcpy(&stcLonLat, &t_buf[2], 8); std::cout << "0x57" << std::endl; break; case 0x58: memcpy(&stcGPSV, &t_buf[2], 8); std::cout << "0x58" << std::endl; break; } // std::vector<char>::iterator it; // for(it=data_st.begin();it<data_st.end();it++){ // std::cout<<std::hex<<(int)*it<<" "; // } // std::cout<<std::endl; // exit(0); } } } } } } close(fd); return 0; }
上述内容就是C++中怎么实现串口通信,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。