1. 程式人生 > >LINUX 使用tcgetattr與tcsetattr函式控制終端

LINUX 使用tcgetattr與tcsetattr函式控制終端

為了便於通過程式來獲得和修改終端引數,Linux還提供了tcgetattr函式和tcsetattr函式。tcgetattr用於獲取終端的相關引數,而tcsetattr函式用於設定終端引數。這兩個函式的具體資訊如表6.2所示。

表6.2 tcgetattr函式和tcsetattr函式

標頭檔案

 

函式形式

int tcgetattr(int fd, struct termios *termios_p);

int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);

返回值

成功

失敗

是否設定errno

0

−1

說明:tcgetattr函式用於獲取與終端相關的引數。引數fd為終端的檔案描述符,返回的結果儲存在termios結構體中,該結構體一般包括如下的成員:

 

 
  1. tcflag_t c_iflag;

  2. tcflag_t c_oflag;

  3. tcflag_t c_cflag;

  4. tcflag_t c_lflag;

  5. cc_t c_cc[NCCS];

  6.  


 

其具體意義如下。

 
c_iflag:輸入模式標誌,控制終端輸入方式,具體引數如表6.3所示。

表6.3 c_iflag引數表

鍵    值

說    明

IGNBRK

忽略BREAK鍵輸入

BRKINT

如果設定了IGNBRK,BREAK鍵的輸入將被忽略,如果設定了BRKINT ,將產生SIGINT中斷

IGNPAR

忽略奇偶校驗錯誤

PARMRK

標識奇偶校驗錯誤

INPCK

允許輸入奇偶校驗

ISTRIP

去除字元的第8個位元

INLCR

將輸入的NL(換行)轉換成CR(回車)

IGNCR

忽略輸入的回車

ICRNL

將輸入的回車轉化成換行(如果IGNCR未設定的情況下)

IUCLC

將輸入的大寫字元轉換成小寫字元(非POSIX)

IXON

允許輸入時對XON/XOFF流進行控制

IXANY

輸入任何字元將重啟停止的輸出

IXOFF

允許輸入時對XON/XOFF流進行控制

IMAXBEL

當輸入佇列滿的時候開始響鈴,Linux在使用該引數而是認為該引數總是已經設定

c_oflag:輸出模式標誌,控制終端輸出方式,具體引數如表6.4所示。

表6.4 c_oflag引數

鍵    值

說    明

OPOST

處理後輸出

OLCUC

將輸入的小寫字元轉換成大寫字元(非POSIX)

ONLCR

將輸入的NL(換行)轉換成CR(回車)及NL(換行)

OCRNL

將輸入的CR(回車)轉換成NL(換行)

ONOCR

第一行不輸出回車符

ONLRET

不輸出回車符

OFILL

傳送填充字元以延遲終端輸出

OFDEL

以ASCII碼的DEL作為填充字元,如果未設定該引數,填充字元將是NUL(‘\0’)(非POSIX)

NLDLY

換行輸出延時,可以取NL0(不延遲)或NL1(延遲0.1s)

CRDLY

回車延遲,取值範圍為:CR0、CR1、CR2和 CR3

TABDLY

水平製表符輸出延遲,取值範圍為:TAB0、TAB1、TAB2和TAB3

BSDLY

空格輸出延遲,可以取BS0或BS1

VTDLY

垂直製表符輸出延遲,可以取VT0或VT1

FFDLY

換頁延遲,可以取FF0或FF1

c_cflag:控制模式標誌,指定終端硬體控制資訊,具體引數如表6.5所示。

 

LINUX 使用tcgetattr函式與tcsetattr函式控制終端二

2009-11-24 15:30

表6.5 c_oflag引數

鍵    值

說    明

CBAUD

波特率(4+1位)(非POSIX)

CBAUDEX

附加波特率(1位)(非POSIX)

CSIZE

字元長度,取值範圍為CS5、CS6、CS7或CS8

CSTOPB

設定兩個停止位

CREAD

