Linux/Android系統開發 串列埠引數配置原始碼 serial.c/serial.cpp
阿新 • • 發佈:2019-01-10
該驅動適用於採用linux和android系統平臺的C/C++開發。
用於配置串列埠相關引數:埠選擇、阻塞非阻塞、波特率、停止位、資料位、校驗位等。
注:需要系統開啟串列埠操作許可權,否則配置失敗。
本驅動在MTK8735平臺上驗證測試,其它平臺修改串列埠埠名稱即可。
原始碼:
serial.h // // Created by taxiang&xuezi on 2018/4/2. // #ifndef NDKAPPECG_SERIAL_H #define NDKAPPECG_SERIAL_H #ifdef SERIAL_GLOBALS #define SERIAL_EXT #else #define SERIAL_EXT extern #endif #define SERIAL_DBG 1 SERIAL_EXT s32 uart_open(s32 fd,s32 port,s8 block); SERIAL_EXT s32 uart_set(s32 fd, s32 nSpeed, s32 nBits, s8 nEvent, s32 nStop); #endif //NDKAPPECG_SERIAL_H
serial.c/serial.cpp // // Created by taxiang&xuezi on 2018/4/2. // #define SERIAL_GLOBALS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <errno.h> #include <fcntl.h> #include <termios.h> #include <time.h> #include <unistd.h> #include <sys/stat.h> #ifdef SERIAL_DBG #define SERIAL_PRINT0(X) printf(X); #define SERIAL_PRINT1(X,A) printf (X,A); #define SERIAL_PRINT2(X,A,B) printf (X,A,B); #define SERIAL_PRINT3(X,A,B,C) printf (X,A,B,C); #define SERIAL_PRINT4(X,A,B,C,D) printf (X,A,B,C,D); #else #define SERIAL_PRINT0(X) #define SERIAL_PRINT1(X,A) #define SERIAL_PRINT2(X,A,B) #define SERIAL_PRINT3(X,A,B,C) #define SERIAL_PRINT4(X,A,B,C) #endif /******************************************************************************* * 函式名稱: s32 uart_open(s32 fd,s32 port,s8 block) * 函式功能: 開啟串列埠 * 輸入引數: * 輸出引數: * 返回值 : *******************************************************************************/ s32 uart_open(s32 fd,s32 port,s8 block) { s8 *dev[]={"/dev/ttyMT0","/dev/ttyMT1","/dev/ttyMT2","/dev/ttyMT3"}; fd = open(dev[port], O_RDWR|O_NOCTTY|O_NONBLOCK);//nblock if(fd == -1){ SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__); return -1; } if(block == 0){//nblock // if(fcntl(fd, F_SETFL, FNDELAY)<0){ // SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__); // return -1; // } }else{//block if(fcntl(fd, F_SETFL, 0)<0){ SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__); return -1; } } // if(isatty(STDIN_FILENO)==0){ // SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__); // return -1; // } // SERIAL_PRINT0("uart open done\n"); return fd; } /******************************************************************************* * 函式名稱: s32 uart_set(s32 fd, s32 nSpeed, s32 nBits, s8 nEvent, s32 nStop) * 函式功能: 配置串列埠 * 輸入引數: * 輸出引數: * 返回值 : *******************************************************************************/ s32 uart_set(s32 fd, s32 nSpeed, s32 nBits, s8 nEvent, s32 nStop) { struct termios newtio; struct termios oldtio; if(tcgetattr(fd,&oldtio) != 0){ SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__); return -1; } bzero(&newtio,sizeof(newtio)); newtio.c_cflag |= CLOCAL |CREAD; /***********資料位選擇****************/ newtio.c_cflag &= ~CSIZE; switch(nBits){ case 7: newtio.c_cflag |= CS7; break; case 8: newtio.c_cflag |= CS8; break; default : newtio.c_cflag |= CS8; break; } /***********校驗位選擇****************/ switch(nEvent){ case 'n': case 'N': newtio.c_cflag &= ~PARENB; newtio.c_iflag &= ~INPCK; break; case 'o': case 'O': newtio.c_cflag |= PARENB; newtio.c_cflag |= PARODD; newtio.c_iflag |= INPCK; break; case 'e': case 'E': newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD; newtio.c_iflag |= INPCK; break; case 's': case 'S': newtio.c_cflag |= PARENB; newtio.c_cflag &= ~CSTOPB; newtio.c_iflag |= INPCK; default : newtio.c_cflag &= ~PARENB; newtio.c_iflag &= ~INPCK; break; } /***********波特率選擇****************/ switch(nSpeed){ case 2400: cfsetispeed(&newtio,B2400); cfsetospeed(&newtio,B2400); break; case 4800: cfsetispeed(&newtio,B4800); cfsetospeed(&newtio,B4800); break; case 9600: cfsetispeed(&newtio,B9600); cfsetospeed(&newtio,B9600); break; case 57600: cfsetispeed(&newtio,B57600); cfsetospeed(&newtio,B57600); break; case 115200: cfsetispeed(&newtio,B115200); cfsetospeed(&newtio,B115200); break; case 230400: cfsetispeed(&newtio,B230400); cfsetospeed(&newtio,B230400); break; case 460800: cfsetispeed(&newtio,B460800); cfsetospeed(&newtio,B460800); break; case 500000: cfsetispeed(&newtio,B500000); cfsetospeed(&newtio,B500000); break; case 576000: cfsetispeed(&newtio,B576000); cfsetospeed(&newtio,B576000); break; case 921600: cfsetispeed(&newtio,B921600); cfsetospeed(&newtio,B921600); break; case 2000000: cfsetispeed(&newtio,B2000000); cfsetospeed(&newtio,B2000000); break; default: cfsetispeed(&newtio,B9600); cfsetospeed(&newtio,B9600); break; } /***********停止位選擇****************/ switch(nStop){ case 1: newtio.c_cflag &= ~CSTOPB; break; case 2: newtio.c_cflag |= CSTOPB; break; default: newtio.c_cflag &= ~CSTOPB; break; } //VTIME和VMIN僅在阻塞模式下有效 newtio.c_cc[VTIME] = 0; newtio.c_cc[VMIN] = 1; tcflush(fd,TCIFLUSH); if((tcsetattr(fd,TCSANOW,&newtio)) != 0){ SERIAL_PRINT3("%s [%s:%d]\n", strerror(errno), __FILE__, __LINE__); return -1; } SERIAL_PRINT4("uart set done:%d %d %C %d\n",nSpeed,nBits,nEvent,nStop); return 0; }