Linux下的串口通信學習筆記

轉:http://blog.csdn.net/jznsmail/archive/2006/03/15/625382.aspx 

    作者:姜江

 

 

一、什麼是串口通信
    串口通信是指計算機主機與外設之間以及主機系統與主機系統之間數據的串行傳送。使用串口通信時,發送和接收到的每一個字符實際上都是一次一位的傳送的,每一位爲1或者爲0。

二、串口通信的分類
    串口通信可以分爲同步通信和異步通信兩類。同步通信是按照軟件識別同步字符來實現數據的發送和接收,異步通信是一種利用字符的再同步技術的通信方式。
    2.1同步通信
    同步通信是一種連續串行傳送數據的通信方式,一次通信只傳送一幀信息。這裏的信息幀與異步通信中的字符幀不同,通常含有若干個數據字符。如圖:

單同步字符幀結構

+-----+------+-------+------+-----+--------+-------+-------+
|同步|數據  |數據  |數據  | ...    |數據    |CRC1|CRC2|
|字符|字符1|字符2|字符3|        |字符N|           |            |
+-----+------+-------+------+-----+--------+-------+-------+

雙同步字符幀結構
+-----+--------+------+-------+---+-------+-------+--------+
|同步 |同步    |數據 |數據   | ... |數據   |CRC1|CRC2|
|字符1|字符2|字符1|字符2|     |字符N|           |            |
+-----+--------+------+-------+---+-------+-------+--------+
    它們均由同步字符、數據字符和校驗字符(CRC)組成。其中同步字符位於幀開頭,用於確認數據字符的開始。數據字符在同步字符之後,個數沒有限制,由所需傳輸的數據塊長度來決定;校驗字符有1到2個,用於接收端對接收到的字符序列進行正確性的校驗。
    同步通信的缺點是要求發送時鐘和接收時鐘保持嚴格的同步。
    2.2異步通信
    異步通信中,數據通常以字符或者字節爲單位組成字符幀傳送。字符幀由發送端逐幀發送,通過傳輸線被接收設備逐幀接收。發送端和接收端可以由各自的時鐘來控制數據的發送和接收,這兩個時鐘源彼此獨立,互不同步。
    接收端檢測到傳輸線上發送過來的低電平邏輯"0"(即字符幀起始位)時,確定發送端已開始發送數據,每當接收端收到字符幀中的停止位時,就知道一幀字符已經發送完畢。
    在異步通行中有兩個比較重要的指標:字符幀格式和波特率。
    (1)字符幀,由起始位、數據位、奇偶校驗位和停止位組成。如圖:

無空閒位字符幀
+--+---+---+---+---+--+--+--+--+--+--+--+---+---+---+--+--+
|D7|0/1| 1 | 0 |D0|D1|D2|D3|D4|D5|D6|D7|0/1| 1 | 0 |D0|D1|
+--+---+---+---+--+--+--+--+--+--+--+--+---+---+---+--+--+
    奇偶 停  起                         奇偶  停  起
    校驗 止  始                         校驗  止  始
         位  位                               位  位

有空閒位字符幀
+---+---+--+--+--+--+--+--+--+--+---+---+---+---+---+---+--+
| 1 | 0 |D0|D1|D2|D3|D4|D5|D6|D7|0/1| 1 | 1 | 1 | 1 | 0 |D0|
+---+---+--+--+--+--+--+--+--+--+---+---+---+---+---+---+--+
  空  起                         奇偶 停   空  閒  位  起
  閒  始                         校驗 止              始
  位  位                              位              位

    1.起始位:位於字符幀開頭,佔1位,始終爲邏輯0電平,用於向接收設備表示發送端開始發送一幀信息。
    2.數據位:緊跟在起始位之後,可以設置爲5位、6位、7位、8位,低位在前高位在後。
    3.奇偶校驗位:位於數據位之後,僅佔一位,用於表示串行通信中採用奇校驗還是偶校驗。

    (2)波特率,波特率是每秒鐘傳送二進制數碼的位數,單位是b/s。
    異步通信的優點是不需要傳送同步脈衝,字符幀長度也不受到限制。缺點是字符幀中因爲包含了起始位和停止位,因此降低了有效數據的傳輸速率。