使用接收器

PARENB

使用奇偶校驗

PARODD

對輸入使用奇偶校驗,對輸出使用偶校驗

HUPCL

關閉裝置時掛起

CLOCAL

忽略調變解調器線路狀態

CRTSCTS

使用RTS/CTS流控制

c_lflag:本地模式標誌,控制終端編輯功能,具體引數如表6.6所示。

 

表6.6 c_lflag引數

鍵    值

說    明

ISIG

當輸入INTR、QUIT、SUSP或DSUSP時,產生相應的訊號

ICANON

使用標準輸入模式

XCASE

在ICANON和XCASE同時設定的情況下,終端只使用大寫。如果只設置了XCASE,則輸入字元將被轉換為小寫字元,除非字元使用了轉義字元(非POSIX,且Linux不支援該引數)

ECHO

顯示輸入字元

ECHOE

如果ICANON同時設定,ERASE將刪除輸入的字元,WERASE將刪除輸入的單詞

ECHOK

如果ICANON同時設定,KILL將刪除當前行

ECHONL

如果ICANON同時設定,即使ECHO沒有設定依然顯示換行符

ECHOPRT

如果ECHO和ICANON同時設定,將刪除打印出的字元(非POSIX)

TOSTOP

向後臺輸出傳送SIGTTOU訊號

c_cc[NCCS]:控制字元,用於儲存終端驅動程式中的特殊字元,如輸入結束符等。c_cc中定義瞭如表6.7所示的控制字元。

表6.7 c_cc支援的控制字元

巨集

說    明

巨集

說    明

VINTR

Interrupt字元

VEOL

附加的End-of-file字元

VQUIT

Quit字元

VTIME

非規範模式讀取時的超時時間

VERASE

Erase字元

VSTOP

Stop字元

VKILL

Kill字元

VSTART

Start字元

VEOF

End-of-file字元

VSUSP

Suspend字元

VMIN

非規範模式讀取時的最小字元數

   

tcsetattr函式用於設定終端的相關引數。引數fd為開啟的終端檔案描述符,引數optional_actions用於控制修改起作用的時間,而結構體termios_p中儲存了要修改的引數。
optional_actions可以取如下的值。
 
TCSANOW:不等資料傳輸完畢就立即改變屬性。
TCSADRAIN:等待所有資料傳輸結束才改變屬性。
TCSAFLUSH:清空輸入輸出緩衝區才改變屬性。

錯誤資訊:
EBADF:非法的檔案描述符。
EINTR:tcsetattr函式呼叫被訊號中斷。
EINVAL:引數optional_actions使用了非法值,或引數termios中使用了非法值。
ENCTTY:非終端的檔案描述符。

例項演練:
程式p6.2.c通過修改終端控制字元,將終端輸入結束符由“Ctrl+D”,修改成了“Ctrl+G”。首先,程式呼叫tcgetattr函式獲得標準 輸入的termios資訊,將termios結構體中的c_cc[VEOF]控制字元的修改成0x07(即Ctrl+G);然後,使用tcsetattr 函式將修改後的termios引數設定到終端中。具體程式碼如下所示:

 
  1. //p6.2.c 修改終端控制字元示例

  2. #include

  3. #include

  4. #include

  5. #include

  6.  
  7. int main(void){

  8. //term用於儲存獲得的終端引數資訊

  9. struct termios term;

  10. int err;

  11.  
  12. //獲得標準輸入的終端引數,將獲得的資訊儲存在term變數中

  13. if(tcgetattr(STDIN_FILENO,&term)==-1){

  14. perror("Cannot get standard input description");

  15. return 1;

  16. }

  17.  
  18. //修改獲得的終端資訊的結束控制字元

  19. term.c_cc[VEOF]=(cc_t)0x07;

  20.  
  21. //使用tcsetattr函式將修改後的終端引數設定到標準輸入中

  22. //err用於儲存函式呼叫後的結果

  23. err=tcsetattr(STDIN_FILENO,TCSAFLUSH,&term);

  24.  
  25. //如果err為-1或是出現EINTR錯誤(函式執行被訊號中斷),

  26. //給出相關出錯資訊

  27. if(err==-1 && err==EINTR){

  28. perror("Failed to change EOF character");

  29. return 1;

  30. }

  31.  
  32. return 0;

  33. }

 

