久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久


嵌入式Linux串口應用編程之串口配置

分(fen)享(xiang)到:
           

    串口的設(she)置(zhi)主(zhu)要是設(she)置(zhi)struct termios結(jie)構體(ti)的各(ge)成員值(zhi),如下所(suo)示:

    #include<termios.h>
    struct termios
    {
        unsigned short c_iflag; /* 輸入模式標志 */
        unsigned short c_oflag; /* 輸出模式標志 */
        unsigned short c_cflag; /* 控制模式標志 */
        unsigned short c_lflag; /* 本地模式標志 */
        unsigned char c_line; /* 線路規程 */
        unsigned char c_cc[NCC]; /* 控制特性 */
        speed_t c_ispeed; /* 輸入速度 */
        speed_t c_ospeed; /* 輸出速度 */
    };

    termios是在Posix規范中(zhong)定(ding)義的(de)標準(zhun)接(jie)口,表示(shi)終(zhong)(zhong)端(duan)設(she)(she)備(bei)(包括虛擬終(zhong)(zhong)端(duan)、串口等)。因為串口是一(yi)種終(zhong)(zhong)端(duan)設(she)(she)備(bei),所(suo)以(yi)通過終(zhong)(zhong)端(duan)編程(cheng)接(jie)口對其進行配(pei)置和控制(zhi)。因此在具體討論串口相(xiang)關編程(cheng)之前(qian),需要先了解一(yi)下終(zhong)(zhong)端(duan)的(de)相(xiang)關知識。

    終端(duan)是指用戶與(yu)計算機進行(xing)對話的接(jie)口,如(ru)鍵(jian)盤、顯(xian)示器(qi)和串(chuan)口設備等物(wu)理設備,X Window上的虛(xu)擬終端(duan)。類(lei)UNIX操作系(xi)統都有文(wen)本(ben)式虛(xu)擬終端(duan),使用【Ctrl+Alt】+F1~F6鍵(jian)可以(yi)進入文(wen)本(ben)式虛(xu)擬終端(duan),在X Window上可以(yi)打開幾十個以(yi)上的圖(tu)形式虛(xu)擬終端(duan)。類(lei)UNIX操作系(xi)統的虛(xu)擬終端(duan)有xterm、rxvt、zterm、eterm等,而(er)Windows上有crt、putty等虛(xu)擬終端(duan)。

