智汇工业-智慧工业、智能制造及工业智能、工业互联门户网站,专业的工业“互联网+”传媒

Win32串口編程

來源:網絡

點擊:2411

A+ A-

所屬頻道:新聞中心

關鍵詞: Win32,串口編程

      Win32串口編程

      Win32下串口通信與16位串口通信有很大的區別。在Win32下,可以使用兩種編程方式實現串口通信,其一是調用的Windows的API函數,其二是使用ActiveX控件。使用API 調用,可以清楚地掌握串口通信的機制,熟悉各種配置和自由靈活采用不同的流控進行串口通信。下面介紹串口操作的基本知識。

      打開串口:使用CreateFile()函數,可以打開串口。有兩種方法可以打開串口,一種是同步方式(NonOverlapped),另外一種異步方式(Overlapped)。使用Overlapped打開時,適當的方法是:

      HANDLE hComm;

      hComm = CreateFile( gszPort,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);

      if (hComm == INVALID_HANDLE_VALUE)

      // error opening port; abort

      配置串口:

      1.DCB配置

      DCB(Device Control Block)結構定義了串口通信設備的控制設置。許多重要設置都是在DCB結構中設置的,有三種方式可以初始化DCB。

      (1)通過GetCommState()函數得DCB的初始值,其使用方式為:

      DCB dcb = {0};

      if (!GetCommState(hComm, &dcb))

      // Error getting current DCB settings

      else

      // DCB is ready for use.

      (2)用BuildCommDCB()函數初始化DCB結構,該函數填充 DCB的波特率、奇偶校驗類型、數據位、停止位。對于流控成員函數設置了缺省值。其用法是:

      DCB dcb;

      FillMemory(&dcb, sizeof(dcb), 0);

      dcb.DCBlength = sizeof(dcb);

      if (!BuildCommDCB(“9600,n,8,1“, &dcb)) {

      // Couldn‘t build the DCB. Usually a problem

      // with the communications specification string.

      return FALSE;

      }

      else

      // DCB is ready for use.

      (3)用SetCommState()函數手動設置DCB初值。用法如下:

      DCB dcb;

      FillMemory(&dcb, sizeof(dcb), 0);

      if (!GetCommState(hComm, &dcb)) // get current DCB

      // Error in GetCommState

      return FALSE;

      // Update DCB rate.

      dcb.BaudRate = CBR_9600 ;

      // Set new state.

      if (!SetCommState(hComm, &dcb))

      // Error in SetCommState.

      Possibly a problem with the communications

      // port handle or a problem with the DCB structure itself.

      手動設置DCB值時,DCB的結構的各成員的含義,可以參看MSDN幫助。

     

      2.流控設置

      硬件流控:串口通信中的硬件流控有兩種,DTE/DSR方式和RTS/CTS方式,這與DCB結構的初始化有關系,DCB結構中的OutxCtsFlow、 fOutxDsrFlow、fDsrSensitivity、fRtsControl、fDtrControl幾個成員的初始值很關鍵,不同的值代表不同流控,也可以自己設置流控,但建議采用標準流行的流控方式。采用硬件流控時,DTE、DSR、RTS、CTS的邏輯位直接影響到數據的讀寫及收發數據的緩沖區控制。

      軟件流控:串口通信中采用特殊字符XON和XOFF作為控制串口數據的收發。與此相關的DCB成員是:fOut、fInX、XoffChar、XonChar、 XoffLim和XonLim。具體含義參見MSDN幫助。

      串口讀寫操作:串口讀寫有兩種方式:同步方式(NonOverlapped)和異步方式(Overlapped)。同步方式是指必須完成了讀寫操作,函數才返回,這可能造成程序死掉,因為如果在讀寫時發生了錯誤,永遠不返回就會出錯,可能線程將永遠等待在那兒。而異步方式則靈活得多,一旦讀寫不成功,就將讀寫掛起,函數直接返回,可以通過GetLastError函數得知讀寫未成功的原因,所以常常采用異步方式操作。

      讀操作:ReadFile()函數用于完成讀操作。異步方式的讀操作為:

      DWORD dwRead;

      BOOL fWaitingOnRead = FALSE;

      OVERLAPPED osReader = {0};

      // Create the overlapped event. Must be closed before exiting

      // to avoid a handle leak.

      osReader.hEvent = CreateEvent

      (NULL, TRUE, FALSE, NULL);

      if (osReader.hEvent == NULL)

      // Error creating overlapped event; abort.

      if (!fWaitingOnRead) {

      // Issue read operation.

      if (!ReadFile(hComm, lpBuf, READ_BUF_SIZE,

      &dwRead, &osReader)) {

      if (GetLastError() != ERROR_IO_PENDING)

      // read not delayed?

      // Error in communications; report it.

      else

      fWaitingOnRead = TRUE;

      }

      else {

      // read completed immediately

      HandleASuccessfulRead(lpBuf, dwRead);

      }

      }

      如果讀操作被掛起,可以調用WaitForSingleObject()函數或WaitForMuntilpleObjects()函數等待讀操作完成或者超時發生,再調用 GetOverlappedResult()得到想要的信息。

      寫操作:與讀操作相似,故不詳述,調用的API函數是: WriteFile函數。

      串口狀態:

      (1)通信事件:用SetCommMask()函數設置想要得到的通信事件的掩碼,再調用WaitCommEvent()函數檢測通信事件的發生。可設置的通信事件標志(即SetCommMask()函數所設置的掩碼)可以有EV_BREAK、EV_CTS、EV_DSR、 EV_ERR、EV_RING、EV_RLSD、EV_RXCHAR、EV_RXFLAG、EV_TXEMPTY。

     

      注意:1對于EV_RING標志的設置,WIN95是不會返回EV_RING事件的,因為WIN95不檢測該事件。2設置EV_RXCHAR,可以檢測到字符到達,但是在綁定此事件和ReadFile()函數一起讀取串口接收數據時,可能會出現錯誤,造成少讀字節數,具體原因查看MSDN幫助。可以采用循環讀的辦法,另外一個比較好的解決辦法是調用ClearCommError()函數,確定在一次讀操作中在緩沖區中等待被讀的字節數。

      (2)錯誤處理和通信狀態:在串口通信中,可能會產生很多的錯誤,使用ClearCommError()函數可以檢測錯誤并且清除錯誤條件。

      (3)Modem狀態:用SetcommMask()可以包含很多事件標志,但是這些事件標志只指示在串口線路上的電壓變化情況。而調用 GetCommModemStatus()函數可以獲得線路上真正的電壓狀態。

      擴展函數:如果應用程序想用自己的流控,可以使用 EscapeCommFunction()函數設置DTR和RTS線路的電平。

      通信超時:在通信中,超時是個很重要的考慮因素,因為如果在數據接收過程中由于某種原因突然中斷或停止,如果不采取超時控制機制,將會使得I/O線程被掛起或無限阻塞。串口通信中的超時設置分為兩步,首先設置 COMMTIMEOUTS結構的五個變量,然后調用SetcommTimeouts()設置超時值。對于使用異步方式讀寫的操作,如果操作掛起后,異步成功完成了讀寫,WaitForSingleObject()或 WaitForMultipleObjects()函數將返回WAIT_OBJECT_0,GetOverlappedResult()返回TRUE。其實還可以用GetCommTimeouts()得到系統初始值。

      關閉串口:程序結束或需要釋放串口資源時,應該正確關閉串口,關閉串口比較簡單,使用API調用CloseHandle()關閉串口的句柄就可以了。

      調用方法為:CloseHandle(hComm);

      但是值得注意的是在關閉串口之前必須保證讀寫串口線程已經退出,否則會引起誤操作,一般采用的辦法是使用事件驅動機制,啟動一事件,通知串口讀寫線程強制退出,在線程退出之前,通知主線程可以關閉串口。

      二、實現

      1.程序設計思路

      對于不同的應用程序,雖然界面不同,但是如果采用串口與主機之間的通信,對串口的處理方式大致相似,無非就是通過串口收發數據,對于通過串口接收到的數據,交給上層軟件處理顯示,對于上層要發給串口的數據,進行轉發。但在實際編程中,由于采用的通信方式和流控不同,串口設置也不同,這就涉及到 DCB的初始化問題和讀寫串口等細節問題。串口通信應用程序設計的總體思路(即操作過程)是:首先,確定要打開的串口名、波特率、奇偶校驗方式、數據位、停止位,傳遞給CreateFile()函數打開特定串口;其次,為了保護系統對串口的初始設置,調用 GetCommTimeouts()得到串口的原始超時設置;然后,初始化DCB對象,調用SetCommState() 設置DCB,調用SetCommTimeouts()設置串口超時控制;再次,調用SetupComm()設置串口接收發送數據的緩沖區大小,串口的設置就基本完成,之后就可以啟動讀寫線程了。

      一般來說,串口的讀寫由串口讀寫線程完成,這樣可以避免讀寫阻塞時主程序死鎖。對于全雙工的串口讀寫,應該分別開啟讀線程和寫線程;對于半雙工和單工的,建議只需開啟一個線程即可。在線程中,按照預定好的通信握手方式,正確檢測串口狀態,讀取發送串口數據。

      2.實現細節

      在半雙工的情況下,首先完成必要的串口配置,成功打開串口、DCB設置、超時設置;然后開啟線程,如: CwinThread hSerialThread = (CWinThread*) AfxBeginThread(SerialOperation,hWnd,THREAD_PRIORITY_NORMAL); 其中開啟之線程為SerialOperation,優先級為普通。

      全雙工情況下的串口編程,與單工差不多,區別僅僅在于啟動雙線程,分別為讀線程和寫線程,讀線程根據不同的事件或消息,通過不斷查詢串口所收到的有效數據,完成讀操作;寫線程通過接收主線程的發送數據事件和要發送的數據,向串口發送。

    (審核編輯: 智匯小新)

    聲明:除特別說明之外,新聞內容及圖片均來自網絡及各大主流媒體。版權歸原作者所有。如認為內容侵權,請聯系我們刪除。

    主站蜘蛛池模板: 注塑机螺杆_光学无卤耐磨耐腐蚀螺杆_合金材料_螺杆研磨抛光机_杰宇螺杆 | 制冷设备|冷库|空调|配件【制冷通】国内领先的制冷服务平台 | 拉丝模|高晶异形拉丝模|联合拉拔机模具|钼丝拉丝模|金刚石纳米涂层模|焊丝拉丝模|钨钢拉丝模|聚晶拉丝模_河北恩泰利嘉金属制品有限公司 | 珠海市甜菊科技发展有限公司 | 气调包装机厂家-真空包装机价格-气调包装机-锁鲜包装机-江苏大江智能装备有限公司 | 眉山净源居环保科技有限公司,眉山除甲醛公司,眉山甲醛治理,眉山保洁服务,眉山家政保洁,眉山家电维修 - 眉山净源居环保科技有限公司,眉山除甲醛公司,眉山甲醛治理,眉山保洁服务,眉山家政保洁,眉山家电维修 | 威海保温板,威海泡沫,威海EPS,威海EPP-威海东兴泡塑科技有限公司 | 热电阻_热电偶_压力表_压力变送器_磁翻板液位计 - 淮安忠和测控仪表有限公司 | 模压机|硫化机|平板硫化机生产厂家-南通海利特橡塑机械有限公司 模压化粪池_三格式化粪池_玻璃钢化粪池厂家 | 台车炉厂家_台车式退火炉_台车式回火炉—安徽大新工业炉有限公司 | 阻抗分析仪 阻抗测试仪 介电常数测试仪 充电枪测试仪-苏州腾斯凯电子科技有限公司 | 廊坊纳科新材料技术有限公司--纳科新材料技术有限公司|廊坊纳科新材料|纳科新材料技术 | 网络广播_公共广播系统_校园,学校数字ip,itc智能广播系统方案 | 呕吐毒素快速检测仪-黄曲霉毒素测定仪-玉米赤霉烯酮快速检测卡-南京微测生物科技有限公司 | 康复支具-医用颈托-辅助固定矫形器-骨折固定带生产厂家-安平县康信医疗器械有限公司 | 箱包定制_广州箱包厂_双肩电脑背包_双肩旅行包_拉杆箱包_商务公文包_包包批发,深圳爱自由,礼品箱包定制,电话:400-0061-690 | 陕西筱润智能科技有限公司 干部人事智能档案柜 智能密集架 智能档案柜 部队选层文件智能柜 智能枪弹柜 财务智能档案柜 边防武警智能密集架 医院智能档案柜 部队选层文件智能柜智能枪弹柜 学校医院文件柜 企事业单位公检法智能文件柜 生产厂家-筱润智能科技有限公司 RFID射频智能密集架 全自动智能选层档案柜 智能密保柜 枪柜部队营房营具床桌椅办公家具 办公用品档案盒设备货架 全自动智能选层柜生产厂家-筱润智能科技有限公司 | 网架厂_网架加工厂家_徐州网架公司报价--三华网架制造商 | 贴膜机厂家|高精度|手机贴膜机|全自动|半自动|无边覆膜机-深圳荷花自动化 | 石家庄华龙鼎电动门,石家庄电动门电话,石家庄电动门配件,石家庄电动门维修电话,石家庄电动门安装电话,石家庄华龙电动门 | 中国工业网_网络工业品牌 资讯创造价值 | 透明膜包装机_三维包装机_上海拓懿机械有限公司 | 装盒机|全自动封盒机|纸盒子包装机|高速装盒机定制-温州胜泰机械有限公司 | 专业无机盐,化工产品检测公司,水处理剂检测公司,第三方水质检测机构—准诺检测 | 推拉雨棚,防雨棚,遮阳遮雨棚,伸缩雨棚,移动雨棚,电动雨棚,雨棚制作厂家 - 山东创力篷业 | 运动控制器_数控系统_廊坊市九盈数控技术公司「官网」 | 辣椒烘干机-百信机械提供大中小型辣椒烘干机房设备视频图片厂家价格多少钱 | 专业的展会信息服务平台 - 展加| 无锡大型数控龙门铣,喷涂加工,回火抛丸加工,精密不锈钢焊接机床身机床底座制造加工-无锡美高帝机械有限公司 | 美缝剂_美缝剂加盟_瓷砖美缝剂_美缝剂厂家_填缝剂_领翔美缝剂-【官网】 | 天木生物科技有限公司-高通量自动化-细胞筛选平台 | 气泡膜机_气垫膜机_缠绕膜机_瑞安市优特机械厂 | 合金锤头_破碎机锤头_耐磨锤头_巩义市东辰实业有限公司 | 亚澳农机-亚澳南阳农机股份公司,旋耕机,旋播机,旋播施肥机,免耕播种机,旋耕播草多用机,果园机械-首页 | 送料机-冲床送料机-伺服送料机 - 常州市佳王精密机械有限公司 | 西安防静电地板_防静电地板厂家_防静电地板价格_OA网络地板_写字楼架空地板_机房墙板安装-红梅防静电地板厂家直销 | 长春市龙飞数码印务有限公司,龙飞印务,长春商务印刷,长春精品包装,长春数码快印 | 耐火砖厂家价格-郑州荣盛窑炉耐火材料有限公司 | 开拓者喷雾设备有限公司专业生产喷嘴,喷雾设备,清洗,喷涂,降温,除尘,润滑等喷雾系统的方案解决商 | 实木中药柜,实木中药斗,木制中药柜,木制中药柜的价格,实木中草药柜,安国美佳中药柜厂家 | 望崖阁书法培训班-杭州书法高考培训班2023届招生简章-优清画院 |