使用gcc編譯p6.2.c程式,得到名為p6.2的可執行程式。在執行p6.2程式前,按“Ctrl+D”可以使終端結束。執行p6.2程式後,按“Ctrl+D”失去了作用,而輸入“Ctrl+G”實現了原來“Ctrl+D”的功能

轉自:http://blog.chinaunix.net/uid-10747583-id-97303.html

======================================================================================================================

 

串列埠操作需要的標頭檔案

 
  1. #include /*標準輸入輸出定義*/

  2.  
  3. #include /*標準函式庫定義*/

  4.  
  5. #include /*Unix 標準函式定義*/

  6.  
  7. #include

  8.  
  9. #include

  10.  
  11. #include /*檔案控制定義*/

  12.  
  13. #include /*PPSIX 終端控制定義*/

  14.  
  15. #include /*錯誤號定義*/


 

 

1.開啟串列埠

在前面已經提到linux下的串列埠訪問是以裝置檔案形式進行的,所以開啟串列埠也即是開啟檔案的操作。函式原型可以如下所示:

 

int open(“DE_name”,int open_Status)

 

引數說明:

(1)DE_name:要開啟的裝置檔名

比如要開啟串列埠1,即為/dev/ttyS0。

(2)open_Status:檔案開啟方式,可採用下面的檔案開啟模式:

  O_RDONLY:以只讀方式開啟檔案

  O_WRONLY:以只寫方式開啟檔案

O_RDWR:以讀寫方式開啟檔案

O_APPEND:寫入資料時新增到檔案末尾

O_CREATE:如果檔案不存在則產生該檔案,使用該標誌需要設定訪問許可權位mode_t

O_EXCL:指定該標誌,並且指定了O_CREATE標誌,如果開啟的檔案存在則會產生一個錯誤

O_TRUNC:如果檔案存在並且成功以寫或者只寫方式開啟,則清除檔案所有內容,使得檔案長度變為0

O_NOCTTY:如果開啟的是一個終端裝置,這個程式不會成為對應這個埠的控制終端,如果沒有該標誌,任何一個輸入,例如鍵盤中止訊號等,都將影響程序。

O_NONBLOCK:該標誌與早期使用的O_NDELAY標誌作用差不多。程式不關心DCD訊號線的狀態,如果指定該標誌,程序將一直在休眠狀態,直到DCD訊號線為0。

函式返回值:

成功返回檔案描述符,如果失敗返回-1

例如:

在 Linux 下串列埠檔案是位於 /dev 下的。串列埠一 為 /dev/ttyS0,串列埠二 為 /dev/ttyS1。開啟串列埠是通過使用標準的檔案開啟函式操作:

 
  1. int fd;

  2.  
  3. /*以讀寫方式開啟串列埠*/

  4.  
  5. fd = open( "/dev/ttyS0", O_RDWR);

  6.  
  7. if (fd==-1)

  8.  
  9. {

  10.  
  11. /* 不能開啟串列埠一*/

  12.  
  13. perror(" 提示錯誤!");

  14.  
  15. }


 

2.設定串列埠

最基本的設定串列埠包括波特率設定,效驗位和停止位設定。串列埠的設定主要是設定

 struct termios 結構體的各成員值。

 
  1. struct termio

  2.  
  3. { unsigned short c_iflag; /* 輸入模式標誌 */

  4.  
  5. unsigned short c_oflag; /* 輸出模式標誌 */

  6.  
  7. unsigned short c_cflag; /* 控制模式標誌*/

  8.  
  9. unsigned short c_lflag; /* local mode flags */

  10.  
  11. unsigned char c_line; /* line discipline */

  12.  
  13. unsigned char c_cc[NCC]; /* control characters */

  14.  
  15. };


 

