【正文】
n is to control the local MODEM to dial remote terminal by telephone line base on Linux operating system. At the same time,it can make the data transmit between two MODEMs to achieve the purpose of data transportation. the MODEM is connected to the puter through the serial port RS232. Linux can control the serial port of the puter by POSIX termios interface. That can carry out the setting and data reading/writing of the serial port, the data transmit between puters (DTE) and MODEM (DCE), and the control from the puter to the MODEM, namely, the reading/writing of the serial port from the puter. The author of this paper acplishes the setting and reading/writing operation, using the AT mands to control the MODEM dialing, and a transport protocols for files. All of these make two PCs send and receive files from the public telephone line by using the MODEM. The design is intended to make the user who has not installed the work to transmit data with others by telephone lines using the 56k MODEM. Compared with the Inter, the telephone line is safer and widely distributed. The design makes use of the universality and the safety of the telephone line. Key words: Linux。 本文作者完成了對 RS232串行端的設(shè)置和讀寫操作,利用 AT命令控制 MODEM撥號,和一個文件傳輸協(xié)議,實(shí)現(xiàn)了兩臺 PC機(jī)利用 MODEM 通過公用電話網(wǎng),傳送和接收文件。 畢業(yè)設(shè)計 ( 論文 ) 一個 Linux下基于電話線路的數(shù)據(jù)通信程序的設(shè)計與實(shí)現(xiàn) 論文作者姓名: 申請學(xué)位專業(yè): 申請學(xué)位類別: 指導(dǎo)教師姓名(職稱): 論文提交日期: 一個 Linux下基于電話線路的數(shù)據(jù)通信程序的設(shè)計與實(shí)現(xiàn) 摘 要 本設(shè)計基于 Linux 操作系統(tǒng),控制本地 MODEM 通過電話線網(wǎng) 向異地終端機(jī)所帶 MODEM 撥號,并實(shí)現(xiàn)兩臺 MODEM 之間數(shù)據(jù)傳輸,達(dá)到兩臺計算機(jī)之間數(shù)據(jù)通信的目的。本設(shè)計旨在使沒有安裝網(wǎng)絡(luò)的用戶,利用 56K MODEM, 通過電話線網(wǎng) 方便和對方傳輸數(shù)據(jù)。 serial port。還有些特殊情況,當(dāng)單位或工廠需要幾臺計算機(jī)之間數(shù)據(jù)共享時,進(jìn)入互聯(lián)網(wǎng)有安全隱患,配置局域網(wǎng)費(fèi)用又很高,而且需要共享的數(shù)據(jù)很小,僅按字節(jié)計算,這時候利用 MODEM 通過公用電話網(wǎng)或電話專線傳輸數(shù)據(jù),既經(jīng)濟(jì),又安全,維護(hù)也非常簡單。 GCC的發(fā)展與 Linux 發(fā)展息息相關(guān) ,相輔相承。 MODEM 的功能非常豐富,這給程序的實(shí)現(xiàn)也帶來一定難度。, HPUX, SunOS174。,和許多其它的類 UNIX 操作系統(tǒng)。串行通訊包括了大多數(shù)的網(wǎng)絡(luò)設(shè)備、鍵盤、 麥克風(fēng),調(diào)制解調(diào)器和終端。 串行數(shù)據(jù)的速度常表示 為比特每秒 (bps) 或波特率 (波特 )。 RS232C RS232C 是 標(biāo)準(zhǔn)的串行通訊電氣接口, 是由美國 EIA(電子工業(yè)聯(lián)合會 )與BELL 等公司一起開 發(fā)并于 1969 年公布的通信協(xié)議,這個標(biāo)準(zhǔn)對串行通信接口的有關(guān)問題,如信號線功能、電器特性都作了明確規(guī)定,它適合于數(shù)據(jù)傳輸速率在0~20 000bit/s 范圍內(nèi)的通信。 EIARS232C 對電器特性、邏輯電平和各種信號線功能都作了規(guī)定。邏輯 0(SPACE) = +3V~ +15V。信號無效 (斷開, OFF 狀態(tài),負(fù)電壓 ) = 3V~ 15V。 RS574 定義了 9pin PC 串行接口和電壓。一位起 始 start 位 、 字符內(nèi)容的每一位 、 一位可選的校驗位 、 以及一位或一位半的終止位。如果是偶校驗 , 當(dāng)在字符中的 1是偶數(shù)個數(shù)時,校驗位為 0; 如果是奇校驗,當(dāng)字符中 第 5 頁 共 24頁 的 1 是奇數(shù)個時,校驗位為 0。 余下的被稱為停止位。它們相應(yīng)地表示 8位數(shù) 據(jù),無校驗, 1 位停止 和 7 位數(shù)據(jù),偶校驗, 1 位停止 。即 MODEM 實(shí)現(xiàn)了計算機(jī)數(shù)據(jù)與模擬電話線路適合傳輸?shù)哪M信號之間的相互轉(zhuǎn)換。 所謂 Hayes 兼容 MODEM,主要是指它能識別并執(zhí)行稱為 AT 命令的某些命令和命令串。 DTE 發(fā)送 AT 命令到 MODEM, MODEM 執(zhí)行后通過 RXD 返回結(jié)果給 DTE。 gcc 是可以在多種硬體平臺上編譯出可執(zhí)行程序的超級編譯器,其執(zhí)行效率與一般的編譯器相比平均效率要高20%~30%。 雖然 稱 gcc 是 C語言的編譯器,但使用 gcc 由 C語言源代碼文件生成可執(zhí)行文件的過程不僅僅是編譯的過程,而是要經(jīng)歷四個相互關(guān)聯(lián)的步驟 ∶ 預(yù)處理 (也稱預(yù)編譯, Preprocessing)、編譯 (Compilation)、匯編 (Assembly)和連接(Linking)。 當(dāng)所有的目標(biāo)文件都生成之后, gcc 就調(diào)用 ld 來完成最后的關(guān)鍵性工作,這個階段就是連接。 Linux 又是完全開放的操作系統(tǒng),很大程度上, Linux 的開放性,賦予了其無窮的生命力。整個程序使用 C 語言實(shí)現(xiàn)。 RS232C 建立與打開 一個輸入 /輸出 (I/O)端口是用來將資料送入計算機(jī)及從計算機(jī)取出的通道,有許多種類的輸出 /輸入端口,現(xiàn)在要處理的是串行端口,每一個串行端口必須有一個輸入 /輸出地址,以及一個中斷號碼 (IRQ),有四個串口設(shè)備對應(yīng)到 COM1 COM4: ttyS0 (COM1) address 0x3f8 IRQ 4 ttyS1 (COM2) address 0x2f8 IRQ 3 ttyS2 (COM3) address 0x3e8 IRQ 4 ttyS3 (COM4) address 0x2e8 IRQ 3 ttyS*是串口在 Linux 中的命名方式, COM*是串口在 Windows 中的命名方式,Linux 是以 ttyS0 開始命名的,與 Windows 從 COM1 開始命名不同。如果不設(shè)置虛擬機(jī)串口設(shè)備,在虛擬機(jī)下將無法識別到串口。像所有的設(shè)備一樣,Linux 提供設(shè)備文件來掛載端口。 fd = open(“ /dev/ttyS0” , O_RDWR | O_NOCTTY | O_NDELAY)。如果不指明這個標(biāo)志,此進(jìn)程將休眠,直到另一端發(fā)送 DCD 信號過來。 多數(shù)系統(tǒng)支持 POSIX termios 終端串行接口來改變,例如波特率,字符尺寸等參數(shù)。option)讀取 當(dāng) 前 串 口 的 狀 態(tài) , termios 成 員 設(shè) 置 完 之 后 , 再 使 用 tcsetattr (fd,TCSANOW,amp。options, B115200)。 amp。= ~PARENB。有些 Linux 版本并不支持cfsetispeed 和 cfsetospeed,但仍可以用 |= B115200這種方式進(jìn)行設(shè)置。 由異步通信可知,串行數(shù)據(jù)中數(shù)據(jù)可以有 5 位、 6 位、 7 位、 8 位,并且可以選擇奇偶校驗,或者無校驗。 c_cflag 還包括對硬件流設(shè)備的常數(shù),這里不會用到,可以不予理會。 amp。 c_lflag 控制輸入字符如何被串行驅(qū)動使用,它和 c_oflag 的設(shè)置應(yīng)該說是整個串口設(shè)置當(dāng)中最重要的,它直接影響到串口的工作方式。此模式下,可以每次讀取固定數(shù) 量的字符,并允許使用字符接收時間定時器。 非標(biāo)準(zhǔn)輸入輸出更適合此次項目, ICANON 代表標(biāo)準(zhǔn)模式,所以屏蔽它。非標(biāo)準(zhǔn)輸出模式更加靈活,適合做為本次設(shè)計的輸出模式,而對這種模式的選擇是非常簡單的,只要屏蔽 c_cflag 的 OPOST 項即可,屏蔽 OPOST項, c_oflag 其余的項就都被忽略。 [VTIME] = 200。 在非標(biāo)準(zhǔn)輸入模式中,輸入的數(shù)據(jù)并不組合成行,也不會進(jìn)行 erase、 kill、delete 等輸入處理。 MIN 0, TIME 0: 讀取函數(shù)會在收到了 MIN 字節(jié)的數(shù)據(jù)后,或者超 TIME時間沒有收到數(shù)據(jù)后返回。實(shí)際讀取到的字符數(shù), 或者要讀到的字符數(shù),會作為返回值返回。這時對 MIN, TIME 的設(shè)置才可以起作用。 最后,將設(shè)置的內(nèi)容存入串口 tcsetattr (fd,TCSANOW,amp。 從串口讀取數(shù)據(jù): n=read(fd, rdata, 1); rdata 是預(yù)先先定義好的字符數(shù)組,要讓 rdata 足夠大,才不會發(fā)生數(shù)據(jù)溢出錯誤。所以 MIN 和 TIME 的設(shè)置很重要。當(dāng) MODEM 啟動后,首先處于命令狀態(tài),連接后進(jìn)入在線狀態(tài)。這兩種狀態(tài)之間可以相互轉(zhuǎn)換。 MODEM 狀態(tài)之間的轉(zhuǎn)換如圖 5所示: 圖 5 MODEM工作狀態(tài)轉(zhuǎn)換 設(shè)計的目的就是要讓 MODEM 由開機(jī)時的命令狀態(tài)轉(zhuǎn)入在線狀態(tài),此時通過串口發(fā)給 MODEM 的數(shù)據(jù)不經(jīng) MODEM 處理的被傳出去,從遠(yuǎn)處接收到的數(shù)據(jù)也不經(jīng)MODEM 處理的被傳到串口。 首先,通過電話機(jī)撥號呼叫對方,電話交換臺向?qū)Ψ桨l(fā)出撥號呼叫信號,當(dāng)對方 DCE 收到該信號后,使 RI(振鈴信號 )有效,通知 DTE,已被呼叫。 (RTS/CTS 可只用于半雙工系統(tǒng)中做發(fā)送方式和接收方式的切換。當(dāng)對方的 DCE 收到載波 信號后,向?qū)Ψ降?DTE 發(fā)出 DCD信號 (數(shù)據(jù)載波檢出 ),通知其 DTE 準(zhǔn)備接收,同時,將載波信號解調(diào)為數(shù)據(jù)信號,從 RxD 線上送給 DTE, DTE 通過串行接收移位寄存器對接收到的位流進(jìn)行移位,當(dāng)收到 1 個字符的全部位流后,把該字符的數(shù)據(jù)位送到數(shù)據(jù)輸入寄存器, CPU可以從數(shù)據(jù)輸入寄存器讀取字符。這里只使用了“ ATE0V0”對 MODEM 初始化。 AT 命令的種類有很多種,有用戶接口命令、撥號呼叫命令、應(yīng)答命令等等13 種之多,而有很多撥號連接軟件對 MODEM 的初始化也只限于用戶接口方面,因為各種 MODEM 都自帶有廠家設(shè)置的出廠設(shè)置,這對撥號上網(wǎng)等普通應(yīng)用已經(jīng)足夠了。 n = 0 代表關(guān)閉回顯。 n = 0 代表以數(shù)字形顯示結(jié)果碼。 D 是撥號命令, T 修飾 D 命令,表示撥打的是音頻電話,( P 表 示脈沖電話,就是已經(jīng)被淘汰的帶撥號盤的電話)后面加要撥打的號碼即可?,F(xiàn)在就可以開始傳送數(shù)據(jù)給對方了??傮w思路是:發(fā)送方發(fā)送一個字符,接收方收到以后判斷此字符是新的字符還是對前一個接收到的字符的修改,如果是對前一個字符的修改,說明前一個字符在傳輸?shù)倪^程中出錯,則用這個修改字符覆蓋掉前一個字符;如果是新字符,則把 它賦值給一個變量,等待往接收文件中寫入,并把前一個字符存入接收文件。在新數(shù)據(jù)高 4位中: bit4|bit5 = 00,表示是新的數(shù)據(jù); bit4|bit5 = 01,表示是重新發(fā)送的數(shù)據(jù); bit4|bit5 = 10,表示文件名結(jié)束; bit4|bit5 = 11,表示文件結(jié)束。options)。options, B115200)。 //屏蔽數(shù)據(jù)位大小 |= CS8。= ~CSTOPB。= ~(ICANON | ECHO | ECHOE | ISIG)。 [VTIME] = 200。 //將新的設(shè)置寫入串口 } 串口讀寫的實(shí)現(xiàn) 對串口的讀寫是通過 read()和 write()來實(shí)現(xiàn)的,跟對文件的操作一樣(串口是個特殊的文件), 寫串口函數(shù)流程圖如圖 8如示: 圖 8 write函數(shù)流程 讀串口函數(shù)流程如圖 9 如示: 第 19 頁 共 24頁 圖 9 read函數(shù)流程 MODEM 初始化的實(shí)現(xiàn) int init_MODEM(void) { /*如果第一次初始化失敗則進(jìn)行第二次 ,如果第二次也失敗則程序退出 */ write_to_MODEM(ATE0V0\r, 7)。 } } return 1。options)。 tcsetattr(fd, TCSANOW, a