Linux操作系統(tǒng)下的串口通信學(xué)習(xí)筆記2007-04-15 17:08一、什么是串口通信
轉(zhuǎn)貼自:http://hi.baidu.com/foxberry/blog/item/ecb59718e0f0860634fa410a.html 串口通信是指計算機(jī)主機(jī)與外設(shè)之間以及主機(jī)系統(tǒng)與主機(jī)系統(tǒng)之間數(shù)據(jù)的串行傳送。使用 串口通信時,發(fā)送和接收到的每一個字符實際上都是一次一位的傳送的,每一位為1或者為 0。 二、串口通信的分類 串口通信可以分為同步通信和異步通信兩類。同步通信是按照軟件識別同步字符來實現(xiàn)數(shù) 據(jù)的發(fā)送和接收,異步通信是一種利用字符的再同步技術(shù)的通信方式。 2.1同步通信 同步通信是一種連續(xù)串行傳送數(shù)據(jù)的通信方式,一次通信只傳送一幀信息。這里的信息幀 與異步通信中的字符幀不同,通常含有若干個數(shù)據(jù)字符。如圖: 單同步字符幀結(jié)構(gòu) +-----+------+-------+------+-----+--------+-------+-------+ |同步|數(shù)據(jù) |數(shù)據(jù) |數(shù)據(jù) | ... |數(shù)據(jù) |CRC1|CRC2| |字符|字符1|字符2|字符3| |字符N| | | +-----+------+-------+------+-----+--------+-------+-------+ 雙同步字符幀結(jié)構(gòu) +-----+--------+------+-------+---+-------+-------+--------+ |同步 |同步 |數(shù)據(jù) |數(shù)據(jù) | ... |數(shù)據(jù) |CRC1|CRC2| |字符1|字符2|字符1|字符2| |字符N| | | +-----+--------+------+-------+---+-------+-------+--------+ 它們均由同步字符、數(shù)據(jù)字符和校驗字符(CRC)組成。其中同步字符位于幀開頭,用于確 認(rèn)數(shù)據(jù)字符的開始。數(shù)據(jù)字符在同步字符之后,個數(shù)沒有限制,由所需傳輸?shù)臄?shù)據(jù)塊長度 來決定;校驗字符有1到2個,用于接收端對接收到的字符序列進(jìn)行正確性的校驗。 同步通信的缺點是要求發(fā)送時鐘和接收時鐘保持嚴(yán)格的同步。 2.2異步通信 異步通信中,數(shù)據(jù)通常以字符或者字節(jié)為單位組成字符幀傳送。字符幀由發(fā)送端逐幀發(fā)送 ,通過傳輸線被接收設(shè)備逐幀接收。發(fā)送端和接收端可以由各自的時鐘來控制數(shù)據(jù)的發(fā)送 和接收,這兩個時鐘源彼此獨立,互不同步。 接收端檢測到傳輸線上發(fā)送過來的低電平邏輯"0"(即字符幀起始位)時,確定發(fā)送端已開 始發(fā)送數(shù)據(jù),每當(dāng)接收端收到字符幀中的停止位時,就知道一幀字符已經(jīng)發(fā)送完畢。 在異步通行中有兩個比較重要的指標(biāo):字符幀格式和波特率。 (1)字符幀,由起始位、數(shù)據(jù)位、奇偶校驗位和停止位組成。如圖: 無空閑位字符幀 +--+---+---+---+---+--+--+--+--+--+--+--+---+---+---+--+--+ |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電平,用于向接收設(shè)備表示發(fā)送端開始 發(fā)送一幀信息。 2.數(shù)據(jù)位:緊跟在起始位之后,可以設(shè)置為5位、6位、7位、8位,低位在前高位在后。 3.奇偶校驗位:位于數(shù)據(jù)位之后,僅占一位,用于表示串行通信中采用奇校驗還是偶校驗 。 (2)波特率,波特率是每秒鐘傳送二進(jìn)制數(shù)碼的位數(shù),單位是b/s。 異步通信的優(yōu)點是不需要傳送同步脈沖,字符幀長度也不受到限制。缺點是字符幀中因為 包含了起始位和停止位,因此降低了有效數(shù)據(jù)的傳輸速率。 三、什么是RS-232 RS-232-C 接口(又稱 EIA RS-232-C)它是在 1970 年由美國電子工業(yè)協(xié)會(EISB2.0、網(wǎng) 卡接口、Modem接口、VGA接口、擴(kuò)展塢、IEEE 1394以及六合一讀卡器,常用的端口一應(yīng)俱 全。 HP Ze2022AP Ze2022AP外觀上采用了惠普經(jīng)典的Pavilion DV1000的模具,模具成熟,外觀無可挑剔。銀 白色的主色調(diào),再經(jīng)過磨砂處理,視覺效果和觸感都相當(dāng)理想。Ze2202AP外形方方正正, 棱角分明,同時惠普還頗費心思地在前后采用了傾斜的切割,整個外形更顯精細(xì)動感。 Ze2202AP的端口主要分布在左右兩端,右側(cè)有2個USB接口、1個1394接口, SD/MS/MMC多功 能存儲卡讀取插槽,還有COMBO光驅(qū),以及S端口。左側(cè)從后到前分布電源接口、VGA輸出接 口、基座擴(kuò)展接口、 RJ11/RJ45網(wǎng)絡(luò)接口,1個USB接口,以及PCMCIA擴(kuò)展插槽。除此之外 ,這款機(jī)型同樣配備擴(kuò)展端口,擴(kuò)展性無疑是相當(dāng)強(qiáng)大的。 ThinkPad R50e 1834HC1 IBM的R系列實際上是T系列的經(jīng)濟(jì)版本,有人將其形象地表示為“偷工減料版的T”,外形 上依然承襲了IBM“小黑”一貫的酷。這款R50e頂蓋材料采用了ABS工程塑料,但借助不錯 的頂蓋框架,強(qiáng)度還是不錯的。 R150e的端口相對齊全,不僅有ThinkPad經(jīng)典的指定桿,接口上還包括RJ45/11網(wǎng)絡(luò)接口、 兩個USB接口、PC卡插槽、VGA接口、S視頻端口,但沒有IEEE1394接口,對經(jīng)常使用數(shù)碼產(chǎn) 品的消費者無疑是個壞消息。 五、全雙工與半雙工 1.全雙工,表示機(jī)器可以同時發(fā)送數(shù)據(jù)也可以接收數(shù)據(jù),有兩個獨立的數(shù)據(jù)通道(一個用 于發(fā)送,一個用于接收) 2.半雙工,表示機(jī)器不能在發(fā)送數(shù)據(jù)的同時也接收數(shù)據(jù)。 六、流量控制 1.使用軟件方法 使用特殊的字符來標(biāo)記數(shù)據(jù)流的開始和結(jié)束,比如XON,DC1,八進(jìn)制021來標(biāo)志開始,用X0F F,DC3,八進(jìn)制023來標(biāo)志結(jié)束。 2.使用硬件方法 使用RS232的CTS和RTS信號來代替特殊字符控制。當(dāng)接收方準(zhǔn)備接收更多數(shù)據(jù)時,設(shè)置CTS 為0,反之設(shè)置成1。對應(yīng)的發(fā)送端準(zhǔn)備發(fā)送數(shù)據(jù)時,設(shè)置RTS為0。 七、串口的訪問 串口設(shè)備在LINUX下與所有設(shè)備一樣都是通過設(shè)備文件來進(jìn)行訪問。 7.1打開串口 LINUX系統(tǒng)下串口設(shè)備是通過open函數(shù)來打開的,不過需要注意的是,一般用戶是沒有權(quán)限 訪問設(shè)備文件的,需要將打開的串口設(shè)備的訪問權(quán)限設(shè)置成一般用戶可以訪問的權(quán)限。 open函數(shù) 頭文件 #include #include #include 函數(shù)原型 int open(const char *pathname, int oflag, .../*, mode_t mode*/); 參數(shù) const char *pathname - 要打開文件的文件名稱,例如/dev/ttyS0 int oflag - 文件打開方式,可用標(biāo)志如下: O_RDONLY 以只讀方式打開文件 O_WRONLY 以只寫方式打開文件 O_RDWR 以讀寫方式打開文件 O_APPEND 寫入數(shù)據(jù)時添加到文件末尾 O_CREATE 如果文件不存在則產(chǎn)生該文件,使用該標(biāo)志需要設(shè)置訪問權(quán)限位mode_t O_EXCL 指定該標(biāo)志,并且指定了O_CREATE標(biāo)志,如果打開的文件存在則會產(chǎn)生一個錯誤 O_TRUNC 如果文件存在并且成功以寫或者只寫方式打開,則清除文件所有內(nèi)容,使得文件 長度變?yōu)? O_NOCTTY 如果打開的是一個終端設(shè)備,這個程序不會成為對應(yīng)這個端口的控制終端,如果 沒有該標(biāo)志,任何一個輸入,例如鍵盤中止信號等,都將影響進(jìn)程。 O_NONBLOCK 該標(biāo)志與早期使用的O_NDELAY標(biāo)志作用差不多。程序不關(guān)心DCD信號線的狀態(tài) ,如果指定該標(biāo)志,進(jìn)程將一直在休眠狀態(tài),直到DCD信號線為0。 O_SYNC 對I/O進(jìn)行寫等待 返回值 成功返回文件描述符,如果失敗返回-1 例如:以可讀寫方式打開/dev/ttyS0設(shè)備 int fd; /* 文件描述符 */ fd = open("/dev/ttyS0", O_RDWR | 0_NOCTTY | O_NONBLOCK); 7.2關(guān)閉串口 Linux系統(tǒng)下通過close函數(shù)來關(guān)閉串口設(shè)備 close函數(shù) 頭文件 #include 函數(shù)原型 int close(int filedes); 參數(shù) int filedes - 文件描述符 返回值 成功返回0,否則返回-1 例如:關(guān)閉打開的串口設(shè)備fd int ret; /* 返回標(biāo)志,用于判斷是否正常關(guān)閉設(shè)備 */ ret = close(fd); 7.3寫串口 寫串口是通過write函數(shù)來完成的 write函數(shù) 頭文件 #include 函數(shù)原型 ssize_t write(int filedes, const void *buff, size_t nbytes); 參數(shù) int filedes - 文件描述符 const void *buff - 存儲寫入數(shù)據(jù)的數(shù)據(jù)緩沖區(qū) size_t nbytes - 寫入數(shù)據(jù)字節(jié)數(shù) 返回值 ssize_t - 返回寫入數(shù)據(jù)的字節(jié)數(shù),該值通常等于nbytes,如果寫入失敗返回-1 例如:向終端設(shè)備發(fā)送初始化命令 int n = 0; /* 寫入字節(jié)數(shù) */ n = write(fd, "ATZ\r", 4); if(n == -1) { fprintf(stderr, "Wirte ATZ command error.\n"); } 7.4讀串口 讀串口是通過read函數(shù)來完成的 read函數(shù) 頭文件 #include 函數(shù)原型 ssize_t read(int filedes, void *buff, size_t nbytes); 參數(shù) int filedes - 文件描述符 void *buff - 存儲讀取數(shù)據(jù)的數(shù)據(jù)緩沖區(qū) size_t nbytes - 需要讀取的字節(jié)數(shù) 返回值 ssize_t - 成功讀取返回讀取的字節(jié)數(shù),否則返回-1 注意,在對串口進(jìn)行讀取操作的時候,如果是使用的RAW模式,每個read系統(tǒng)調(diào)用將返回當(dāng) 前串行輸入緩沖區(qū)中存在的字節(jié)數(shù)。如果沒有數(shù)據(jù),將會一致阻塞到有字符達(dá)到或者間隔 時鐘到期,或者發(fā)生錯誤。如果想使read函數(shù)在沒有數(shù)據(jù)的時候立即返回則可以使用fcnt l函數(shù)來設(shè)置文件訪問屬性。例如: fcntl(fd, F_SETFL, FNDELAY); 這樣設(shè)置后,當(dāng)沒有可讀取的數(shù)據(jù)時,read函數(shù)立即返回0。 通過fcntl(fd, F_SETFL, 0)可以設(shè)置回一般狀態(tài)。 例如:從終端讀取5個字節(jié)的應(yīng)答數(shù)據(jù) int nRead; /* 從終端讀取的字節(jié)數(shù) */ char buffer[256]; /* 接收緩沖區(qū) */ nRead = read(fd, buffer, 5); if(nRead == -1) { fprintf(stderr, "Read answer message error.\n"); } 八、終端配置 8.1 POSIX終端接口 大多數(shù)系統(tǒng)都支持POSIX終端接口,POSIX終端通過一個termios結(jié)構(gòu)來進(jìn)行控制,該結(jié)構(gòu)定 義在termios.h文件中。 termios結(jié)構(gòu) struct termios { tcflag_t c_iflag; /* 輸入選項標(biāo)志 */ tcflag_t c_oflag; /* 輸出選項標(biāo)志 */ tcflag_t c_cflag; /* 控制選項標(biāo)志 */ tcflag_t c_lflag; /* 本地選項標(biāo)志 */ cc_t c_cc[NCCS]; /* 控制特性 */ }; c_iflag成員 Flag Description GNBRK 忽略輸入中的BREAK狀態(tài) BRKINT 如果設(shè)置了IGNBRK,將忽略BREAK。如果沒有設(shè)置,但是設(shè)置了BRKINT,那么BREA K將使得輸入和輸出隊列被刷新,如果終端是一個前臺進(jìn)程組的控制終端,這個進(jìn)程組中所 有進(jìn)程將收到SIGINT信號。如果既未設(shè)置IGNBRK也未設(shè)置BRKINT,BREAK將視為NUL同義字 符,除非設(shè)置了PARMRK,這種情況下被視為序列\(zhòng)377\0\0 IGNPAR 忽略楨錯誤和奇偶校驗錯誤 PARMRK 如果沒有設(shè)置IGNPAR,在有奇偶校驗錯誤或者楨錯誤的字符前插入\377\0。如果既 沒有設(shè)置IGNPAR也沒有設(shè)置PARMRK,將所有奇偶校驗錯誤或者楨錯誤的字符視為\0。 |
|