詳解linux下的串口通訊開發[轉載]

來源:互聯網
上載者:User

詳解linux下的串口通訊開發[轉載] 
串列口是電腦一種常用的介面,具有連接線少,通訊簡單,得到廣泛的使用。常用的串口是RS-232-C介面(又稱EIA RS-232-C)它是在1970年由美國電子工業協會(EIA)聯合貝爾系統、數據機廠家及電腦終端生產廠家共同制定的用於串列通訊的標準。串口通訊指的是電腦依次以位(bit)為單位來傳送資料,串列通訊使用的範圍很廣,在嵌入式系統開發過程中串口通訊也經常用到通訊方式之一。

Linux對所有裝置的訪問是通過裝置檔案來進行的,串口也是這樣,為了訪問串口,只需開啟其裝置檔案即可操作串口裝置。在linux系統下面,每一個串口裝置都有裝置檔案與其關聯,裝置檔案位於系統的/dev目錄下面。如linux下的/ttyS0,/ttyS1分別表示的是串口1和串口2。下面來詳細介紹linux下是如何使用串口的:

 

1.      串口操作需要用到的標頭檔

#include     <stdio.h>      /*標準輸入輸出定義*/

#include     <stdlib.h>     /*標準函數庫定義*/

#include     <unistd.h>     /*Unix 標準函數定義*/

#include     <sys/types.h> 

#include     <sys/stat.h>  

#include     <fcntl.h>      /*檔案控制定義*/

#include     <termios.h>    /*POSIX 終端控制定義*/

#include     <errno.h>      /*錯誤號碼定義*/

#include   <string.h>       /*字串功能函數*/

2.      串口通訊傳輸速率設定

傳輸速率的設定定義在<asm/termbits.h>,其包含在標頭檔<termios.h>裡。

常用的傳輸速率常數如下:

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()函數來完成的。比如可以這樣來指定串口通訊的傳輸速率:

#include <stdio.h>    //標頭檔定義

........

........

.......

struct termios opt;           /*定義指向termios 結構類型的指標opt*/

 

/***************以下設定通訊傳輸速率****************/

cfsetispeed(&opt,B9600 ); /*指定輸入傳輸速率,9600bps*/

cfsetospeed(&opt,B9600);/*指定輸出傳輸速率,9600bps*/

/************************************************/

.........

..........

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

3.      串口屬性配置

在程式中,很容易配置串口的屬性,這些屬性定義在結構體struct termios中。為在程式中使用該結構體,需要包含檔案<termbits.h>,該標頭檔定義了結構體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)

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

l        fd:待操作的檔案描述符

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

TCSANOW:  不等資料轉送完畢就立即改變屬性

TCSADRAIN:等待所有資料轉送結束才改變屬性

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

l        *ptr:指向termios結構的指標

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

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

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

l     fd:待操作的檔案描述符

l        *ptr:指向termios結構的指標

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

4.      開啟串口

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

int open(“DE_name”,int open_Status)

參數說明:

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

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

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

l          O_RDONLY:以唯讀方式開啟檔案

l          O_WRONLY:以唯寫方式開啟檔案

l          O_RDWR:以讀寫方式開啟檔案

l          O_APPEND:寫入資料時添加到檔案末尾

l          O_CREATE:如果檔案不存在則產生該檔案,使用該標誌需要設定存取權限位mode_t

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

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

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

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

函數傳回值:

成功返迴文件描述符,如果失敗返回-1

例如假定以可讀寫方式開啟/dev/ttyS0裝置,就可以這樣操作:

#include<stdio.h>    //標頭檔包含

......

......

int fd; /* 檔案描述符 */

fd = open("/dev/ttyS0", O_RDWR | 0_NOCTTY);  /*以讀寫方式開啟裝置*/

if(fd == -1)

perror("Can not open Serial_Port 1/n!");/*開啟失敗時的錯誤提示*/

........

........

 

5.      串口讀操作(接收端)

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

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

參數說明:

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

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

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

函數傳回值:

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

6.      串口寫操作(發送端)

寫串口操作是通過write函數來完成的。函數原型如下:

write(int fd, *buffer,length);

參數說明:

(1).fd:檔案描述符

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

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

函數傳回值:

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

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

#include<stdio.h>    //標頭檔包含

......

......

 

int n

sbuf[]={Hello,this is a Serial_Port test!/n };//待發送資料

int len_send="sizeof"(sbuf);//發送緩衝區位元組數定義

n = write(fd,sbuf,len_send); //寫緩衝區

if(n == -1)

{

printf("Wirte sbuf error./n");

}

......

......

7.      關閉串口

對裝置檔案的操作與對普通檔案的操作一樣,開啟操作之後還需要關閉,關閉串口用函數close( )來操作,函數原型為:

int close(int fd);

參數說明:

fd:檔案描述符

函數傳回值:

成功返回0,失敗返回-1。

在後面的文章我會提供一個串列通訊的測試程式,供大家參考!
 
 
 
 
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.