WIN95 界 面 下 的VC++ 串 口 通 訊 程 序 (轉)

worldblog發表於2007-12-06
WIN95 界 面 下 的VC++ 串 口 通 訊 程 序 (轉)[@more@] 


實用技巧

WIN95 界 面 下 的VC++ 串 口 通 訊 程 序

南 京 石 油 物 探 研 究 所
吳 鳳 華

---- Visual C++ 以 其 界 面 的 開 放 性 著 稱, 因 其 簡 單 易 學、32 位 面 向 對 象 的 程 序 設 計 及Activate X 的 靈 活 性 而 受 廣 大 計 算 機 開 發 者 的 青 睞, 廣 泛 應 用 於 各 個 領 域。 怎 樣 利 用VC++ 進 行 串 口 的 通 訊 編 程, 這 是 一 種 基 本 功。 特 別 是 在 實 時 監 控、 大 小 型 設 備 的 整 個 生 產 過 程 控 制 等 方 面,VC++ 的 串 口 編 程 顯 得 尤 為 重 要。 我 曾 參 與 編 寫 了 無 線 電 非 法 頻 段 佔 用 的 實 時 監 控 系 統、 混 凝 土 攪 拌 自 動 化 生 產 控 制 系 統。 下 面 就 自 己 的 一 點 經 驗 體 會 與 讀 者 分 享。

---- 一 般 情 況 下 的 串 口 通 訊 無 非 採 用 兩 種 方 法: 一 是 利 用 的 通 訊 函 數, 二 是 利 用VC++( 或 其 它 語 言) 的 標 準 通 訊 函 數_inp、_outp 來 實 現。

---- Windows 的API 函 數 雖 然 使 用 面 很 廣, 但 由 於 比 較 復 雜 而 有 一 定 的 難 度, 故 簡 單 述 之, 其 編 程 過 程 分 為 初 始 化 串 口、 配 置 串 口、 超 時 控 制、 數 據 傳 輸、 關 閉 串 口 等。

---- VC++ 串 口 通 訊

---- 一、 初 始 化 串 行 通 訊 口

---- 通 過 計 算 機 串 口 進 行 通 訊 之 前, 必 須 根 據 監 控 設 備 的 有 關 通 訊 參 數, 約 定 雙 方 的 通 訊 方 式, 包 括 波 特 率 的 設 置、 奇 偶 位 校 驗 及 停 止 位 的 設 立。 確 定 數 據 傳 輸 幀 格 式, 確 定UART 操 作 方 式。 逐 個 對 線 路 控 制 寄 存 器、 波 特 率 因 子 寄 存 器 和M0DEM 寄 存 器 寫 入 操 作。

---- 先 確 定 計 算 機 的 通 訊 口 地 址 是3F8 還 是2F8( 根 據 用 戶 的 不 同 要 求, 可 加 插 卡 而 有3E8、2E8, 甚 至 使 用 多 用 戶 卡 而 有3220、3228、4220、4228、5220、5228), 例 中 以2F8 做 為 端 口 地 址。 利 用_outp(PORT,0x0c) 將 波 特 率 設 置 為9600,(_outp(PORT,0x30) 將 波 特 率 設 置 為2400,_outp(PORT,0x18) 將 波 特 率 設 置 為4800)。

---- 數 據 傳 輸 格 式 則 由 地 址PORT+3 確 定, 如 選 用 七 位 一 停 止 位 偶 校 驗, 則 採 用outp(PORT+3,0x3a) 及outp(PORT+3 ,0x1a) 兩 個 語 句; 如 選 用 八 位 一 停 止 位 無 奇 偶 校 驗, 則 採 用outp(PORT+3,0x3a) 及outp(PORT+3 ,0x03) 兩 個 語 句; 至 於 為 什 麼, 可 參 考 有 關 異 步 通 訊 數 據 格 式 方 面 的 書。

---- 二、 查 詢 發 送 流 程

---- 只 需 檢 測 到UART 發 送 器 保 持 寄 存 器 為 空, 即 向UART 輸 出 一 個 字 符。 發 送 方 首 先 輸 出RTS 和DTR 有 效, 檢 測MODEM 寄 存 器, 只 有 收 到DEC 輸 入 的CTS、DSR 有 效,CPU 才 向UART 輸 出 一 發 送 字 符。

---- 三、 查 詢 接 收 流 程

---- 只 需CPU 檢 測 到UART 接 收 器 數 據 準 備 就 緒, 即 可 從 接 收 器 數 據 寄 存 器 中 讀 取 一 字 符。 接 收 方 首 先 輸 出 數 據 終 端 就 緒 有 效(DTR=1), 然 後 檢 測MODEM 狀 態 寄 存 器, 只 有DSR=1,CPU 才 接 收 一 字 符。

---- 程 序 例

---- 為 了 編 程 的 方 便, 我 把 實 時 監 控 過 程 中 的 串 口 初 始 化、 串 口 接 收、 串 口 發 送 等 以 子 程 序 的 形 式 呈 現。

確 定 通 訊 口 地 址:int PORT=0x2F8; 接 收 字 符 子 程 序: char near reayte(void) { int time_limit; char sta; time_limit=5000; while ((sta=inp(PORT+5) & 0x01) !=1) { time_limit--; if (time_limit==0) { /*printf("s=%4xm ",sta);*/return 0;} } return inp(PORT); printf("%s",inp(PORT)); } 發 送 字 符 子 程 序: void sendbyte(unsigned char sdata) { long int time_limit; time_limit=50000; while ((inp(PORT+5) & 0xf0) != 0x60) { time_limit--; if (time_limit==0) break; } outp(PORT,sdata); } 串 口 初 始 化 子 程 序: void init_com(PORT) { char i; outp(PORT+3,0x80); outp(PORT ,0x0C); /* baud rate 9600 */ outp(PORT+1,0); /*8bit 1stop no even */ outp(PORT+3 ,0x3a); outp(PORT+3 ,0x03); i=inp(PORT+5) & 0xfe; outp(PORT+5,i); } 字 符 串 發 送 子 程 序: void sendstrn(char *mess) { for (; *mess; mess++) sendbyte(*mess); sendbyte(0X0D); /*sendbyte(0X0A); */ } 簡 單 的 主 程 序: init_com(ox2f8); sendstrn(PORT,"FUNC"); j=0; line=0; do { for(i=0;i<25;i++) ttemp[i]="" ; if(readbyte(PORT)="='M')" { i="0;" do { ttemp[i]="readbyte(PORT);" i++; }while((ttemp[i-2]!="13)&&(ttemp[i-1]!=10));" line++; dcqd.TextOut(450,line*20+180,ttemp);} j++;} while((j< 1000)&&(line< 5)); Wed, 16 Sep 1998 "acejet" < cejet@public1.ptt.js.cn>


 


 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988839/,如需轉載,請註明出處,否則將追究法律責任。

相關文章