<strike id="kiyse"></strike>
  • <tr id="kiyse"></tr>
  • <strike id="kiyse"></strike><samp id="kiyse"><tbody id="kiyse"></tbody></samp>
    <strike id="kiyse"><s id="kiyse"></s></strike>
    <tr id="kiyse"></tr>
    <noframes id="kiyse"><code id="kiyse"></code></noframes>
    <th id="kiyse"></th>
    <samp id="kiyse"></samp>
  • <th id="kiyse"><s id="kiyse"></s></th>
  • 串口9bit通訊模式的高效優化實現

     8/27/2025 4:55:47 PM     作者:黃志超     聯系作者    

    在傳統 UART(串口)通信中,每一幀數據通常包含1位起始位,8位數據位,可以選配的1位奇偶校驗位,以及1位或者2位停止位,可參考下圖的數據幀結構:


    wechat_2025-08-27_170247_925.png


    在一些特定的應用中,比如多機通信、地址/數據區分等場景中,需要用到串口的9bit通訊模式,該模式下每幀數據會擴展到9位,數據的最后一位為額外的標識位。這個額外的第 9 位可以用于標識數據類型(比如地址/數據區分)或者多機通信中的設備尋址等。可參考下圖的數據幀結構:


    2.png


    串口的9bit模式比較常見的使用方式是當總線上有多個設備時,第一幀數據使用第 9 位標記為“地址幀”,其余設備判斷是否接收。后續幀第 9 位標記為“數據幀”,所有設備按需處理。一般第 9 位為0 表示普通數據,為1 表示特殊命令或地址。

    在這種應用模式下,就要求程序先設置為地址模式(即第9位為1),發送第一個地址幀后再切換為數據模式(第9位為0),再發送后續的數據幀。如果用戶每次發送都進行切換的話,一是代碼相對繁瑣,另一點是在應用層切換存在調度機制,可能會讓地址幀與數據幀出現一定的間隔。如果實際的場景對通訊的響應速度有一定的要求的話,在應用層來回切換可能就無法達到要求。

    考慮到這一點,英創公司在Linux工控主板的驅動中進行了優化,給要使用9bit通訊模式的用戶增加了一個專用的設置接口。通過這個設置接口,用戶只需在發送數據前進行一次設置,就可以將數據一次性填入,主板會自動以地址幀的模式發送第一個字節,然后切換為數據幀發送后續字節,整個切換流程都是在驅動中自動完成,能夠保證數據之間幾乎沒有間隔。下面就介紹一下具體的使用方法。

    專用的設置接口借鑒了原來設置串口參數的方式,在struct termios中的c_cflag指定了一個未使用特殊的值,當驅動檢測到這個特殊值后,就會自動切換地址幀與數據幀來發送填入的數據。這樣就可保持UART串口設置的習慣方式不變。具體設置c_cflag的值方法為:使能CMSPAR位,異或PARODD位,對應的代碼如下(在英創提供的串口例程基礎上修改):


    int CSerial::set_port_bit9()
    {
       struct termios new_opt;
       int status;
       tcgetattr(m_fd,&new_opt);
       new_opt.c_cflag &= ~(PARENB | CMSPAR);
       new_opt.c_cflag |= CMSPAR;
       new_opt.c_cflag ^= PARODD;
       new_opt.c_iflag |= INPCK;
       status = tcsetattr(m_fd,TCSANOW,&new_opt);
       if(status != 0)
       {
           perror("Cannot set the serial bit9");
           return -1;
       }
      
       return status;
    }
     
    int main( int argc,char* argv[] )
    {
        int     i1;
        int     portno, baudRate;
        char    Buf[20], cmd;
     
        //打開串口,并設置參數
        i1 = m_Serial.OpenPort( portno, baudRate, '8', '1', 'N');
        if( i1<0 )
        {
        printf( "serial open fail\n");
        return -1;
        }
     
        Buf[0] = 0xaa; //第一個字節為地址
        Buf[1] = 0xaa; //后面的字節為數據
     
        //設置9bit通訊模式
        m_Serial.set_port_bit9();
        //發送填入的數據
        i1 = m_Serial.WritePort(Buf, 2);
     
        return 0;
    }


    用戶使用時,如果需要按照9bit通訊模式發送數據,在調用發送前先調用一次封裝好的set_port_bit9()函數設置串口后,再進行發送即可。為了避免做其他設置的時候影響到相關的標志位,建議用戶在調用發送函數前,再調用set_port_bit9()函數設置,然后就立即進行發送。

    下圖是測試的波形,使用9bit通訊模式發送了兩個字節(都是0xaa),第一個字節位的第9位(標識位)為1,代表地址或者特殊命令,第二個字節的第9位(標識位)為0,代表正常數據,圖中紅色箭頭指向的就是兩個字節的第9位:


    3.png


    另外可以看到由于是一次性填入的數據進行發送,所以兩個字節之間(第一個字節的停止位和第二個字節的起始位)幾乎沒有什么間隔,能夠保證數據發送的實時性。

    我們在主流的產品ESM335x、ESM6800、ESM7000、ESM6200、ESM6400、ESM8000、ESM7400、ESM8400、ESM3568中均已實現該功能,如果對該方案感興趣的用戶,可以聯系英創的工程師獲取詳細的測試例程。


    精品人妻无码一区二区色欲产成人 | 精品国产中文字幕| 99视频精品国在线视频艾草| 99re热久久这里只有精品6| 日韩精品一区二区三区大桥未久| 精品国产热久久久福利| 国产精品视频一区| 国产成人久久精品激情 | 久久青青草原精品国产| 老司机91精品网站在线观看| 欧洲精品无码一区二区三区在线播放| 亚洲精品综合久久| 国产成人精品一区二三区在线观看| 国产成人精品亚洲| 国产精品va在线观看一| 国产精品久久久久久亚洲小说| 精品久久久久久中文字幕女| 国产老女人精品免费视频| 日韩加勒比一本无码精品| 国产综合精品一区二区| 国产精品漂亮美女在线观看| 国产精品久久久久9999赢消| 国产成人无码精品一区不卡| 国产精品国产色综合色| 日本精品久久久久久久久免费| 偷拍精品视频一区二区三区| 亚洲高清国产拍精品青青草原| 国产成人AV无码精品| 91老司机深夜福利精品视频在线观看| 香蕉在线精品视频在线观看6| 亚洲精品乱码久久久久久蜜桃不卡| 国产亚洲精品美女久久久| 久久精品aⅴ无码中文字字幕| 99久久综合给久久精品| 国产福利在线观看精品| 久9视频这里只有精品8| 国产精品久久久久国产精品| 国产精品女同一区二区久久| 亚洲国产另类久久久精品小说| 日韩精品无码免费一区二区三区| 91久久精品视频|