Linux C 串列埠程式設計 詳解 例項

2021-08-03 07:05:54 字數 3775 閱讀 5234

linux下的串列埠程式設計其實與windows下無本質差別,說白了就是類似讀寫檔案一樣,對串列埠進行讀寫操作,用到的函式無非就是open,close,read,write函式等。具體的讀寫操作可分為下面四個步驟

開啟串列埠

配置串列埠

讀寫串列埠

關閉串列埠

串列埠配置主要包括波特率的配置,校驗位,停止位的設定等等。具體如下:

struct termios opt;       //建立設定結構體,配置串列埠即改變結構體內元素的內容

tcgetattr(fd, &opt); //儲存原有的配置,儲存在opt中

tcflush(fd, tcioflush); //刷清輸入輸出佇列

cfsetispeed(&opt, b9600); //設定輸入波特率

cfsetospeed(&opt, b9600); //設定輸出波特率

波特率可以設定115200,9600等等,值得注意的是在設定波特率的時候要在前面加b。接下來設定停止位,校驗位等等,依舊使用上述建立的結構體:

opt.c_cflag &= ~csize;   //遮蔽資料位

opt.c_cflag |= cs8; // 資料位為 8 ,cs7

for7

opt.c_cflag &= ~cstopb; // 一位停止位, 兩位停止為 |= cstopb

opt.c_cflag &= ~parenb; // 無校驗

opt.c_cflag |= parenb; //有校驗

opt.c_cflag &= ~parodd; // 偶校驗

opt.c_cflag |= parodd; // 奇校驗

接下來設定一些時間引數:

opt.c_cc[vtime] = 1;  //設定等待時間

opt.c_cc[vmin] = 100; //設定最小位元組數

時間引數只有在設定為阻塞模式下才能使用,vmin代表讀取的最小位元組數,當vtime引數設定為0時,只有當串列埠內的資料達到vmin長度時,read函式才會進行讀取操作;

當時間引數vtime不為0時,若串列埠內到達的資料未到達vmin,read函式將等待vtime時間之後對資料進行讀取;

另一種監測串列埠是否有資料到達的函式是select,使用此引數可以在確定串列埠內有資料時才對串列埠資料進行讀寫。

fd_zero(&rfds);

fd_set(fd,&rfds);

timeval timeout;

timeout.tv_sec = 10;

timeout.tv_usec = 0;

retval =select(fd+1,&rfds,null,null,null);

上述**通過設定控制代碼rfds來對fd進行監控,並根據fd的狀態,select函式將返回不同的值。其中timeout為超時等待時間,若不希望函式阻塞可以寫為:

retval =select(fd+1,&rfds,null,null,&timeout);
讀函式:

res = read(fd,buf,len);
寫函式:

n = write(fd, "str", len);

注意,當讀寫出錯是函式將返回值-1。

關閉串列埠簡單粗暴:

close(fd);
bool connectdevice()

// flushing is to be done after opening. this prevents first read and write to be spam'ish.

tcflush(fd, tcioflush);

int n = fcntl(fd, f_getfl, 0);

//恢復為阻塞模式

fcntl(fd, f_setfl, n & ~o_ndelay);

portset(fd,9600,8,"none","1",false,false);

connected = true;

return

1;}

int portset(int m_fd, int baudrate, int databits, const std::string & parity, const std::string & stop, bool softwarehandshake, bool hardwarehandshake)

//printf("tcgetattr() 3 success!\n");

speed_t _baud=0;

switch (baudrate)

cfsetospeed(&newtio, (speed_t)_baud);

cfsetispeed(&newtio, (speed_t)_baud);

/* we generate mark and space parity ourself. */

if (databits == 7 && (parity=="mark" || parity == "space"))

switch (databits)

newtio.c_cflag |= clocal | cread;

//parity

newtio.c_cflag &= ~(parenb | parodd);

if (parity == "even")

else

if (parity== "odd")

//hardware handshake

/* if (hardwarehandshake)

newtio.c_cflag |= crtscts;

else

newtio.c_cflag &= ~crtscts;*/

newtio.c_cflag &= ~crtscts;

//stopbits

if (stop=="2")

else

// newtio.c_iflag=ignpar | ignbrk;

newtio.c_iflag=ignbrk;

// newtio.c_iflag=ignpar;

//software handshake

if (softwarehandshake)

else

newtio.c_lflag=0;

newtio.c_oflag=0;

newtio.c_cc[vtime]=1;

newtio.c_cc[vmin]=60;

// tcflush(m_fd, tciflush);

if (tcsetattr(m_fd, tcsanow, &newtio)!=0)

//hardware handshake

if (hardwarehandshake)

else

/* if (on)

newtio.c_cflag |= crtscts;

else

newtio.c_cflag &= ~crtscts;*/

if (tcsetattr(m_fd, tcsanow, &newtio)!=0)

//printf("tcsetattr() 2 success!\n");

return

1;}

int readrev(char* revbuf)

else

}

Linux C程式設計例項

這是本人曾經寫過的 linux c 語言的例項。其中每個例項都是本人編譯通過,並且執行測試過的,所有的都是乙個完整的例項,幾乎沒有錯誤。因為例項還比較齊全,所以分享給大家,希望對於剛開始學 linux c 語言而又苦於例項練習少 動手程式設計能力差的人有所幫助。注意 所有linux c 語言的博文沒...

MFC 串列埠程式設計例項

vc串列埠程式設計從實現方法上一般分為兩種,一種使用mscomm控制項,這種方法比較簡單,軟體的移植性較低,在這裡介紹一種串列埠封裝類的使用方法。先看 commutils.cpp include stdafx.h include commutils.h include stdio.h const i...

linux C程式設計 popen函式詳解

include stdio.h file popen const char command,const char type int pclose file stream popen 函式 用 建立管道 的 方式 啟動 乙個 程序,並呼叫 shell.因為 管道 是被定義成 單向的,所以 type 引...