在C語言中,你能找到的最好的文檔是源代碼本身,你可以在/usr/include/termios.h
找到您的計算機上(實際上是分佈在一個或多個在其中的包括) - 這裏是bsd based termios.h for apples我根據我的回答,值可能會改變,取決於你的Unix的味道。
在那裏,你會發現,你的tty
對象是struct termios
類型,定義如下:
struct termios {
tcflag_t c_iflag; /* input flags */
tcflag_t c_oflag; /* output flags */
tcflag_t c_cflag; /* control flags */
tcflag_t c_lflag; /* local flags */
cc_t c_cc[NCCS]; /* control chars */
speed_t c_ispeed; /* input speed */
speed_t c_ospeed; /* output speed */
};
所以c_cflag
爲tcflag_t
類型,這是由下面這行定義的:
typedef unsigned long tcflag_t;
而unsigned long
預計爲8個字節,即32位。
然後,您在示例中使用的所有標誌都被定義如下:使用8倍字節的值:
#define PARENB 0x00001000 /* parity enable */
#define CSTOPB 0x00000400 /* send 2 stop bits */
#define CSIZE 0x00000300 /* character size mask */
#define CS8 0x00000300 /* 8 bits */
如此說來,它的工作方式是,c_cflag
用作比特陣列,這意味着每個位爲函數顯著。這是一種常用的方法,因爲處理能力中的位操作「便宜」(CPU可以在一個週期內執行一次操作),而在內存空間中「便宜」,而不是使用32個布爾值數組來存儲值一個大小爲1字節的布爾類型來存儲一個二進制值),你可以存儲每個字節8個二進制值。
另一個優點和優化是因爲你的CPU至少有32位,並且在2015年可能是64位,它可以在一個CPU週期中對32個值應用掩碼。
位掩碼的另一種表示是創建一個結構如下所示:
struct tcflag_t {
bool cignore;
uint8_t csize;
bool cstopb;
bool cread;
bool parenb;
bool hupcl;
bool clocal;
bool ccts_oflow;
bool crts_iflow;
bool cdtr_iflow;
bool ctdr_oflow;
bool ccar_oflow;
};
這將是12個字節。要改變它們,你必須做12次操作。
然後你就可以在字節做業務遵循布爾邏輯,這是由真值表定義:
的AND(&
),或(|
),而不是(~
)真值表:
| a | b | & | | a | b | | | | a | ~ |
| - | - | - | | - | - | - | | 0 | 1 |
| 0 | 0 | 0 | | 0 | 0 | 0 | | 1 | 0 |
| 0 | 1 | 0 | | 0 | 1 | 1 |
| 1 | 0 | 0 | | 1 | 0 | 1 |
| 1 | 1 | 1 | | 1 | 1 | 1 |
我們通常綽號而操作員「力爲零」和或者運營商作爲「力量1」,因爲 除非兩個值都爲1
, 和將導致0
,除非這兩個值都是0
,或將 導致1
。
所以,如果我們考慮到tty.c_cflag = 0x00000000
並要啓用奇偶校驗:
tty.c_cflag |= PARENB;
然後tty.c_cflag
將包含0x00001000
,即0b1000000000000
然後,你要設置7位大小:
tty.c_cflag |= CS7;
and tty.c_cflag
將包含0x00001200
,即現在0b1001000000000
,讓我們回到你的問題:你的「等價物」的例子是不是真的代表,爲你考慮CSIZE
和CS8
不含任何價值。
因此,讓我們通過您從示例獲取的代碼獲得:
tty.c_cflag &= ~PARENB; // No Parity
tty.c_cflag &= ~CSTOPB; // 1 Stop Bit
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; // 8 Bits
這裏,tty.c_cflag
包含未知值:
0b????????????????????????????????
而且你知道你想要無奇偶校驗,一個停止位,以及8位的數據大小。所以在這裏你 否定了「設置平價」值將其關閉:
~PARENB == 0b0111111111111
,然後使用而運營商,你迫使位爲零:
tty.c_cflag &= ~PARENB —→ 0b???????????????????0????????????
然後,你做同樣的CSTOPB
:
tty.c_cflag &= ~CSTOPB —→ 0b???????????????????0?0??????????
終於CSIZE
:
tty.c_cflag &= ~CSIZE —→ 0b???????????????????0?000????????
對於CSIZE
,目標是確保重置數據長度的兩位值。 然後你樹立正確的長度,迫使以1
值:
tty.c_cflag |= CS8 —→ 0b???????????????????0?011????????
其實,重置CSIZE
到00
然後設置CS8
到11
是無用的,因爲 直接tty.c_cflag |= CS8
這樣做將使11
。但是,如果您想要從CS8
更改爲CS7
,並且 將只設置其中一個位,另一個位置保持原始值,那麼這是很好的做法。
最後,當你打開你的串口時,庫會檢查這些值到 配置端口,並使用默認值爲你沒有強制的所有其他值,你可以使用 你的串口。
我希望我的解釋能夠幫助您更好地瞭解串口上的標誌設置 是怎麼回事,以及完全使用位掩碼。僅供參考,同樣的原理是 用於很多其他的東西,例如IPv4網絡掩碼,文件I/O等。
** C不是C++不是C!** – Olaf