&nbsp;   終端有三種工(gong)作模式(shi),分別為規范模式(shi)(canonical mode)、非規范模式(shi)(non-canonical mode)和原(yuan)始模式(shi)(raw mode)。

    通過在termios結(jie)構(gou)的(de)c_lflag中設置ICANNON標志來定(ding)義(yi)終端是以規范模(mo)式(shi)(shi)(設置ICANNON標志)還(huan)是以非規范模(mo)式(shi)(shi)(清除ICANNON標志)工作,默認(ren)情(qing)況為規范模(mo)式(shi)(shi)。

    在規范(fan)模式下(xia),所(suo)有的(de)(de)(de)輸(shu)入是(shi)基于(yu)行(xing)(xing)(xing)進行(xing)(xing)(xing)處(chu)理的(de)(de)(de)。在用(yong)(yong)戶(hu)輸(shu)入一(yi)(yi)個行(xing)(xing)(xing)結(jie)束符(fu)(回(hui)車(che)(che)符(fu)、EOF等)之前,系統(tong)調用(yong)(yong)read()函(han)數(shu)(shu)是(shi)讀(du)(du)不到用(yong)(yong)戶(hu)輸(shu)入的(de)(de)(de)任何字(zi)(zi)符(fu)的(de)(de)(de)。除了(le)EOF之外的(de)(de)(de)行(xing)(xing)(xing)結(jie)束符(fu)(回(hui)車(che)(che)符(fu)等)與普(pu)通字(zi)(zi)符(fu)一(yi)(yi)樣會被(bei)read()函(han)數(shu)(shu)讀(du)(du)取(qu)到緩沖區中。在規范(fan)模式中,行(xing)(xing)(xing)編輯是(shi)可行(xing)(xing)(xing)的(de)(de)(de),而且一(yi)(yi)次(ci)調用(yong)(yong)read()函(han)數(shu)(shu)多只(zhi)能讀(du)(du)取(qu)一(yi)(yi)行(xing)(xing)(xing)數(shu)(shu)據(ju)。如果在read()函(han)數(shu)(shu)中被(bei)請(qing)求讀(du)(du)取(qu)的(de)(de)(de)數(shu)(shu)據(ju)字(zi)(zi)節數(shu)(shu)小(xiao)于(yu)當(dang)前行(xing)(xing)(xing)可讀(du)(du)取(qu)的(de)(de)(de)字(zi)(zi)節數(shu)(shu),則read()函(han)數(shu)(shu)只(zhi)會讀(du)(du)取(qu)被(bei)請(qing)求的(de)(de)(de)字(zi)(zi)節數(shu)(shu),剩下(xia)的(de)(de)(de)字(zi)(zi)節下(xia)次(ci)再被(bei)讀(du)(du)取(qu)。

    在非(fei)規范模式(shi)下,所有(you)(you)的(de)輸入是即時有(you)(you)效的(de),不(bu)需(xu)要用戶另外輸入行(xing)結束符,而且(qie)不(bu)可進行(xing)行(xing)編輯(ji)。在非(fei)規范模式(shi)下,對參數MIN(c_cc[VMIN])和(he)TIME(c_cc[VTIME])的(de)設置(zhi)(zhi)決定(ding)read()函數的(de)調(diao)用方(fang)式(shi)。設置(zhi)(zhi)可以有(you)(you)4種不(bu)同的(de)情況。

    ● MIN = 0和TIME = 0:read()函數立即返回。若有可讀數據,則讀取數據并返回被讀取的字節數,否則讀取失敗并返回0。
    ● MIN > 0和TIME = 0:read()函數會被阻塞,直到MIN個字節數據可被讀取。
    ● MIN = 0和TIME > 0:只要有數據可讀或者經過TIME個十分之一秒的時間,read()函數則立即返回,返回值為被讀取的字節數。如果超時并且未讀到數據,則read()函數返回0。
    ● MIN > 0和TIME > 0:當有(you)MIN個(ge)(ge)(ge)(ge)字(zi)(zi)節可讀或者兩個(ge)(ge)(ge)(ge)輸入字(zi)(zi)符之間(jian)的時(shi)(shi)間(jian)間(jian)隔超(chao)過TIME個(ge)(ge)(ge)(ge)十分之一秒時(shi)(shi),read()函數(shu)才返回。因為在輸入第(di)一個(ge)(ge)(ge)(ge)字(zi)(zi)符后(hou)系(xi)統才會啟動定時(shi)(shi)器(qi),所以,在這種情況下,read()函數(shu)至(zhi)少讀取一個(ge)(ge)(ge)(ge)字(zi)(zi)節后(hou)才返回。

    按照嚴(yan)格意義(yi)來講,原(yuan)始(shi)(shi)模式(shi)(shi)是一種特(te)殊的非規范模式(shi)(shi)。在(zai)原(yuan)始(shi)(shi)模式(shi)(shi)下,所有的輸入數(shu)據以(yi)字節(jie)為單位被處(chu)理。在(zai)這個模式(shi)(shi)下,終端(duan)是不(bu)可(ke)(ke)回(hui)顯的,而且所有特(te)定的終端(duan)輸入/輸出控(kong)制(zhi)處(chu)理不(bu)可(ke)(ke)用(yong)(yong)。通過(guo)調用(yong)(yong)cfmakeraw()函數(shu)可(ke)(ke)以(yi)將終端(duan)設置為原(yuan)始(shi)(shi)模式(shi)(shi),而且該函數(shu)通過(guo)以(yi)下代碼可(ke)(ke)以(yi)得到實(shi)現:

    termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
    | INLCR | IGNCR | ICRNL | IXON);
    termios_p->c_oflag &= ~OPOST;
    termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    termios_p->c_cflag &= ~(CSIZE | PARENB);
     termios_p->c_cflag |= CS8;

    現在(zai)講解設置串口(kou)的基本(ben)方法。如(ru)上所述,串口(kou)設置基本(ben)的操(cao)作包括波特(te)率設置,校(xiao)驗位(wei)和(he)(he)停止(zhi)位(wei)設置。在(zai)這(zhe)個結構中(zhong)為重要的是(shi)c_cflag,通過對它的賦值(zhi),用戶(hu)可以設置波特(te)率、字符大小、數據(ju)位(wei)、停止(zhi)位(wei)、奇偶校(xiao)驗位(wei)和(he)(he)硬(ying)軟流(liu)控等。另外,c_iflag和(he)(he)c_cc也是(shi)比較常(chang)用的標志(zhi)。在(zai)此主(zhu)要對這(zhe)3個成員(yuan)進行詳細說明。c_cflag支持的常(chang)量名(ming)稱如(ru)表(biao)(biao)2.11所示(shi)。其(qi)中(zhong)設置波特(te)率宏名(ming)為相應的波特(te)率數值(zhi)前加上B,由于數值(zhi)較多,本(ben)表(biao)(biao)沒有(you)全部列出。