設定這個結構體很複雜,我這裡就只說說常見的一些設定:

2.1 波特率設定

波特率的設定定義在,其包含在標頭檔案裡。

常用的波特率常數如下:

B0-------à0                     B1800-------à1800

B50-----à50                    B2400------à2400

B75-----à75                    B4800------à4800

B110----à110                 B9600------à9600

B134----à134.5              B19200-----à19200

B200----à200                 B38400------à38400

B300----à300                 B57600------à57600

B600----à600                 B76800------à76800

B1200---à1200              B115200-----à115200

假定程式中想要設定通訊的波特率,使用cfsetispeed( )和cfsetospeed( )函式來操作,獲取波特率資訊是通過cfgetispeed()和cfgetospeed()函式來完成的。

比如可以這樣來指定串列埠通訊的波特率:

 
  1. #include //標頭檔案定義

  2.  
  3. ........

  4.  
  5. .......

  6.  
  7. struct termios opt; /*定義指向termios 結構型別的指標opt*/

  8.  
  9.  
  10.  
  11. /***************以下設定通訊波特率****************/

  12.  
  13. cfsetispeed(&opt,B9600 ); /*指定輸入波特率,9600bps*/

  14.  
  15. cfsetospeed(&opt,B9600);/*指定輸出波特率,9600bps*/

  16.  
  17. /************************************************/

  18.  
  19. .........

  20.  
  21. ..........


 

一般來說,輸入、輸出的波特率應該是一致的。

下面是另一個修改波特率的程式碼:

 
  1. struct termios Opt;

  2.  
  3. tcgetattr(fd, &Opt);

  4.  
  5. cfsetispeed(&Opt,B19200); /*設定為19200Bps*/

  6.  
  7. cfsetospeed(&Opt,B19200);

  8.  
  9. tcsetattr(fd,TCANOW,&Opt);


 

設定波特率的例子函式:

 
  1. /**

  2.  
  3. *@brief 設定串列埠通訊速率

  4.  
  5. *@param fd 型別 int 開啟串列埠的檔案控制代碼

  6.  
  7. *@param speed 型別 int 串列埠速度

  8.  
  9. *@return void

  10.  
  11. */

  12.  
  13. int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,

  14.  
  15. B38400, B19200, B9600, B4800, B2400, B1200, B300, };

  16.  
  17. int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400,

  18.  
  19. 19200, 9600, 4800, 2400, 1200, 300, };

  20.  
  21. void set_speed(int fd, int speed){

  22.  
  23. int i;

  24.  
  25. int status;

  26.  
  27. struct termios Opt;

  28.  
  29. tcgetattr(fd, &Opt);

  30.  
  31. for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {

  32.  
  33. if (speed == name_arr[i]) {

  34.  
  35. tcflush(fd, TCIOFLUSH);

  36.  
  37. cfsetispeed(&Opt, speed_arr[i]);

  38.  
  39. cfsetospeed(&Opt, speed_arr[i]);

  40.  
  41. status = tcsetattr(fd1, TCSANOW, &Opt);

  42.  
  43. if (status != 0) {

  44.  
  45. perror("tcsetattr fd1");

  46.  
  47. return;

  48.  
  49. }

  50.  
  51. tcflush(fd,TCIOFLUSH);

  52.  
  53. }

  54.  
  55. }

  56.  
  57. }


 

