1. 程式人生 > >Linux下串列埠

Linux下串列埠

1.串列埠通訊

  •    DB9串列埠頭型

                                母頭                                                                                   

                                公頭 

  • DB9 9針腳的功能:

        資料:

        GND(pin 5):地線

        TXD(pin 3):串列埠資料輸出(Transmit Data)

        RXD(pin 2):串列埠資料輸入(Receive Data)

        握手:

        RTS(pin 7):傳送資料請求(Request to Send)

        CTS(pin 8):清除傳送(Clear to Send)

        DSR(pin 6):資料傳送就緒(Data Send Ready)

        DCD(pin 1):資料載波檢測(Data Carrier Detect)

        DTR(pin 4):資料終端就緒(Data Terminal Ready)  

        其它

        RI(pin 9):鈴聲指示

1)資料通訊最少需要3根線: TXD  RXD GND

2)三線通訊:

         (3匯流排空閒,一般是高電平;   起始位,低電平,一個位寬;

          (4)接收方探測: 預設匯流排 空閒時是高電平,一旦來一個位的                 低電平,說明一幀資料開始了。緊接著就是資料位,一幀資料

             有多少個數據位,由通訊雙方定義。資料位: 5, 6,7, 8,

             般是8個位; 

          (5)資料位發完了,一般會跟奇偶校驗位(奇校驗、偶校驗、無校               驗),驗證收發雙方的資料是否正常

             奇校驗: 資料位加上校驗位保證1的個數為奇數;

             偶校驗: 資料位加上校驗位保證1的個數為偶數;

             資料發完之後,會發一個停止位,停止位的寬度一般是:1,               1.5,2

3)TTL電平與RS232電平的區別

    <1>TTL電平標準:

       輸出 L: <0.8V ; H:>2.4V。

       輸入 L: <1.2V ; H:>2.0V

       TTL器件輸出低電平要小於0.8V,高電平要大於2.4V。輸入,低於

       1.2V就認為是0,高於2.0就認為是1。

    <2>RS232標準

           邏輯1的電平為-3~-15V,邏輯0的電平為+3~+15V,注意電平

           的定義反相了一次。        

2.Linux串列埠程式設計

 1)TTY裝置:

   TTY裝置包括虛擬控制檯,串列埠以及偽終端裝置。

   比如說3G/4G/5G其實最終是 USB介面轉成串列埠(/dey/ttyUSB*)

   GPS GPRS/3G/4G/5G/串列埠藍芽/串列埠wife/Lora模組 AT命令

   bootargs:console=/dev/ttyS0,115200

   stdin、stdout、stderr串列埠1,Linux核心的列印資訊console

  2)串列埠程式設計      

開啟串列埠

int fd;

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

if(fd == -1)

{

    Perror("串列埠開啟失敗");

}

除了使用O_RDWR標誌之外,通常還會使用O_NOCTTY和O_NDELAY這兩個標誌

O_NOCTTY:告訴UNIX這個程式不想成為”控制終端“控制的程式,如果不說明這個標誌,任何輸入都會影響你的程式

O_NDELAY:告訴UNIX這個程式不關心DCD訊號線狀態,即其他埠是否執行,不說明這個標誌,程式下DCD訊號線為低電平時停止

3)串列埠的最基本設定:<1>波特率、<2>校驗位、停止位、資料位

主要使用termios.h標頭檔案中定義的termios結構,如:            

struct termios

{

   tcflag_t  c_iflag;   //輸入模式標誌

   tcflag_t  c_oflag;  //輸出模式標誌

   tcflag_t  c_cflag;  //控制模式標誌

   tcflag_t  c_lflag;   //本地模式標誌

   cc_t   c_line;              //line discipline

   cc_t   c_cc[NCC];    //control characters

}

位操作

struct xxx 

{

    unsigned char      flag;    //unsigned char佔兩個位元組,8位

} st;                 

這樣可以來操做8個LED燈