表2.11 c_cflag支持的常量名稱

CBAUD 波特率的位掩碼
B0 0波特率(放棄DTR)

續表

CBAUD 波特率的位掩碼
B1800 1800波特率
B2400 2400波特率
B4800 4800波特率
B9600 9600波特率
B19200 19200波特率
B38400 38400波特率
B57600 57600波特率
B115200 115200波特率
EXTA 外部時鐘率
EXTB 外部時鐘率
CSIZE 數據位的位掩碼
CS5 5個數據位
CS6 6個數據位
CS7 7個數據位
CS8 8個數據位
CSTOPB 2個停止位(不設則是1個停止位)
CREAD 接收使能
PARENB
PARODD
校驗位使能
使用奇校驗而不使用偶校驗
HUPCL 后關閉時掛線(放棄DTR)
CLOCAL 本地連接(不改變端口所有者)
CRTSCTS 硬件流控

    在這(zhe)里,對于c_cflag成員不能(neng)直接對其(qi)初始化,而(er)要將(jiang)其(qi)通過(guo)“與(yu)”、“或”操作使用其(qi)中的某些選項。

    輸入模(mo)式(shi)標志c_iflag用(yong)于控制端口接(jie)收端的字符輸入處理(li)。c_iflag支持(chi)的常量名稱,如表2.12所示。

表2.12 c_iflag支(zhi)持的常量(liang)名稱

INPCK 奇偶校驗使能
IGNPAR 忽略奇偶校驗錯誤
PARMRK 奇偶校驗錯誤掩碼
ISTRIP 裁減掉第8位比特
IXON 啟動輸出軟件流控
IXOFF 啟動輸入軟件流控

續表

INPCK 奇偶校驗使能
IXANY 允許輸入任意字符可以重新啟動輸出(默認為輸入起始字符才重啟輸出)
IGNBRK 忽略輸入終止條件
BRKINT 當檢測到輸入終止條件時發送SIGINT信號
INLCR 將接收到的NL(換行符)轉換為CR(回車符)
IGNCR 忽略接收到的CR(回車符)
ICRNL 將接收到的CR(回車符)轉換為NL(換行符)
IUCLC 將接收到的大寫字符映射為小寫字符
IMAXBEL 當輸入隊列滿時響鈴

    c_oflag用于控制(zhi)終端(duan)端(duan)口發(fa)送(song)出去的(de)字符處理(li),c_oflag支持的(de)常(chang)量(liang)名稱(cheng)如表2.13所示。因為現在(zai)終端(duan)的(de)速度比以前(qian)快得多,所以大部分延時掩碼幾乎(hu)沒什(shen)么(me)用途。

