Linux操作系統(tǒng)下的串口通信學(xué)習(xí)筆記2007-04-15 17:08一、什么是串口通信
轉(zhuǎn)貼自:http://hi.baidu.com/foxberry/blog/item/ecb59718e0f0860634fa410a.html 串口通信是指計算機主機與外設(shè)之間以及主機系統(tǒng)與主機系統(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個,,用于接收端對接收到的字符序列進行正確性的校驗。 同步通信的缺點是要求發(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)波特率,波特率是每秒鐘傳送二進制數(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接口、擴展塢,、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輸出接 口,、基座擴展接口、 RJ11/RJ45網(wǎng)絡(luò)接口,,1個USB接口,,以及PCMCIA擴展插槽。除此之外 ,,這款機型同樣配備擴展端口,,擴展性無疑是相當(dāng)強大的。 ThinkPad R50e 1834HC1 IBM的R系列實際上是T系列的經(jīng)濟版本,,有人將其形象地表示為“偷工減料版的T”,,外形 上依然承襲了IBM“小黑”一貫的酷。這款R50e頂蓋材料采用了ABS工程塑料,,但借助不錯 的頂蓋框架,,強度還是不錯的。 R150e的端口相對齊全,,不僅有ThinkPad經(jīng)典的指定桿,,接口上還包括RJ45/11網(wǎng)絡(luò)接口、 兩個USB接口,、PC卡插槽,、VGA接口、S視頻端口,,但沒有IEEE1394接口,,對經(jīng)常使用數(shù)碼產(chǎn) 品的消費者無疑是個壞消息。 五,、全雙工與半雙工 1.全雙工,,表示機器可以同時發(fā)送數(shù)據(jù)也可以接收數(shù)據(jù),有兩個獨立的數(shù)據(jù)通道(一個用 于發(fā)送,,一個用于接收) 2.半雙工,,表示機器不能在發(fā)送數(shù)據(jù)的同時也接收數(shù)據(jù),。 六、流量控制 1.使用軟件方法 使用特殊的字符來標(biāo)記數(shù)據(jù)流的開始和結(jié)束,,比如XON,DC1,八進制021來標(biāo)志開始,,用X0F F,DC3,八進制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è)備文件來進行訪問,。 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)志,任何一個輸入,,例如鍵盤中止信號等,都將影響進程,。 O_NONBLOCK 該標(biāo)志與早期使用的O_NDELAY標(biāo)志作用差不多,。程序不關(guān)心DCD信號線的狀態(tài) ,如果指定該標(biāo)志,,進程將一直在休眠狀態(tài),,直到DCD信號線為0。 O_SYNC 對I/O進行寫等待 返回值 成功返回文件描述符,,如果失敗返回-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 注意,,在對串口進行讀取操作的時候,如果是使用的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)來進行控制,,該結(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將使得輸入和輸出隊列被刷新,,如果終端是一個前臺進程組的控制終端,,這個進程組中所 有進程將收到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,。 |
|