bit[0]  LED1: 1,  ON   0: off

bit[1]  LED2: 1,  ON   0: off

bit[2]  LED3: 1,  ON   0: off

                    .

                    .

                    .

bit[7]  LED3: 1,  ON  0: off

flag:bit[7:0]    xxxx   xxxx

                      0000  0001

                    --------------

                      0000  000x

然後可以這寫程式碼來控制這個:

if(st.flag & (1<<0))

    turn_led1(ON);

else

    turn_led1(OFF);

如果判斷第三位:

if(st.flag & (1<<3))    //將1左移三位

    turn_led1(ON);

else

    turn_led1(OFF);

如果我想知道flag:bit[7:5]的相應的值:

xxxyyyx xxxx

首先先丟掉低位

(std.falg>>5)&7 =  (std.falg>>5)&(2<<3-1)

 用來設定上面的結構體    

 <1>波特率

int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, };

int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, };

void SetSpeed(int fd, int speed)

{

    int i;

    struct termios Opt;    //定義termios結構

    if(tcgetattr(fd, &Opt) != 0)

    {

        perror(“tcgetattr fd”);

        return;

    }

    for(i = 0; i < sizeof(speed_arr) / sizeof(int); i++)

    {

        if(speed == name_arr[i])

        {

            tcflush(fd, TCIOFLUSH);

            cfsetispeed(&Opt, speed_arr[i]);

            cfsetospeed(&Opt, speed_arr[i]);

            if(tcsetattr(fd, TCSANOW, &Opt) != 0)

            {

                perror(“tcsetattr fd”);

                return;

            }

            tcflush(fd, TCIOFLUSH);

        }

    }

}

        <2>校驗位、停止位、資料位

                        以下是幾個資料位、停止位和校驗位的設定方法:(以下均為1位停止位)

                        8位資料位、無校驗位:

                        Opt.c_cflag &= ~PARENB;

                        Opt.c_cflag &= ~CSTOPB;

                        Opt.c_cflag &= ~CSIZE;

                        Opt.c_cflag |= CS8;

                        7位資料位、奇校驗:

                        Opt.c_cflag |= PARENB;

                        Opt.c_cflag |= PARODD;

                        Opt.c_cflag &= ~CSTOPB;

                        Opt.c_cflag &= ~CSIZE;

                        Opt.c_cflag |= CS7;

                        7位資料位、偶校驗:

                        Opt.c_cflag |= PARENB;

                        Opt.c_cflag &= ~PARODD;

                        Opt.c_cflag &= ~CSTOPB;

                        Opt.c_cflag &= ~CSIZE;

                        Opt.c_cflag |= CS7;

                        7位資料位、Space校驗:

                        Opt.c_cflag &= ~PARENB;

                        Opt.c_cflag &= ~CSTOPB;

                        Opt.c_cflag &= ~CSIZE;

                        Opt.c_cflag |= CS7;    

3.Linux核心串列埠具體工作     

 

4.socket通訊

    1.  網路的7層協議                                      五層協議(書面)                          TCP/IP四層協議棧

                                           

這裡以實際的四層協議來分析

   2.遊覽器訪問www.baidu.com過程

   1>由應用程式實現

      遊覽器會封裝一個http的報文請求,然後把這個報文傳送給百度的伺服器

    2>由作業系統實現

        PC會訪問DNS伺服器(114.114.114.114),查詢baidun.com的IP地址123.125.115.110

        因為是www協議,那就訪問123.125.115.110的80埠

        獲取自己的IP地址,核心給應用程式動態分配一個未用的埠    

     網路通訊的四要素:源IP、源埠、目的IP、目的埠

6擴充套件

 1.將IP地址做域名解析

   比如:要訪問192.168.1.X時,我們可以直接通過訪問studio.xxx.com來實

   現連線訪問

 2.如果客戶端如何判斷伺服器斷開了這個連結

 3.如何解決connect()、read()阻塞的問題