表(biao)2.13 c_oflag支持的常量名稱

OPOST 啟用輸出處理功能,如果不設置該標志則其他標志都被忽略
OLCUC 將輸出中的大寫字符轉換成小寫字符
ONLCR 將輸出中的換行符('\n')轉換成回車符('\r')
ONOCR 如果當前列號為0,則不輸出回車符
OCRNL 將輸出中的回車符('\r')轉換成換行符('\n')
ONLRET 不輸出回車符
OFILL 發送填充字符以提供延時
OFDEL 如果設置該標志,則表示填充字符為DEL字符,否則為NUL字符
NLDLY 換行符延時掩碼
CRDLY 回車符延時掩碼
TABDLY 制表符延時掩碼
BSDLY 水平退格符延時掩碼
VTDLY 垂直退格符延時掩碼
FFLDY 換頁符延時掩碼

    c_lflag用于控(kong)制(zhi)終(zhong)端的(de)本地數據處(chu)理和(he)工作模式(shi),c_lflag所(suo)支持的(de)常量名稱如表(biao)2.14所(suo)示。

表(biao)2.14 c_lflag支(zhi)持的常量名稱

ISIG 若收到信號字符(INTR、QUIT等),則會產生相應的信號
ICANON 啟用規范模式
ECHO 啟用本地回顯功能
ECHOE 若設置ICANON,則允許退格操作

續表

ECHOK 若設置ICANON,則KILL字符會刪除當前行
ECHONL 若設置ICANON,則允許回顯換行符
ECHOCTL 若設置ECHO,則控制字符(制表符、換行符等)會顯示成“^X”,其中X的ASCII碼等于給相應控制字符的ASCII碼加上0x40。例如,退格字符(0x08)會顯示為“^H”('H'的ASCII碼為0x48)
ECHOPRT 若設置ICANON和IECHO,則刪除字符(退格符等)和被刪除的字符都會被顯示
ECHOKE 若設置ICANON,則允許回顯在ECHOE和ECHOPRT中設定的KILL字符
NOFLSH 在通常情況下,當接收到INTR、QUIT和SUSP控制字符時,會清空輸入和輸出隊列。如果設置該標志,則所有的隊列不會被清空
TOSTOP 若一個后臺進程試圖向它的控制終端進行寫操作,則系統向該后臺進程的進程組發送SIGTTOU信號。該信號通常終止進程的執行
IEXTEN 啟用輸入處理功能

    c_cc定義特殊控制特性,c_cc所支持(chi)的常量(liang)名稱如表2.15所示。

表2.15 c_cc支(zhi)持的常(chang)量名稱(cheng)

