【程式碼參考網上的】linux串列埠程式設計學習筆記
阿新 • • 發佈:2019-01-28
1.串列埠通訊:
同步通訊:將很多字元組成一個資訊組進行傳送
非同步通訊:一個字元一符的傳送。(可靠性高,但是效率相對降低)
2.通過echo和cat來測試串列埠通訊 echo “Hello” >/dev/ttyS0 cat /dev/ttyS1
3.直接通過read/write函式來讀寫串列埠 用select()函式來監聽
4.struct termios opt;/*定義指向termios結構型別的指標opt*/
cfsetispeed(&opt,B9600);/*制定輸入波特率 ,9600bps*/
cfsetospeed(&opt,B9600);/*制定輸出波特率,9600bps*/
5.fd=open("/dev/ttyS0",O_RDWR|O_NOCTTY);/*以讀寫方式開啟裝置*/
int read(int fd,*buffer,length);
int write(int fd,*buffer,length);
int close(int fd);
6.串列埠操作需要的標頭檔案:
#include <stdio.h>/*標準輸入輸出定義*/
#include <stdlib.h>/*標準函式庫定義*/
#include <unistd.h>/*Unix標準函式定義*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>/*檔案控制定義*/
#include <termios.h>/*PPSIX終端控制定義*/
#include <errno.h>/*錯誤號定義*/
7.RTS/CTS請求資料傳送/清楚資料傳送
8.設定串列埠流程
1.儲存運來串列埠配置使用tcgetattr(fd,&oldtio)函式
struct termios newtio,oldtio;
tcgetattr(fd,&oldtio);
2.啟用選項有CLOCAL和CREAD,用於本地連線和接收使能
newtio.c_cflag |= CLOCAL|CREAD;
3.設定波特率,使用函式cfsetispeed,cfsetospeed
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
4.設定資料位,需使用掩碼設定
newtio.c_cflag&=~CSIZE;
newtio.c_cflag|=CS8;
5.設定奇偶校驗位,使用c_cflag和c_iflag.
設定奇校驗:
newtio.c_cflag|=PARENB;
newtio.c_cflag|=PARODD;
newtio.c_iflag|=(INPACK|ISTRIP);
設定偶校驗:
newtio.c_iflag|=(INPACK|ISTRIP);
newtio.c_cflag|=PARENB;
newtio.c_cflag&=~PARODD;
7.設定停止位,通過啟用c_cflag中的CSTOPB實現,若停止位為1,則
清除CSTOPB,若停止位為2,則啟用
newtio.c-cfalg&~CSTOPB;
8。設定最少字元和等待時間,對於接收字元和等待時間沒有特別要求時,可設為0;
newtio.c_cc[VTIME]=0;
newtio.c_cc[VMIN]=0;
9.處理要寫入的引用物件
tcflush函式刷清(拋棄)輸入快取(終端驅動程式已經接收到但是使用者程式尚未讀)或者輸出快取
int tcflush(int filedes,int queue);
queue數應當是下列三個常數之一:TCIFLUSH刷清輸入佇列,TCOFLUSH抒情輸出佇列,TCIOFLUSH刷清輸入輸出佇列
比如:tcflush(fd,TCIFLUSH);
同步通訊:將很多字元組成一個資訊組進行傳送
非同步通訊:一個字元一符的傳送。(可靠性高,但是效率相對降低)
2.通過echo和cat來測試串列埠通訊 echo “Hello” >/dev/ttyS0 cat /dev/ttyS1
3.直接通過read/write函式來讀寫串列埠 用select()函式來監聽
4.struct termios opt;/*定義指向termios結構型別的指標opt*/
cfsetispeed(&opt,B9600);/*制定輸入波特率 ,9600bps*/
cfsetospeed(&opt,B9600);/*制定輸出波特率,9600bps*/
5.fd=open("/dev/ttyS0",O_RDWR|O_NOCTTY);/*以讀寫方式開啟裝置*/
int read(int fd,*buffer,length);
int write(int fd,*buffer,length);
int close(int fd);
6.串列埠操作需要的標頭檔案:
#include <stdio.h>/*標準輸入輸出定義*/
#include <stdlib.h>/*標準函式庫定義*/
#include <unistd.h>/*Unix標準函式定義*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>/*檔案控制定義*/
#include <termios.h>/*PPSIX終端控制定義*/
#include <errno.h>/*錯誤號定義*/
7.RTS/CTS請求資料傳送/清楚資料傳送
8.設定串列埠流程
1.儲存運來串列埠配置使用tcgetattr(fd,&oldtio)函式
struct termios newtio,oldtio;
tcgetattr(fd,&oldtio);
2.啟用選項有CLOCAL和CREAD,用於本地連線和接收使能
newtio.c_cflag |= CLOCAL|CREAD;
3.設定波特率,使用函式cfsetispeed,cfsetospeed
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
4.設定資料位,需使用掩碼設定
newtio.c_cflag&=~CSIZE;
newtio.c_cflag|=CS8;
5.設定奇偶校驗位,使用c_cflag和c_iflag.
設定奇校驗:
newtio.c_cflag|=PARENB;
newtio.c_cflag|=PARODD;
newtio.c_iflag|=(INPACK|ISTRIP);
設定偶校驗:
newtio.c_iflag|=(INPACK|ISTRIP);
newtio.c_cflag|=PARENB;
newtio.c_cflag&=~PARODD;
7.設定停止位,通過啟用c_cflag中的CSTOPB實現,若停止位為1,則
清除CSTOPB,若停止位為2,則啟用
newtio.c-cfalg&~CSTOPB;
8。設定最少字元和等待時間,對於接收字元和等待時間沒有特別要求時,可設為0;
newtio.c_cc[VTIME]=0;
newtio.c_cc[VMIN]=0;
9.處理要寫入的引用物件
tcflush函式刷清(拋棄)輸入快取(終端驅動程式已經接收到但是使用者程式尚未讀)或者輸出快取
int tcflush(int filedes,int queue);
queue數應當是下列三個常數之一:TCIFLUSH刷清輸入佇列,TCOFLUSH抒情輸出佇列,TCIOFLUSH刷清輸入輸出佇列
比如:tcflush(fd,TCIFLUSH);
10啟用配置。用tsettattr();比如:tcsetattr(fd,TCSANOW,&newtio);
</pre><pre name="code" class="cpp"><span style="font-size:18px;"><strong>#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> #include <errno.h> /* **@名稱:open_port **@功能:開啟串列埠 **@引數 fd 型別 int 含義 檔案標號 **@引數 comport 型別 int 含義 使用者選擇的串列埠號 **@返回值: -1 開啟串列埠失敗 **@返回值: 0 開啟串列埠成功 */ int open_port(int fd,int comport) { char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"}; long vdisable; if(1==comport) { fd=open(dev[0],O_RDWR|NOCTTY|NDELAY); if(-1==fd) { perror("can`t open serial port!!!\n"); return -1; } else { printf("open ttyS0"); } } else if(comport==2) { fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY); if (-1 == fd) { perror("Can't Open Serial Port"); return(-1); } else { printf("open ttyS1 .....\n"); } } else if (comport==3) { fd = open( "/dev/ttyS2", O_RDWR|O_NOCTTY|O_NDELAY); if (-1 == fd) { perror("Can't Open Serial Port"); return(-1); } else { printf("open ttyS2 .....\n"); } } /*然後恢復串列埠的狀態為阻塞狀態,用於等待串列埠資料的讀入,用fcntl函式: **fcntl(fd,F_SETFL,0); //F_SETFL:設定檔案flag為0,即預設,即阻塞狀態**** ** 接著測試開啟的檔案描述符是否應用一個終端裝置,以進一步確認串列埠是否正確開啟. **isatty(STDIN_FILENO); */ if(fcntl(fd,F_SETFL,0)<0) { printf("fcntl failed!!!\n"); } else { printf("fcntl=%d\n",fcntl(fd,F_SETFL,0)); } if(0==isatty(STDIN_FILENO)) { printf("standard input is not a terminal device!!!\n"); } else { printf("isatty success!!\n"); } printf("fd-open%d\n",fd); return fd; } /* **@名稱:set_port **@功能:設定串列埠 **@引數 fd 型別 int 含義 檔案標號 **@引數 nSpeed 型別 int 含義 速度 **@引數 nBits 型別 int 含義 資料位 **@引數 nEvent型別 int 含義 奇偶校驗 **@引數 nStop型別 int 含義 停止位 **@返回值: -1 設定串列埠失敗 **@返回值: 0 設定串列埠成功 */ int set_port(int fd,int nSpeed,int nBits,char nEvent,int nStop) { struct termios newtio,oldtio; if(tcgetattr(fd,&oldtio)!=0) {//獲取終端相關引數失敗 perror("setupSerial 1"); return -1; } bzero(&newtio,sizeof(newtio));//值前n個位元組為0 /* ** 2>啟用選項有CLOCAL和CREAD,用於本地連線和接收使用 ** newtio.c_cflag | = CLOCAL | CREAD; */ newtio.c_cflag|=CLOACAL|CREAD; newtio.c_cflag&=~CSIZE;//將資料位清零 switch(nBits) { case 7: newtio.c_cflag|=CS7; break; case 8: newtio.c_cflag|=CS8; break; } switch(nEvent) { case 'o'://奇校驗 case 'O': newtio.c_cflag|=PARENB; newtio.c_cflag|=PARODD; newtio.c_iflag|=(INPCK|ISTRIP); case 'e'://偶校驗 case 'E': newtio.c_iflag|=(INPCK|ISTRIP); newtio.c_cflag|=PARENB; newtio.c_cflag&=~PARODD; break; case 'n'://無校驗 case 'N': newtio.c_cflag&=~PARENB; break; } switch(nSpeed) { case 4800: cfsetispeed(&newtio, B4800); cfsetospeed(&newtio, B4800); break; case 115200: cfsetispeed(&newtio,B115200); cfsetospeed(&newtio,B115200); break; default: printf("set error!!!\n"); } switch(nStop) { case 1: newtio.c_cflag&=~CSTOPB; break; case 2: newtio.c_cflag|=CSTOPB; break; } newtio.c_cc[VTIME]=0; newtio.c_cc[VMIN]=0; tcflush(fd,TCIFLUSH); if((tcsetattr(fd,TCSANOW,&newtio))!=0) { perror("com set error!!!\n"); return -1; } printf("set done!!!\n"); return 0; } int main() { int fd;//用於接收開啟串列埠的狀態 int i;//用於接收設定串列埠的狀態 int nread;//用於接收read的返回值 char buff[]="zhang lei\n"; if((fd=open_port(fd,1))<0) {//開啟串列埠不成功 perror("open_port error!!!\n"); return -1; } if((i=set_port(fd,115200,8,'N',1))<0) {//設定串列埠不成功 perror("set_port error!!!\n"); return -1; } printf("fd=%d",fd); nread=read(fd,buff,8); close(fd); return 0; }</strong></span>