2.2 設定效驗的函式:

 
  1. /**

  2.  
  3. *@brief 設定串列埠資料位,停止位和效驗位

  4.  
  5. *@param fd 型別 int 開啟的串列埠檔案控制代碼

  6.  
  7. *@param databits 型別 int 資料位 取值 為 7 或者8

  8.  
  9. *@param stopbits 型別 int 停止位 取值為 1 或者2

  10.  
  11. *@param parity 型別 int 效驗型別 取值為N,E,O,,S

  12.  
  13. */

  14.  
  15. int set_Parity(int fd,int databits,int stopbits,int parity)

  16.  
  17. {

  18.  
  19. struct termios options;

  20.  
  21. if ( tcgetattr( fd,&options) != 0) {

  22.  
  23. perror("SetupSerial 1");

  24.  
  25. return(FALSE);

  26.  
  27. }

  28.  
  29. options.c_cflag &= ~CSIZE;

  30.  
  31. switch (databits) /*設定資料位數*/

  32.  
  33. {

  34.  
  35. case 7:

  36.  
  37. options.c_cflag |= CS7;

  38.  
  39. break;

  40.  
  41. case 8:

  42.  
  43. options.c_cflag |= CS8;

  44.  
  45. break;

  46.  
  47. default:

  48.  
  49. fprintf(stderr,"Unsupported data sizen"); return (FALSE);

  50.  
  51. }

  52.  
  53. switch (parity)

  54.  
  55. {

  56.  
  57. case 'n':

  58.  
  59. case 'N':

  60.  
  61. options.c_cflag &= ~PARENB; /* Clear parity enable */

  62.  
  63. options.c_iflag &= ~INPCK; /* Enable parity checking */

  64.  
  65. break;

  66.  
  67. case 'o':

  68.  
  69. case 'O':

  70.  
  71. options.c_cflag |= (PARODD | PARENB); /* 設定為奇效驗*/

  72.  
  73. options.c_iflag |= INPCK; /* Disnable parity checking */

  74.  
  75. break;

  76.  
  77. case 'e':

  78.  
  79. case 'E':

  80.  
  81. options.c_cflag |= PARENB; /* Enable parity */

  82.  
  83. options.c_cflag &= ~PARODD; /* 轉換為偶效驗*/

  84.  
  85. options.c_iflag |= INPCK; /* Disnable parity checking */

  86.  
  87. break;

  88.  
  89. case 'S':

  90.  
  91. case 's': /*as no parity*/

  92.  
  93. options.c_cflag &= ~PARENB;

  94.  
  95. options.c_cflag &= ~CSTOPB;break;

  96.  
  97. default:

  98.  
  99. fprintf(stderr,"Unsupported parityn");

  100.  
  101. return (FALSE);

  102.  
  103. }


 

2.3 設定停止位

 
  1. switch (stopbits)

  2.  
  3. {

  4.  
  5. case 1:

  6.  
  7. options.c_cflag &= ~CSTOPB;

  8.  
  9. break;

  10.  
  11. case 2:

  12.  
  13. options.c_cflag |= CSTOPB;

  14.  
  15. break;

  16.  
  17. default:

  18.  
  19. fprintf(stderr,"Unsupported stop bitsn");

  20.  
  21. return (FALSE);

  22.  
  23. }

  24.  
  25. /* Set input parity option */

  26.  
  27. if (parity != 'n')

  28.  
  29. options.c_iflag |= INPCK;

  30.  
  31. tcflush(fd,TCIFLUSH);

  32.  
  33. options.c_cc[VTIME] = 150; /* 設定超時15 seconds*/

  34.  
  35. options.c_cc[VMIN] = 0; /* Update the options and do it NOW */

  36.  
  37. if (tcsetattr(fd,TCSANOW,&options) != 0)

  38.  
  39. {

  40.  
  41. perror("SetupSerial 3");

  42.  
  43. return (FALSE);

  44.  
  45. }

  46.  
  47. return (TRUE);

  48.  
  49. }


 

 

    在上述程式碼中,有兩句話特別重要:

options.c_cc[VTIME] = 0; /* 設定超時0 seconds*/  

options.c_cc[VMIN] = 13; /* define the minimum bytes data to be readed*/

這兩句話決定了對串列埠讀取的函式read()的一些功能。我將著重介紹一下他們對read()函式的影響。