VINTR 中斷控制字符,對應鍵為Ctrl+C
VQUIT 退出操作符,對應鍵為Ctrl+Z
VERASE 刪除操作符,對應鍵為Backspace(BS)
VKILL 刪除行符,對應鍵為Ctrl+U
VEOF 文件結尾符,對應鍵為Ctrl+D
VEOL 附加行結尾符,對應鍵為Carriage return(CR)
VEOL2 第二行結尾符,對應鍵為Line feed(LF)
VMIN 指定少讀取的字符數
VTIME 指定讀取的每個字符之間的超時時間

    下面就詳細講解設置串口屬(shu)性的基本流(liu)程。

    1.保存原先串口配置(zhi)

    首先,為(wei)了安全起見和(he)以(yi)后(hou)調試程序方便,可(ke)以(yi)先保(bao)存(cun)原先串口的配置(zhi),在這里(li)可(ke)以(yi)使用函數(shu)(shu)tcgetattr(fd, &old_cfg)。該函數(shu)(shu)得到由fd指向的終(zhong)端的配置(zhi)參數(shu)(shu),并(bing)將它們保(bao)存(cun)于termios結構變量(liang)old_cfg中。該函數(shu)(shu)還(huan)可(ke)以(yi)測(ce)試配置(zhi)是否正(zheng)確、該串口是否可(ke)用等。若調用成功,函數(shu)(shu)返回(hui)值為(wei)0,若調用失敗,函數(shu)(shu)返回(hui)值為(wei)-1,其使用如下所示:

    if (tcgetattr(fd, &old_cfg) != 0)
    {
        perror("tcgetattr");
        return -1;
    }

    2.激活選項(xiang)

    CLOCAL和CREAD分別(bie)用于本地連接和接收使(shi)能,因(yin)此,首先(xian)要通過位掩碼(ma)的方式激(ji)活這(zhe)兩個選項(xiang)。

    newtio.c_cflag |= CLOCAL | CREAD;

    調(diao)用cfmakeraw()函數可以將終端設(she)置為原始模式(shi),在(zai)后面(mian)的實例中,采用原始模式(shi)進行串口(kou)數據(ju)通(tong)信。

    cfmakeraw(&new_cfg);

    3.設置波特率

    設置波特率有(you)專(zhuan)門的函數,用戶(hu)不(bu)能(neng)直(zhi)接通過位掩(yan)碼來操作。設置波特率的主要函數有(you)cfsetispeed()和(he)cfsetospeed()。這兩個函數的使用很(hen)簡(jian)單,如下所示:

    cfsetispeed(&\&new_cfg, B115200);
