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

用Win32 API實(shí)現(xiàn)串行通信

來源:網(wǎng)絡(luò)

點(diǎn)擊:2248

A+ A-

所屬頻道:新聞中心

關(guān)鍵詞: Win32,串行通信

    用Win32 API實(shí)現(xiàn)串行通信

    串口是常用的計(jì)算機(jī)與外部串行設(shè)備之間的數(shù)據(jù)傳輸通道,由于串行通信方便
    易行,所以應(yīng)用廣泛。我們可以利用Windows API 提供的通信函數(shù)編寫出高可移植性的
    串行通信程序。
        在Win16中,可以利用OpenComm、CloseComm和WriteComm等函數(shù)打開、關(guān)閉和
    讀寫串口。但在Win32中,串口和其他通信設(shè)備均被作為文件處理,串口的打開、關(guān)閉
    和讀寫等操作所用的API函數(shù)與操作文件的函數(shù)相同。可通過CreateFile函數(shù)打開串口
    ,通過CloseFile函數(shù)關(guān)閉串口,通過CommProp、DCB結(jié)構(gòu)、GetCommProperties、
    SetCommProperties、GetCommState及SetCommState等函數(shù)設(shè)置串口狀態(tài),通過函數(shù)
    ReadFile和WritFile讀寫串口。 
    VC++ 6.0是Windows應(yīng)用程序開發(fā)的主流語言之一,它具有良好的圖形設(shè)計(jì)
    界面并支持面向?qū)ο蟮某绦蛟O(shè)計(jì)方法。本文結(jié)合一個(gè)實(shí)例介紹在VC++ 6.0下如何利用
    Win32 API 實(shí)現(xiàn)串行通信程序。 
    實(shí)現(xiàn)原理 
        本文的實(shí)例來自一個(gè)水泥發(fā)貨系統(tǒng),在系統(tǒng)中,需要將通過總量傳感器采集到
    的倉重值傳入到計(jì)算機(jī)中,以便系統(tǒng)做出相應(yīng)的處理。這需要使用串行通信來完成采集
    數(shù)據(jù)的傳遞工作。 
        對(duì)于串行通信設(shè)備,Win32 API支持同步和異步兩種I/O操作。同步操作方式的
    程序設(shè)計(jì)相對(duì)比較簡單,但I(xiàn)/O操作函數(shù)在I/O操作結(jié)束前不能返回,這將掛起調(diào)用線程
    ,直到I/O操作結(jié)束。異步操作方式相對(duì)要復(fù)雜一些,但它可讓耗時(shí)的I/O操作在后臺(tái)進(jìn)
    行,不會(huì)掛起調(diào)用線程,這在大數(shù)據(jù)量通信的情況下對(duì)改善調(diào)用線程的響應(yīng)速度是相當(dāng)
    有效的。異步操作方式特別適合同時(shí)對(duì)多個(gè)串行設(shè)備進(jìn)行I/O操作和同時(shí)對(duì)一個(gè)串行設(shè)
    備進(jìn)行讀/寫操作。這兩種操作方式的程序設(shè)計(jì)基本思想是相似的,本文將針對(duì)同步操
    作方式給出具體的通信程序設(shè)計(jì),同時(shí)簡單說明如何實(shí)現(xiàn)異步的I/O操作。 
    串行設(shè)備的初始化 
        串行設(shè)備的初始化是利用CreateFile函數(shù)實(shí)現(xiàn)的。該函數(shù)獲得串行設(shè)備句柄并
    對(duì)其進(jìn)行通信參數(shù)設(shè)置,包括設(shè)置輸出/接收緩沖區(qū)大小、超時(shí)控制和事件監(jiān)視等。 
    //串行設(shè)備句柄; 
    HANDLE hComDev=0;  
    //串口打開標(biāo)志; 
    BOOL bOpen=FALSE; 
    //線程同步事件句柄; 
    HANDLE hEvent=0;  
    BOOL SetupSynCom() 
    {  
     DCB dcb; 
     COMMTIMEOUTS timeouts; 
     //設(shè)備已打開 
     if(bOpen) return FALSE;   
     //打開COM1 
    if((hComDev=CreateFile(“COM1”,GENERICREAD|GENERICWRITE,0,NULL,OPEN
    EXISTING,FILEATTRIBUTENORMAL,NULL))== 
    INVALIDHANDLEVALUE)  
    return FALSE; 
    //設(shè)置超時(shí)控制 
    SetCommTimeouts(hComDev,&timeouts);  
     //設(shè)置接收緩沖區(qū)和輸出緩沖區(qū)的大小 
     SetupComm(hComDev,1024,512);  
    //獲取缺省的DCB結(jié)構(gòu)的值 
     GetCommState(hComDev,&dcb);  
    //設(shè)定波特率為9600 bps 
     dcb.BaudRate=CBR9600;  
    //設(shè)定無奇偶校驗(yàn) 
     dcb.fParity=NOPARITY;  
    //設(shè)定數(shù)據(jù)位為8 
     dcb.ByteSize=8;  
     //設(shè)定一個(gè)停止位 
     dcb.StopBits=ONESTOPBIT;  
    //監(jiān)視串口的錯(cuò)誤和接收到字符兩種事件 
     SetCommMask(hComDev,EVERR|EVRXCHAR);  
    //設(shè)置串行設(shè)備控制參數(shù) 
     SetCommState(hComDev,&dcb);  
    //設(shè)備已打開 
     bOpen=TRUE;  
     //創(chuàng)建人工重設(shè)、未發(fā)信號(hào)的事件 
     hEvent=CreateEvent(NULL,FALSE,FALSE, 
    “WatchEvent”); 
    //創(chuàng)建一個(gè)事件監(jiān)視線程來監(jiān)視串口事件 
     AfxBeginThread(CommWatchProc,pParam);  

     

    在設(shè)置串口DCB結(jié)構(gòu)的參數(shù)時(shí),不必設(shè)置每一個(gè)值。首先讀出DCB缺省的參數(shù)設(shè)
    置,然后只修改必要的參數(shù),其他參數(shù)都取缺省值。由于對(duì)串口進(jìn)行的是同步I/O操作
    ,所以除非指定進(jìn)行監(jiān)測(cè)的事件發(fā)生,否則WaitCommEvent函數(shù)不會(huì)返回。在串行設(shè)備
    初始化的最后要建立一個(gè)單獨(dú)的監(jiān)視線程來監(jiān)視串口事件,以免掛起當(dāng)前調(diào)用線程,其
    中pParam可以是一個(gè)對(duì)事件進(jìn)行處理的窗口類指針。 
    如果要進(jìn)行異步I/O操作,打開設(shè)備句柄時(shí),CreateFile的第6個(gè)參數(shù)應(yīng)增加FILEFLAG
    OVERLAPPED 標(biāo)志。 
    數(shù)據(jù)發(fā)送 
            數(shù)據(jù)發(fā)送利用WriteFile函數(shù)實(shí)現(xiàn)。對(duì)于同步I/O操作,它的最后一個(gè)參數(shù)可為
    NULL;而對(duì)異步I/O操作,它的最后一個(gè)參數(shù)必需是一個(gè)指向OVERLAPPED結(jié)構(gòu)的指針,
    通過OVERLAPPED結(jié)構(gòu)來獲得當(dāng)前的操作狀態(tài)。 
    BOOL WriteComm(LPCVOID lpSndBuffer,DWORD  
    dwBytesToWrite) 
    { //lpSndBuffer為發(fā)送數(shù)據(jù)緩沖區(qū)指針, 
    dwBytesToWrite為將要發(fā)送的字節(jié)長度 
    //設(shè)備已打開 
     BOOL bWriteState;  
    //實(shí)際發(fā)送的字節(jié)數(shù) 
     DWORD dwBytesWritten;  
    //設(shè)備未打開 
     if(!bOpen) return FALSE;  
     bWriteState=WriteFile(hComDev,lpSndBuffer, 
    dwBytesToWrite,&dwBytesWritten,NULL); 
     if(!bWriteState || dwBytesToWrite!=dwBytesWritten) 
    //發(fā)送失敗 
      return FALSE;  
     else 
    //發(fā)送成功 
      return TRUE;  

    數(shù)據(jù)接收 
        接收數(shù)據(jù)的任務(wù)由ReadFile函數(shù)完成。該函數(shù)從串口接收緩沖區(qū)中讀取數(shù)據(jù),
    讀取數(shù)據(jù)前,先用ClearCommError函數(shù)獲得接收緩沖區(qū)中的字節(jié)數(shù)。接收數(shù)據(jù)時(shí),同步
    和異步讀取的差別同發(fā)送數(shù)據(jù)是一樣的。 
    DWORD ReadComm(LPVOID lpInBuffer,DWORD  
    dwBytesToRead) 
    { //lpInBuffer為接收數(shù)據(jù)的緩沖區(qū)指針, dwBytesToRead為準(zhǔn)備讀取的數(shù)據(jù)長度(字
    節(jié)數(shù)) 
    //串行設(shè)備狀態(tài)結(jié)構(gòu) 
     COMSTAT ComStat;  
     DWORD dwBytesRead,dwErrorFlags;  
    //設(shè)備未打開 
     if(!bOpen) return 0; 
     //讀取串行設(shè)備的當(dāng)前狀態(tài) 
     ClearCommError(hComDev,&dwErrorFlags,&ComStat);  
     //應(yīng)該讀取的數(shù)據(jù)長度 
    dwBytesRead=min(dwBytesToRead,ComStat.cbInQue);  
     if(dwBytesRead>0) 
      //讀取數(shù)據(jù) 
      if(!ReadFile(hComDev,lpInBuffer,dwBytesRead,&dwBytesRead,NULL))  
       dwBytesRead=0; 
     return dwBytesRead; 

    事件監(jiān)視線程 
        事件監(jiān)視線程對(duì)串口事件進(jìn)行監(jiān)視,當(dāng)監(jiān)視的事件發(fā)生時(shí),監(jiān)視線程可將這個(gè)
    事件發(fā)送(SendMessage)或登記(PostMessage)到對(duì)事件進(jìn)行處理的窗口類(由pParam指
    定)中。 
    UINT CommWatchProc(LPVOID pParam) 
    { DWORD dwEventMask=0; //發(fā)生的事件; 
     while(bOpen) 
     { //等待監(jiān)視的事件發(fā)生 
    WaitCommEvent(hComDev, &dwEventMask,  
    NULL);  
     if ((dwEventMask & EVRXCHAR) ==  
    EVRXCHAR) 
    ……//接收到字符事件后,可以將此消息登記到由pParam有指定的窗口類中進(jìn)行處理 
      if(dwEventMask & EVERR)==EVERROR) 
       ……//發(fā)生錯(cuò)誤時(shí)的處理 
     } 
     SetEvent(hEvent);  
     //發(fā)信號(hào),指示監(jiān)視線程結(jié)束 
     return 0; 

     


    關(guān)閉串行設(shè)備 
        在整個(gè)應(yīng)用程序結(jié)束或不再使用串行設(shè)備時(shí),應(yīng)將串行設(shè)備關(guān)閉,包括取消事
    件監(jiān)視,將設(shè)備打開標(biāo)志bOpen置為FALSE以使事件監(jiān)視線程結(jié)束,清除發(fā)送/接收緩沖
    區(qū)和關(guān)閉設(shè)備句柄。 
    void CloseSynComm() 
    {  
    if(!bOpen) return; 
    //結(jié)束事件監(jiān)視線程 
     bOpen=FALSE;  
     SetCommMask(hComDev,0);  
     //取消事件監(jiān)視,此時(shí)監(jiān)視線程中的WaitCommEvent將返回 
     WaitForSingleObject(hEvent,INFINITE); 
     //等待監(jiān)視線程結(jié)束 
     CloseHandle(hEvent); //關(guān)閉事件句柄 
     //停止發(fā)送和接收數(shù)據(jù),并清除發(fā)送和接收緩沖區(qū) 
    PurgeComm(hComDev,PURGETXABORT| 
    PURGERXABORT|PURGETXCLEAR| 
    PURGERXCLEAR); 
    //關(guān)閉設(shè)備句柄 
     CloseHandle(hComDev);  

    小 結(jié) 
        以上給出了用Win32 API 設(shè)計(jì)串行通信的基本思路,對(duì)這個(gè)同步I/O操作的串
    行通信程序稍加改造就可進(jìn)行異步I/O操作。在實(shí)際應(yīng)用中,我們可以將這些串行通信
    函數(shù)和成員變量加到一個(gè)已有的CWnd類或其派生類中來實(shí)現(xiàn)串行通信,也可設(shè)計(jì)一個(gè)新
    的串行通信類來包含這些成員函數(shù)和成員變量。總之,利用Win32 API可以設(shè)計(jì)出滿足
    各種需要的串行通信程序。
     

     

    (審核編輯: 智匯小新)

    聲明:除特別說明之外,新聞內(nèi)容及圖片均來自網(wǎng)絡(luò)及各大主流媒體。版權(quán)歸原作者所有。如認(rèn)為內(nèi)容侵權(quán),請(qǐng)聯(lián)系我們刪除。

    主站蜘蛛池模板: 浙江德威不锈钢管业股份有限公司 | 气体泄漏检测仪,COD水质分析仪,RD8200管线探测仪-成都恒通兴业科技有限责任公司 | 小程序定制,小程序开发,北京小程序公司,网站建设,网站制作,北京网站建设,北京网站制作 | 中国焊接协会网站—中国焊接信息网;焊接行业最权威访问量最大的专业网站:焊接信息、焊接材料,焊接机器,焊接设备,焊机,焊材,辅助设备,焊机配件,仪器仪表,电动工具,钎焊,送丝机,表面处理,自动化专机,焊锡丝,助焊剂 | 徐州护栏,围栏,锌铁丝网围栏安全设施专家徐州铜山区威峰金属护栏厂 | 景德镇古窑民俗博览区-国家AAAAA级旅游景区_全国旅游标准化示范景区_国家文化产业示范基地_国家级非物质文化遗产生产性保护示范基地--官方网站 | 锦州龙威机械有限公司官网 ,锦州医药包装机,包装机,锦州包装机械,小袋颗粒装盒生产线,颗粒装盒生产线,软双铝装盒线,伺服颗粒 | 免费建站_自助建站_网站建设_企业建站_中小企业建网站_免费网站模板-牵牛建站 | 压力变送器,差压变送器,液位变送器,温度变送器生产厂家价格-西安仕乐克仪表科技有限公司 | 空气能热水器|空气能热水器工程|太阳能热水器工程|蓝冠机电 | 河北太尚园林-太尚雕塑厂家_石雕_不锈钢雕塑厂家_铸铜雕塑_雕塑设计定制 | 售后服务认证-五星级物业售后服务体系认证证书-ISO27001信息安全管理体系认证证书查询认E云-湖北省贯标企业管理咨询有限公司 | 企业信息安全整体解决方案提供商-上海华垸信息技术有限公司 | 破碎机锤头-耐磨锤头-合金锤头-河南磐石耐磨材料有限公司 | 西安宣传片拍摄,陕西艺景网络科技有限公司资料备份,西安影视公司,视频拍摄制作,抖音视频制作,纪录片拍摄西安短视频摄影团队,西安抖音视频拍摄 | 上海源科生物技术有限公司| 品牌策划-品牌设计-济南之式传媒广告有限公司官网-提供品牌整合丨影视创意丨公关活动丨数字营销丨自媒体运营丨数字营销 | 西安测试仪-西安电压测试仪-西安电流测试仪-西安热油汽水测试仪-西安阻抗测试仪-西安时间速度测试仪-西安电力设备厂家-西安中洲电力设备有限公司 | 两面针(江苏)实业有限公司-原两面针(扬州)酒店用品有限公司 | 宁波公司注册_宁波注册公司_宁波代理记账_宁波做内账|安隆会计专业服务机构 | 注塑加工,无锡塑料件加工,注塑模具加工厂家-无锡富立康精密模塑有限公司 | 一站式应用与数据集成平台(iPaaS) - 数环通 | 钱眼网-透过钱眼看商机 | 螺旋钢管厂家,临沂瑞源工贸有限公司| 制砂机_鹅卵石制砂机_河卵石制砂机_制砂机价格-上海山卓重工机械有限公司 | 西克制冷官网│制冷机组冷风机冷库设备厂家-西克制冷(无锡)有限公司_西克制冷(无锡)有限公司 | 微型电磁阀_隔膜泵_活塞泵_微型水泵_微型真空泵_微型气泵【东莞市宗旨电子科技有限公司】 | 宁波雷豹机电科技有限公司|雷豹冷风机|雷豹工业大风扇|MFC18000|MFC16000|MFC6000|EF3622|EF4222|EF4822|移动工业蒸发式冷风机空气冷却器|大型工业空调扇|雷豹移动式工业大风扇|雷豹大风扇|生产厂家|公司官网 | 组合式空调机组-吊顶式新风换气机-消防高温排烟风机-德州宏楚空调设备有限公司 | 河北省金融租赁有限公司官网 | 有机肥设备|有机肥生产线|有机肥料生产设备|河南通达重工科技有限公司 | 皮带输送机(输送机械)-带式输送机-皮带输送机生产厂家-河南坤威机械 | 柔性防水套管_刚性防水套管-河南恒生管道制造有限公司 | 钻床,数控钻床,摇臂钻床,立式钻床_滕州市高地机床有限公司 | 永康风水大师选风水先生老徐 - 徐根法 | 西安宣传片拍摄,陕西艺景网络科技有限公司资料备份,西安影视公司,视频拍摄制作,抖音视频制作,纪录片拍摄西安短视频摄影团队,西安抖音视频拍摄 | 中山电子控制板|中山工业控制板|中山市云禾电子科技有限公司 | 兰州职业学校-新华互联网学校咨询平台中心 | 英格索兰空压机_英格索兰空压机配件_英格索兰空压机维修—商天机械 | 铸造厂_铸造厂家_硅溶胶熔模铸造-盐城市春秋精密机械有限公司 | 酒博会丨京酒展丨北京国际酒业博览会|