對串列埠操作的結構體是

 
  1. Struct{

  2.  
  3. tcflag_t c_iflag; /*輸入模式標記*/

  4.  
  5. tcflag_t c_oflag; /*輸出模式標記*/

  6.  
  7. tcflag_t c_cflag; /*控制模式標記*/

  8.  
  9. tcflag_t c_lflag; /*本地模式標記*/

  10.  
  11. cc_t c_line; /*線路規程*/

  12.  
  13. cc_t c_cc[NCCS]; /*控制符號*/

  14.  
  15. };


 

其中cc_t, c_line只有在一些特殊的系統程式(比如,設定通過tty裝置來通訊的網路協議)中才會用。在陣列c_cc中有兩個下標(VTIME和VMIN)對應的元素不是控制符,並且只是在原始模式下有效。只有在原始模式下,他們決定了read()函式在什麼時候返回。在標準模式下,除非設定了O_NONBLOCK選項,否則只有當遇到檔案結束符或各行的字元都已經編輯完畢後才返回。

控制符VTIME和VMIN之間有著複雜的關係。VTIME定義要求等待的零到幾百毫秒的時間量(通常是一個8位的unsigned char變數,取值不能大於cc_t)。           VMIN定義了要求等待的最小位元組數(不是要求讀的位元組數——read()的第三個引數才是指定要求讀的最大位元組數),這個位元組數可能是0。

l) 如果VTIME取0,VMIN定義了要求等待讀取的最小位元組數。函式read()只有在讀取了VMIN個位元組的資料或者收到一個訊號的時候才返回。

2) 如果VMIN取0,VTIME定義了即使沒有資料可以讀取,read()函式返回前也要等待幾百毫秒的時間量。這時,read()函式不需要像其通常情況那樣要遇到一個檔案結束標誌才返回0。

3) 如果VTIME和VMIN都不取0,VTIME定義的是當接收到第一個位元組的資料後開始計算等待的時間量。如果當呼叫read函式時可以得到資料,計時器馬上開始計時。如果當呼叫read函式時還沒有任何資料可讀,則等接收到第一個位元組的資料後,計時器開始計時。函式read可能會在讀取到VMIN個位元組的資料後返回,也可能在計時完畢後返回,這主要取決於哪個條件首先實現。不過函式至少會讀取到一個位元組的資料,因為計時器是在讀取到第一個資料時開始計時的。

4) 如果VTIME和VMIN都取0,即使讀取不到任何資料,函式read也會立即返回。同時,返回值0表示read函式不需要等待檔案結束標誌就返回了。

這就是這兩個變數對read函式的影響。

 

2.4 串列埠屬性配置

在程式中,很容易配置串列埠的屬性,這些屬性定義在結構體struct termios中。為在程式中使用該結構體,需要包含檔案,該標頭檔案定義了結構體struct termios。該結構體定義如下:

#define NCCS 19

struct termios {

             tcflag_t c_iflag;               /* 輸入引數 */

             tcflag_t c_oflag;               /* 輸出引數 */

             tcflag_t c_cflag;               /* 控制引數*/

             tcflag_t c_ispeed;              /* 輸入波特率 */

tcflag_t c_ospeed;              /* 輸出波特率 */

             cc_t c_line;                   /* 線控制 */

             cc_t c_cc[NCCS];              /* 控制字元*/

};

其中成員c_line在POSIX(Portable Operating System Interface for UNIX)系統中不使用。對於支援POSIX終端介面的系統中,對於埠屬性的設定和獲取要用到兩個重要的函式是:

(1).int tcsetattr(int fd,int opt_DE,*ptr)

該函式用來設定終端控制屬性,其引數說明如下:

fd:待操作的檔案描述符

opt_DE:選項值,有三個選項以供選擇:

TCSANOW:  不等資料傳輸完畢就立即改變屬性

TCSADRAIN:等待所有資料傳輸結束才改變屬性

TCSAFLUSH:清空輸入輸出緩衝區才改變屬性

*ptr:指向termios結構的指標

函式返回值:成功返回0,失敗返回-1。

(2).int tcgetattr(int fd,*ptr)