&nbsp;   cfsetospeed(&new_cfg, B115200);

    cfsetispeed()函數(shu)在termios結構中設置數(shu)據(ju)輸入波特率,而cfsetospeed()函數(shu)在termios結構中設置數(shu)據(ju)輸入波特率。一(yi)般來說(shuo),用戶需將終端的輸入和輸出波特率設置成一(yi)樣的。這(zhe)幾個函數(shu)在成功時返(fan)回0,失敗時返(fan)回-1。

    4.設置字(zi)符(fu)大小

    與設置波特率不同,設置字(zi)符大小并沒(mei)有現成可用(yong)的(de)函數(shu),需要(yao)用(yong)位(wei)掩碼。一般首先去(qu)除數(shu)據位(wei)中的(de)位(wei)掩碼,再重新按要(yao)求(qiu)設置,如下(xia)所示(shi):

    new_cfg.c_cflag &= ~CSIZE; /* 用數據位掩碼清空數據位設置 */
     new_cfg.c_cflag |= CS8;

    5.設(she)置奇偶校驗位

    設置(zhi)奇偶(ou)校(xiao)驗(yan)(yan)(yan)位需要用(yong)到termios中(zhong)的兩個成員:c_cflag和c_iflag。首先(xian)要激(ji)活(huo)c_cflag中(zhong)的校(xiao)驗(yan)(yan)(yan)位使能標志PARENB和確認是否要進行校(xiao)驗(yan)(yan)(yan),這樣會對(dui)輸出數(shu)據(ju)產(chan)生校(xiao)驗(yan)(yan)(yan)位,而對(dui)輸入(ru)數(shu)據(ju)進行校(xiao)驗(yan)(yan)(yan)檢(jian)查(cha)。同時還要激(ji)活(huo)c_iflag中(zhong)的對(dui)于輸入(ru)數(shu)據(ju)的奇偶(ou)校(xiao)驗(yan)(yan)(yan)使能(INPCK)。如使能奇校(xiao)驗(yan)(yan)(yan)時,代(dai)碼如下(xia)所示:

    new_cfg.c_cflag |= (PARODD | PARENB);
   &nbsp;new_cfg.c_iflag |= INPCK;

    而使(shi)能偶(ou)校驗時,代碼如下所示:

    new_cfg.c_cflag |= PARENB;
    new_cfg.c_cflag &= ~PARODD; /* 清除偶奇校驗標志,則配置為偶校驗 */
    new_cfg.c_iflag |= INPCK; 

    6.設置停止(zhi)位

  &nbsp; 設置停(ting)(ting)止(zhi)位(wei)是通過激(ji)活(huo)c_cflag中的CSTOPB而實(shi)現的。若(ruo)停(ting)(ting)止(zhi)位(wei)為(wei)一個(ge)比特,則清除CSTOPB;若(ruo)停(ting)(ting)止(zhi)位(wei)為(wei)兩(liang)個(ge),則激(ji)活(huo)CSTOPB。以下分別(bie)是停(ting)(ting)止(zhi)位(wei)為(wei)一個(ge)和兩(liang)個(ge)比特時的代碼:

    new_cfg.c_cflag &= ~CSTOPB; /* 將停止位設置為一個比特 */
    new_cfg.c_cflag |= CSTOPB; /* 將(jiang)停止位(wei)設(she)置為兩個(ge)比特 */

    7.設置少字符和等待時間

    在(zai)對接收字符和等待時(shi)間沒有特別要求的情(qing)況(kuang)下,可以將其(qi)設(she)置(zhi)為0,則在(zai)任何情(qing)況(kuang)下read()函數立即返回(hui),此時(shi)串口操作會設(she)置(zhi)為非阻塞方式,如(ru)下所示(shi):

    new_cfg.c_cc[VTIME] = 0;
 &nbsp;  new_cfg.c_cc[VMIN] = 0;

  &nbsp;&nbsp;8.清(qing)除(chu)串(chuan)口(kou)緩沖

    由于串(chuan)口在重新設置(zhi)后,需要對(dui)當(dang)前(qian)的串(chuan)口設備進(jin)行(xing)適當(dang)的處(chu)理,這時就可(ke)調用在&lt;termios.h&gt;中(zhong)聲明的tcdrain()、tcflow()、tcflush()等函數來處(chu)理目前(qian)串(chuan)口緩沖中(zhong)的數據,它們的格式(shi)如下(xia)所示(shi):

    int tcdrain(int fd); /* 使程序阻塞,直到輸出緩沖區的數據全部發送完畢 */
    int tcflow(int fd, int action); /* 用于暫停或重新開始輸出 */
    int tcflush(int fd, int queue_selector); /* 用于清空輸(shu)入(ru)/輸(shu)出緩沖區 */

    在(zai)本實例中(zhong)使用(yong)tcflush()函數,對于在(zai)緩沖區中(zhong)尚(shang)未(wei)傳輸的(de)數據(ju),或者(zhe)收到的(de)但是尚(shang)未(wei)讀取的(de)數據(ju),其處理方法(fa)取決(jue)于queue_selector的(de)值(zhi),它可能的(de)取值(zhi)有以下幾種。

    ● TCIFLUSH:對接收到而未被讀取的數據進行清空處理。
    ● TCOFLUSH:對尚未傳送成功的輸出數據進行清空處理。
    ● TCIOFLUSH:包括前兩(liang)種功能(neng),即對尚未(wei)處理的輸入/輸出數據進行清空處理。

 &nbsp;  如在本例中所采用的是(shi)第一種方法,當然可以使用TCIOFLUSH參數(shu):

    tcflush(fd, TCIFLUSH);

    9.激活配置(zhi)

    在(zai)完成全部(bu)串口配置后,要激活剛(gang)才的(de)配置并使配置生效。這里(li)用(yong)到(dao)的(de)函(han)數是tcsetattr(),它的(de)函(han)數原型是:

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

&nbsp;   其(qi)中,參數termios_p是termios類型的新配置變量。