三、什麼是RS-232
    RS-232-C 接口(又稱 EIA RS-232-C)它是在 1970 年由美國電子工業協會(EIA)聯合貝爾系統、調制解調器廠家及計算機終端生產廠家共同制定的用於串行通訊的標準。它的全名是"數據終端設備(DTE)和數據通訊設備(DCE)之間串行二進制數據交換接口技術標準"該標準規定採用一個 25 個腳的 DB25 連接器,對連接器的每個引腳的信號內容加以規定,還對各種信號的電平加以規定。傳輸距離在碼元畸變小於 4% 的情況下,傳輸電纜長度應爲 50 英尺。 

四、計算機串口引腳說明
    引出號    說明
    1         接地
    2         TXD輸出
    3         RXD輸入
    4         RTS請求發送
    5         CTS請求接收    
    6         DSR數據序列就緒
    7         GND邏輯地
    8         DCD數據負載檢測
    9         保留  
    10        保留
    11        未定義
    12        後備DCD
    13        後備CTS
    14        後備TXD
    15        傳輸時鐘
    16        後備RXD
    17        接收時鐘
    18        未定義
    19        後備RTS
    20        DTR數據終端就緒
    21        信號質量檢測
    22        鬧鐘檢測
    23        數據速率選擇
    24        傳輸時鐘
    25        未定義

五、全雙工與半雙工
     1.全雙工,表示機器可以同時發送數據也可以接收數據,有兩個獨立的數據通道(一個用於發送,一個用於接收)
     2.半雙工,表示機器不能在發送數據的同時也接收數據。
    
六、流量控制
    1.使用軟件方法
    使用特殊的字符來標記數據流的開始和結束,比如XON,DC1,八進制021來標誌開始,用X0FF,DC3,八進制023來標誌結束。
    2.使用硬件方法
    使用RS232的CTS和RTS信號來代替特殊字符控制。當接收方準備接收更多數據時,設置CTS爲0,反之設置成1。對應的發送端準備發送數據時,設置RTS爲0。

七、串口的訪問
    串口設備在LINUX下與所有設備一樣都是通過設備文件來進行訪問。
    7.1打開串口
    LINUX系統下串口設備是通過open函數來打開的,不過需要注意的是,一般用戶是沒有權限訪問設備文件的,需要將打開的串口設備的訪問權限設置成一般用戶可以訪問的權限。
    open函數
    頭文件
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    函數原型
    int open(const char *pathname, int oflag, .../*, mode_t mode*/);
    參數
    const char *pathname - 要打開文件的文件名稱,例如/dev/ttyS0
    int oflag - 文件打開方式,可用標誌如下:
    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。
    O_SYNC   對I/O進行寫等待
    返回值
    成功返回文件描述符,如果失敗返回-1

    例如:以可讀寫方式打開/dev/ttyS0設備
    int fd;        /* 文件描述符 */
    fd = open("/dev/ttyS0", O_RDWR | 0_NOCTTY | O_NONBLOCK);

    7.2關閉串口
    Linux系統下通過close函數來關閉串口設備
    close函數
    頭文件
    #include <unistd.h>
    函數原型
    int close(int filedes);
    參數
    int filedes - 文件描述符
    返回值
    成功返回0,否則返回-1

    例如:關閉打開的串口設備fd
    int ret;        /* 返回標誌,用於判斷是否正常關閉設備 */
    ret = close(fd);

    7.3寫串口
    寫串口是通過write函數來完成的
    write函數
    頭文件
    #include <unistd.h>
    函數原型
    ssize_t write(int filedes, const void *buff, size_t nbytes);
    參數
    int filedes - 文件描述符
    const void *buff - 存儲寫入數據的數據緩衝區
    size_t nbytes - 寫入數據字節數
    返回值
    ssize_t - 返回寫入數據的字節數,該值通常等於nbytes,如果寫入失敗返回-1

    例如:向終端設備發送初始化命令
    int n = 0;    /* 寫入字節數 */
    n = write(fd, "ATZ/r", 4);
    if(n == -1)
    {
          fprintf(stderr, "Wirte ATZ command error./n");
    }

    7.4讀串口
    讀串口是通過read函數來完成的
    read函數
    頭文件
    #include <unistd.h>
    函數原型
    ssize_t read(int filedes, void *buff, size_t nbytes);
    參數
    int filedes - 文件描述符
    void *buff - 存儲讀取數據的數據緩衝區
    size_t nbytes - 需要讀取的字節數
    返回值
    ssize_t - 成功讀取返回讀取的字節數,否則返回-1
    
    注意,在對串口進行讀取操作的時候,如果是使用的RAW模式,每個read系統調用將返回當前串行輸入緩衝區中存在的字節數。如果沒有數據,將會一致阻塞到有字符達到或者間隔時鐘到期,或者發生錯誤。如果想使read函數在沒有數據的時候立即返回則可以使用fcntl函數來設置文件訪問屬性。例如:
    fcntl(fd, F_SETFL, FNDELAY);
    這樣設置後,當沒有可讀取的數據時,read函數立即返回0。
    通過fcntl(fd, F_SETFL, 0)可以設置回一般狀態。

    例如:從終端讀取5個字節的應答數據
    int nRead;        /* 從終端讀取的字節數 */
    char buffer[256];    /* 接收緩衝區 */
    nRead = read(fd, buffer, 5);
    if(nRead == -1)
    {
         fprintf(stderr, "Read answer message error./n");
    }