該函式用來獲取終端控制屬性,它把串列埠的預設設定賦給了termios資料資料結構,其引數說明如下:

fd:待操作的檔案描述符

*ptr:指向termios結構的指標

函式返回值:成功返回0,失敗返回-1。

2.5 注意的問題:

如果不是開發終端之類的,只是串列埠傳輸資料,而不需要串列埠來處理,那麼使用原始模式(Raw Mode)方式來通訊,設定方式如下:

options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/

options.c_oflag &= ~OPOST; /*Output*/

3.讀寫串列埠

3.1 串列埠讀操作(接收端)

用open函式開啟裝置檔案,函式返回一個檔案描述符(file descriptors,fd),通過檔案描述符來訪問檔案。讀串列埠操作是通過read函式來完成的。函式原型如下:

int read(int fd, *buffer,length);

引數說明:

(1).int fd:檔案描述符

(2).*buffer:資料緩衝區

(3).length:要讀取的位元組數

函式返回值:

讀操作成功讀取返回讀取的位元組數,失敗則返回-1。

3.2 串列埠寫操作(傳送端)

寫串列埠操作是通過write函式來完成的。函式原型如下:

write(int fd, *buffer,length);

引數說明:

(1).fd:檔案描述符

(2).*buffer:儲存寫入資料的資料緩衝區

(3).length:寫入緩衝去的資料位元組數

函式返回值:

成功返回寫入資料的位元組數,該值通常等於length,如果寫入失敗返回-1。

例如:向終端裝置傳送初始化命令

設定好串列埠之後,讀寫串列埠就很容易了,把串列埠當作檔案讀寫就是。

·傳送資料

char buffer[1024];

int Length;int nByte;

nByte = write(fd, buffer ,Length)

 

4.關閉串列埠

關閉串列埠就是關閉檔案。

close(fd);

5.例子

下面是一個簡單的讀取串列埠資料的例子,使用了上面定義的一些函式和標頭檔案

 
  1. /**********************************************************************

  2.  
  3. 程式碼說明:使用串列埠二測試的,傳送的資料是字元,

  4.  
  5. 但是沒有傳送字串結束符號,所以接收到後,後面加上了結束符號。

  6.  
  7. 我測試使用的是單片機發送資料到第二個串列埠,測試通過。

  8.  
  9. **********************************************************************/

  10.  
  11. #define FALSE -1

  12.  
  13. #define TRUE 0

  14.  
  15. /*********************************************************************/

  16.  
  17. int OpenDev(char *Dev)

  18.  
  19. {

  20.  
  21. int fd = open( Dev, O_RDWR );

  22.  
  23. //| O_NOCTTY | O_NDELAY

  24.  
  25. if (-1 == fd)

  26.  
  27. {

  28.  
  29. perror("Can't Open Serial Port");

  30.  
  31. return -1;

  32.  
  33. }

  34.  
  35. else

  36.  
  37. return fd;

  38.  
  39. }

  40.  
  41. int main(int argc, char **argv){

  42.  
  43. int fd;

  44.  
  45. int nread;

  46.  
  47. char buff[512];

  48.  
  49. char *dev = "/dev/ttyS1"; //串列埠二

  50.  
  51. fd = OpenDev(dev);

  52.  
  53. set_speed(fd,19200);

  54.  
  55. if (set_Parity(fd,8,1,'N') == FALSE) {

  56.  
  57. printf("Set Parity Errorn");

  58.  
  59. exit (0);

  60.  
  61. }

  62.  
  63. while (1) //迴圈讀取資料

  64.  
  65. {

  66.  
  67. while((nread = read(fd, buff, 512))>0)

  68.  
  69. {

  70.  
  71. printf("nLen %dn",nread);

  72.  
  73. buff[nread+1] = '';

  74.  
  75. printf( "n%s", buff);

  76.  
  77. }

  78.  
  79. }

  80.  
  81. //close(fd);

  82.  
  83. // exit (0);

  84.  
  85. }