&nbsp;   參數optional_actions可能的取值有以下3種。

    ● TCSANOW:配置的修改立即生效。
    ● TCSADRAIN:配置的修改在所有寫入fd的輸出都傳輸完畢之后生效。
  &nbsp; ● TCSAFLUSH:所(suo)有已接(jie)收但未讀入的(de)輸入都將在修(xiu)改生效之(zhi)前(qian)被丟棄。 

 &nbsp;  該(gai)函數若調用成功則(ze)返(fan)回0,若失敗則(ze)返(fan)回-1,代碼如下所示:

    if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0)
    {
        perror("tcsetattr");
        return -1;
    }

    下面(mian)給(gei)出了(le)串口配(pei)置(zhi)(zhi)的(de)完整函(han)(han)數(shu)。為了(le)函(han)(han)數(shu)的(de)通用(yong)(yong)性(xing),通常將常用(yong)(yong)的(de)選(xuan)項都在函(han)(han)數(shu)中列出,這樣可以(yi)(yi)大(da)(da)大(da)(da)方(fang)便(bian)以(yi)(yi)后用(yong)(yong)戶(hu)的(de)調試使用(yong)(yong)。該設置(zhi)(zhi)函(han)(han)數(shu)如下所示(shi):

    int set_com_config(int fd,int baud_rate,
    int data_bits, char parity, int stop_bits)
    {
        struct termios new_cfg,old_cfg;
        int speed;

        /* 保存并測試現有串口參數設置,在這里如果串口號等出錯,會有相關的出錯信息 */
        if (tcgetattr(fd, &old_cfg) != 0)
        {
            perror("tcgetattr");
            return -1;
        }
        new_cfg = old_cfg;
        cfmakeraw(&new_cfg); /* 配置為原始模式 */
        new_cfg.c_cflag &= ~CSIZE;
        /* 設置波特率 */
        switch (baud_rate)
        {
            case 2400:
            {
                speed = B2400;
            }
            break;
            case 4800:
            {
                speed = B4800;
            }
            break;
            case 9600:
            {
                speed = B9600;
            }
            break;
            case 19200:
            {
                speed = B19200;
            }
            break;
            case 38400:
            {
                speed = B38400;
            }
            break;

            default:
            case 115200:
            {
                speed = B115200;
            }
            break;
        }
        cfsetispeed(&new_cfg, speed);
        cfsetospeed(&new_cfg, speed);

        switch (data_bits) /* 設置數據位 */
        {
            case 7:
            {
                new_cfg.c_cflag |= CS7;
            }
            break;

            default:
            case 8:
            {
                new_cfg.c_cflag |= CS8
;             }
            break;
        }

        switch (parity) /* 設置奇偶校驗位 */
        {
            default:
            case 'n':
            case 'N':
            {
                new_cfg.c_cflag &= ~PARENB;
                new_cfg.c_iflag &= ~INPCK;
            }
            break;

            case 'o':
            case 'O':
            {
                new_cfg.c_cflag |= (PARODD | PARENB);
                new_cfg.c_iflag |= INPCK;
            }
            break;

            case 'e':
            case 'E':
            {
                new_cfg.c_cflag |= PARENB;
                new_cfg.c_cflag &= ~PARODD;
                new_cfg.c_iflag |= INPCK;
            }
            break;

            case 's': /* as no parity */
            case 'S':
            {
                new_cfg.c_cflag &= ~PARENB;
                new_cfg.c_cflag &= ~CSTOPB;
            }
            break;
        }

        switch (stop_bits) /* 設置停止位 */
        {
            default:
            case 1:
            {
                new_cfg.c_cflag &= ~CSTOPB;
            }
            break;

            case 2:
            {
                new_cfg.c_cflag |= CSTOPB;
            }
        }

        /* 設置等待時間和小接收字符 */
        new_cfg.c_cc[VTIME] = 0;
        new_cfg.c_cc[VMIN] = 1;
        tcflush(fd, TCIFLUSH); /* 處理未接收字符 */
        if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0) /* 激活新配置 */
        {
            perror("tcsetattr");
            return -1;
        }
        return 0;
    }

    本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式Linux應用程序開發》

   熱點鏈接(jie):

   1、嵌入式Linux串口應用編程基礎知識
   2、Linux下多路復用I/O接口
   3、linux 文件鎖的實現及其應用
   4、底層文件I/O操作的系統調用
   5、Linux中的文件及文件描述符

更多新聞>>