八、終端配置
    8.1 POSIX終端接口
    大多數系統都支持POSIX終端接口,POSIX終端通過一個termios結構來進行控制,該結構定義在termios.h文件中。
    termios結構
    struct termios
    {
         tcflag_t  c_iflag;        /* 輸入選項標誌 */
         tcflag_t  c_oflag;       /* 輸出選項標誌 */
         tcflag_t  c_cflag;       /* 控制選項標誌 */
         tcflag_t  c_lflag;       /* 本地選項標誌 */
         cc_t      c_cc[NCCS];    /* 控制特性 */
    };

    c_iflag成員
    Flag        Description
    IGNBRK      忽略輸入中的BREAK狀態
    BRKINT      如果設置了IGNBRK,將忽略BREAK。如果沒有設置,但是設置了BRKINT,那麼BREAK將使得輸入和輸出隊列被刷新,如果終端是一個前臺進程組的控制終端,這個進程組中所有進程將收到SIGINT信號。如果既未設置IGNBRK也未設置BRKINT,BREAK將視爲NUL同義字符,除非設置了PARMRK,這種情況下被視爲序列/377/0/0
    IGNPAR      忽略楨錯誤和奇偶校驗錯誤
    PARMRK      如果沒有設置IGNPAR,在有奇偶校驗錯誤或者楨錯誤的字符前插入/377/0。如果既沒有設置IGNPAR也沒有設置PARMRK,將所有奇偶校驗錯誤或者楨錯誤的字符視爲/0。
    INPCK       啓用輸入奇偶校驗檢測。
    ISTRIP      去掉第八位。
    INLCR       將輸入的NL翻譯爲CR。
    IGNCR       忽略輸入中的回車。
    ICRNL       將輸入中的回車翻譯爲新行字符(除非設置了IGNCR)。
    IUCLC       (不屬於POSIX)將輸入中的大寫字母映射爲小寫字母。
    IXON        啓用輸出的XON/XOFF流控制
    IXANY       (不屬於POSIX。1;XSI)允許任何字符來重新開始輸出。
    IXOFF       啓用輸入的XON/XOFF流控制
    IMAXBEL     (不屬於POSIX)當輸入隊列滿時響鈴。LINUX沒有實現該位,總是將其視爲已設置。

    c_oflag成員
    Flag        Description
    OPOST       啓用具體實現自行定義的輸出。
    OLCUC       (不屬於POSIX)將輸出中的小寫字母映射爲大寫字母。
    ONLCR       (XSI)將輸出中的新行符映射爲回車-換行
    OCRNL       將輸出中的回車映射爲新行符。
    ONOCR       不在第0列輸出回車。
    ONLRET      不輸出回車。
    OFILL       發送填充字符作爲延時。
    OFDEL       (不屬於POSIX)填充字符是ASCII DEL(0177)。如果不設置填充字符則是ASCII NUL。
    NLDLY       新行延時掩碼。取值爲NL0和NL1。
    CRDLY       回車延時掩碼。取值爲CR0,CR1,CR2或CR3。
    TABDLY      水平跳格延時掩碼。取值爲TAB0,TAB1,TAB2,TAB3(或XTABS)。取值爲TAB3,即XTABS,將擴展跳格爲空格(每個跳格符填充8個空格)。
    BSDLY       回車延時掩碼。取值爲BS0或BS1.(從來沒有被實現)
    VTDLY       豎直跳格掩碼。取值爲VT0或VT1。
    FFDLY       進表延時掩碼。取值爲FF0或者FF1。

    c_cflag成員
    Flag        Description
    CBAUD       (不屬於POSIX)波特率掩碼(4+1位)。
    CBAUDEX     (不屬於POSIX)擴展的波特率掩碼(1位),包含在CBAUD中。
    CSIZE       字符長度掩碼。取值爲CS5,CS6,CS7或CS8。
    CSTOPB      設置兩個停止位。
    CREAD       打開接受者。
    PARENB      允許輸出產生奇偶信息以及輸入的奇偶校驗。
    PARODD      輸入和輸出是奇校驗
    HUPCL       在最後一個進程關閉設備後,降低MODEM控制線(掛斷)。
    CLOCAL      忽略MODEM控制線。
    LOBLK       (不屬於POSIX)從非當前SHELL層阻塞輸出(用於sh1)。
    CIBAUD      (不屬於POSIX)輸入速度的掩碼。CIBAUD各位的值與CBAUD各位相同,左移了IBSHIFT位。
    CRTSCTS     (不屬於POSIX)啓用RTS/CTS(硬件)控制流。

    c_lflag成員
    Flag        Description
    ISIG        當接收到字符INTR,QUIT,SUSP或DSUSP時,產生相應的信號。
    XCASE       (不屬於POSIX;LINUX下不支持)如果同時設置了ICANON,終端只有大寫。輸入被轉換爲小寫,除了以/前綴的字符。輸出時,大寫字符被前綴/,小寫字符被轉換成大寫。
    ECHO        回顯輸入字符。
    ECHOE       如果同時設置了ICANON,字符ERASE擦除前一個輸入字符,WERASE擦除前一個詞。
    ECHOK       如果同時設置了ICANON,字符KILL刪除當前行。
    ECHONL      如果同時設置了ICANON,回顯字符NL,即使沒有設置ECHO。
    ECHOCTL     (不屬於POSIX)如果同時設置了ECHO,除了TAB,NL,START和STOP之外的ASCII控制信號被回顯爲^x,這裏X是比控制信號大0x40的ASCII碼。例如字符0x08(BS)被回顯爲^H。
    ECHOPRT     (不屬於POSIX)如果同時設置了ICANON和IECHO,字符在刪除的同時被打印。
    ECHOKE      (不屬於POSIX)如果同時設置了ICANON,回顯KILL時將刪除一行中的每個字符,如同指定了ECHOE和ECHORPT一樣。
    DEFECHO     (不屬於POSIX)只在一個進程讀的時候回顯。
    FLUSHO      (不屬於POSIX;LINUX不支持)輸出被刷新。這個標誌可以通過鍵入字符DISCARD來打開和關閉。
    NOFLSH      禁止產生SIGINT,SIGQUIT和SIGSUSP信號時刷新輸入和輸出隊列。
    TOSTOP      向試圖寫控制終端的後臺進程組發送SIGTTOU信號。
    PENDIN      (不屬於POSIX;LINUX不支持)在讀入一個字符時,輸入隊列中的所有字符被重新輸出。(bash用他來處理typeahead)。
    IEXTEN      啓用實現自定義的輸入處理。這個標誌必須與ICANON同時使用,才能解釋特殊字符EOL2,LNEXT,REPRINT和WERASE,IUCLC標誌纔有效。

    c_cc數組成員
    Flag        Description
    VINTR       (003,ETX,Ctrl-C,or also 0177, DEL, rubout)中斷字符。發送SIGINT信號。當設置ISIG時可被識別,不再作爲輸入傳遞。
    VQUIT       (034,FS,Ctrl-/)退出字符。發出SIGQUIT信號。當設置ISIG時可被識別,不再作爲輸入傳遞。
    VERASE       (0177, DEL, rubout, or 010, BS, Ctrl-H, or also #) 刪除字符。刪除上一個還沒有刪掉的字符,但不刪除上一個 EOF 或行首。當設置 ICANON 時可被識別,不再作爲輸入傳遞。 
    VKILL        (025, NAK, Ctrl-U, or Ctrl-X, or also @) 終止字符。刪除自上一個 EOF 或行首以來的輸入。當設置 ICANON 時可被識別,不再作爲輸入傳遞。 
    VEOF         (004, EOT, Ctrl-D) 文件尾字符。更精確地說,這個字符使得 tty 緩衝中的內容被送到等待輸入的用戶程序中,而不必等到 EOL。如果它是一行的第一個字符,那麼用戶程序的 read() 將返回 0,指示讀到了 EOF。當設置 ICANON 時可被識別,不再作爲輸入傳遞。 
    VMIN         非 canonical 模式讀的最小字符數。 VEOL (0, NUL) 附加的行尾字符。當設置 ICANON 時可被識別。 VTIME 非 canonical 模式讀時的延時,以十分之一秒爲單位。 VEOL2 (not in POSIX; 0, NUL) 另一個行尾字符。當設置 ICANON 時可被識別。 
    VEOL         (0, NUL) 附加的行尾字符。當設置 ICANON 時可被識別。 
    VTIME        非 canonical 模式讀時的延時,以十分之一秒爲單位。 
    VEOL2        (not in POSIX; 0, NUL) 另一個行尾字符。當設置 ICANON 時可被識別。 
    VSWTCH       (not in POSIX; not supported under Linux; 0, NUL) 開關字符。(只爲 shl 所用。) 
    VSTART       (021, DC1, Ctrl-Q) 開始字符。重新開始被 Stop 字符中止的輸出。當設置 IXON 時可被識別,不再作爲輸入傳遞。 
    VSTOP        (023, DC3, Ctrl-S) 停止字符。停止輸出,直到鍵入 Start 字符。當設置 IXON 時可被識別,不再作爲輸入傳遞。 
    VSUSP        (032, SUB, Ctrl-Z) 掛起字符。發送 SIGTSTP 信號。當設置 ISIG 時可被識別,不再作爲輸入傳遞。 
    VDSUSP       (not in POSIX; not supported under Linux; 031, EM, Ctrl-Y) 延時掛起信號。當用戶程序讀到這個字符時,發送 SIGTSTP 信號。當設置 IEXTEN 和 ISIG,並且系統支持作業管理時可被識別,不再作爲輸入傳遞。 
    VLNEXT       (not in POSIX; 026, SYN, Ctrl-V) 字面上的下一個。引用下一個輸入字符,取消它的任何特殊含義。當設置 IEXTEN 時可被識別,不再作爲輸入傳遞。 
    VWERASE      (not in POSIX; 027, ETB, Ctrl-W) 刪除詞。當設置 ICANON 和 IEXTEN 時可被識別,不再作爲輸入傳遞。 
    VREPRINT     (not in POSIX; 022, DC2, Ctrl-R) 重新輸出未讀的字符。當設置 ICANON 和 IEXTEN 時可被識別,不再作爲輸入傳遞。 
    VDISCARD     (not in POSIX; not supported under Linux; 017, SI, Ctrl-O) 開關:開始/結束丟棄未完成的輸出。當設置 IEXTEN 時可被識別,不再作爲輸入傳遞。 
    VSTATUS      (not in POSIX; not supported under Linux; status request: 024, DC4, Ctrl-T).

    8.2設置波特率
    對於波特率的設置通常使用cfsetospeed和cfsetispeed函數來完成。獲取波特率信息是通過cfgetispeed和cfgetospeed函數來完成的。
    cfsetospeed函數
    頭文件:
    #include <termios.h>
    函數原型:
    int cfsetospeed(struct termios *termptr, speed_t speed);
    參數:
    struct termios *termptr - 指向termios結構的指針
    speed_t speed - 需要設置的輸出波特率
    返回值:
    如果成功返回0,否則返回-1

    cfsetispeed函數
    頭文件:
    #include <termios.h>
    函數原型:
    int cfsetispeed(struct termios *termptr, speed_t speed);
    參數:
    struct termios *termptr - 指向termios結構的指針
    speed_t speed - 需要設置的輸入波特率
    返回值:
    如果成功返回0,否則返回-1

    cfgetospeed函數
    頭文件:
    #include <termios.h>
    函數原型:
    speed_t cfgetospeed(const struct termios *termptr);
    參數:
    const struct termios - 指向termios結構的指針
    返回值:
    返回輸出波特率

    cfgetispeed函數
    頭文件:
    #include <termios.h>
    函數原型:
    speed_t cfgetispeed(const struct termios *termptr);
    參數:
    const struct termios *termptr - 指向termios結構的指針
    返回值:
    返回輸入波特率

    波特率常量:
    CBAUD           掩碼
    B0              0波特
    B50             50波特
    B75             75波特
    B110            100波特
    B134            134波特
    B150            150波特
    B200            200波特
    B300            300波特
    B600            600波特
    B1200           1200波特
    B1800           1800波特
    B2400           2400波特
    B9600           9600波特
    B19200          19200波特
    B38400          38400波特
    B57600          57600波特
    B115200         115200波特

    8.3設置字符大小
    設置字符的大小通過設置c_cflag標誌位來實現的。
    例如:
    option.c_cflag &= ~CSIZE;
    option.c_cflag |= CS7;

    8.4設置奇偶校驗
    對於奇偶校驗是需要手工設置的,常用的設置方式如下:
    No parity (8N1):
    options.c_cflag &= ~PARENB
    options.c_cflag &= ~CSTOPB
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

    Even parity (7E1):
    options.c_cflag |= PARENB
    options.c_cflag &= ~PARODD
    options.c_cflag &= ~CSTOPB
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS7;

    Odd parity (7O1):
    options.c_cflag |= PARENB
    options.c_cflag |= PARODD
    options.c_cflag &= ~CSTOPB
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS7;

    Space parity is setup the same as no parity (7S1):
    options.c_cflag &= ~PARENB
    options.c_cflag &= ~CSTOPB
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

    8.5獲取和設置終端屬性
    設置和獲取終端控制屬性是通過tcgetattr和tcsetattr兩個函數來完成的
    tcgetattr函數
    頭文件:
    #include <termios.h>
    函數原型:
    int tcgetattr(int filedes, struct termios *termptr);
    參數:
    int filedes -  文件描述符
    struct termiso *termptr - 指向termios結構的指針,
    返回值:
    如果成功返回0,否則返回-1

    tcsetattr函數
    頭文件:
    #include <termios.h>
    函數原型:
    int tcsetattr(int filedes, int opt, const struct termios *termptr);
    參數:
    int filedes - 文件描述符
    int opt - 選項值,可以爲下面三個值之一
                TCSANOW - 不等數據傳輸完畢就改變屬性
                TCSADRAIN - 等待所有數據傳輸結束才改變屬性
                TCSAFLUSH - 清空輸入輸出緩衝區並且是設置屬性
    const struct termios *termptr - 指向termios結構的指針,
    返回值:
    成功返回0,否則返回-1

九、常用設置
    9.1設置規範模式
    規範模式是面向行的輸入方式,輸入字符被放入用於和用戶交互可以編輯的緩衝區內,直接到讀入回車或者換行符號時才結束。
    可以通過如下方式來設置
    option.c_lflag |= (ICANON | ECHO | ECHOE);

    9.2設置原始輸入模式
    原始輸入模式是沒有處理過的,當接收數據時,輸入的字符在它們被接收後立即被傳送,使用原始輸入模式時候,一般可以選擇取消ICANON,ECHO,ECHOE和ISIG選項。
    例如:
    option.c_lflag &= ~(ICANON | ECHO | ECHOE);

    9.3設置輸入奇偶選項
    當激活c_cflag中的奇偶校驗後,應該激活輸入的奇偶校驗。與之相關的標誌有INPCK,IGNPAR,PARMRK和ISTRIP。一般是通過選擇INPCK和ISTRIP激活檢驗和移除奇偶位。
    例如:
    option.c_iflag |= (INPCK | ISTRIP);

    9.4設置軟件控制流
    軟件控制流通過IXON,IXOFF和IXANY標誌來設置
    例如:
    option.c_iflag |=(IXON | IXOFF | IXANY);

    9.5選擇預處理輸出
    通過OPOST標誌來設置預處理的輸出
    例如:
    option.c_oflag |= OPOST;

    9.6選擇原始數據輸出
    原始數據的輸出通過設置c_oflag的OPOST標誌
    例如:
    option.c_oflag &= ~OPOST;

    9.7設置軟件流控制字符
    軟件流控制字符是通過c_cc數組中的VSTART和VSTOP來設置的,一般來說,它們應該被設置城DC1(021八進制)和DC3(023八進制),分別表示ASCII碼的XON和XOFF字符。

    9.8設置讀超時
    c_cc數組中的VMIN指定了最少讀取的字符數,如果設置爲0,那麼VTIME就指定了讀取每個字符的等待時間。VTIME是以1/10秒爲單位指定接收字符的超時時間的,如果VTIME設置爲0,而端口沒有用open或者fcntl設置爲NONBLOCK,那麼read操作將會阻塞不確定的時間。

十、參考資料
    1.《Serial Programming Guide for POSIX Operating Systems》5th Edition Michael R.Sweet
    2.《Linux 下串口編程入門》左錦
    3.《Advanced Programming in the UNIX Environment》 W.Richard Stevens
    4.《Linux Serial Programming HOWTO》
    5.《Unix Systems Programming》Kay A.Robbins & Steven Robbins
    6.《Linux Programming by Example》Arnold Robbins
    7.《Linux Programmer's Manual》
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章