久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3733|回復: 0
打印 上一主題 下一主題
收起左側

CSerialPort的WriteToPort 連續發送的問題分析

[復制鏈接]
跳轉到指定樓層
樓主
ID:60266 發表于 2014-8-18 02:05 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
Gilbert在串口通信中使用CSerialPort時,發現連續發送有問題,比如,連續發了三個數組:

m_serial.WriteToPort(chSend1);
m_serial.WriteToPort(chSend2);
m_serial.WriteToPort(chSend2);
//chSend1,chSend2,chSend3是數組首地址.

只有最后一個數組發送成功,開始以為這個類不能連續發送數據,但是后來發現如果寫成這個樣子:

m_serial.WriteToPort(chSend1);
AfxMessageBox("");
m_serial.WriteToPort(chSend2);
AfxMessageBox("");
m_serial.WriteToPort(chSend3);
AfxMessageBox("");

三個數組的數據就都能發出去,這是為什么呢?

=========================================
這個要看CSerialPort是怎么做出來的,也就是從Windows的串口編程說起。在Win32下,可以使用兩種編程方式實現串口通信,其一是使用ActiveX控件,這種方法程序簡單,但是控件只能在對話框中使用。其二是調用Windows的API函數,這種方法可以清楚地掌握串口通信的機制,并且自由靈活。CSerialPort類就是對串口的API函數封裝。

與以往DOS下串行通信程序不同的是,Windows不提倡應用程序直接控制硬件,而是通過Windows操作系統提供的設備驅動程序來進行數據傳遞。串行口在Win 32中是作為文件來進行處理的,而不是直接對端口進行操作,對于串行通信,Win 32 提供了相應的文件I/O函數與通信函數,通過了解這些函數的使用,可以編制出符合不同需要的通信程序。

由于是作為文件來處理,我們看看windows API中打開串口的函數:
HANDLE CreateFile( LPCTSTR lpFileName, //將要打開的串口邏輯名,如“COM1”;
DWORD dwDesiredAccess, //指定串口訪問的類型,可以是讀取、寫入或二者并列;
DWORD dwShareMode, //指定共享屬性,由于串口不能共享,該參數必須置為0;
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //引用安全性屬性結構,缺省值為NULL;
DWORD dwCreationDistribution, //創建標志,對串口操作該參數必須置為OPEN_EXISTING;
DWORD dwFlagsAndAttributes, //屬性描述,用于指定該串口進行異步或同步操作;
HANDLE hTemplateFile); //對串口而言該參數必須置為NULL;

=========================================
請務必注意倒數第二個參數dwFlagsAndAttributes,它指示了串口進行異步或同步操作。還請注意這里的同步和異步不是指的數據通信里時鐘的同步和異步。這里的同步和異步指的是:

同步操作時,API函數會阻塞直到操作完成以后才能返回(在多線程方式中,雖然不會阻塞主線程,但是仍然會阻塞監聽線程);而異步(重疊)操作方式,API函數會立即返回,操作在后臺進行,避免線程的阻塞。

dwFlagsAndAttributes該值為FILE_FLAG_OVERLAPPED,表示使用異步的I/O;該值為0,表示同步I/O操作。

既然CSerialPort類是對API函數的封裝,我們有理由相信在它的實現里面必定有CreateFile函數,打開它的cpp來看,果然可以搜索的到,再看看它是怎么設置的:

m_hComm = CreateFile(szPort,       // communication port string (COMX)
GENERIC_READ | GENERIC_WRITE,    // read/write types
0,                                // comm devices must be opened with exclusive access
NULL,                            // no security attributes
OPEN_EXISTING,                    // comm devices must use OPEN_EXISTING
FILE_FLAG_OVERLAPPED,      // Async I/O
0);                            // template must be 0 for comm devices

可以看到倒數第二個參數設為FILE_FLAG_OVERLAPPED,即異步發送。

=========================================
其實問題就在這里,異步發送的話就造成文章一開始說的兩個現象。

先說第一個現象:為什么三個數組中只發送了最后一個數組?
因為采用了異步操作,在執行到m_serial.WriteToPort(chSend1); 時,并不馬上發送串口數據,而是要等進入CSerialPort的線程之后再發送(如果是同步操作,則程序停在那里等發送完成)。
你可以跟蹤一下程序,看是什么時候進入它的線程的,三句WriteToPort都會進入這一個線程,而不是三個線程,在這個線程中只發送一次數據,數據的來源就是形參最后的更新,所以就是第三個數組了。

第二個現象:為什么加了AfxMessageBox(""); 就都可以發送?
因為AfxMessageBox(""); 使程序的進程被掛起,這樣CSerialPort的線程就得以運行,所以就發送了。

=========================================
看到這里你可能會想:那能不能將dwFlagsAndAttributes改成0設為同步發送?
答案是好像不可以,可能還需要改其他地方,光這里改成同步的話,串口什么數據也發不了。
如果你發現能簡易的將這個類改成同步的方法,歡迎聯系我gilbertjuly@gmail.com

=========================================
那我們要同步發送怎么辦?
1.將chSend1,chSend2,chSend3放在一起組建成一個更大的數組一次發送
這樣如果接收端處理串口數據較慢的話,可能要在每個數組當中插入些無用的數據。
2.使用其他具有同步操作功能的類


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品久久久久婷婷二区次 | 欧美极品一区二区 | 精品国产欧美 | 欧美成人激情 | 精品免费视频 | 九九精品视频在线 | 日本欧美黄色片 | 亚洲精品一区二区三区丝袜 | 亚洲 欧美 另类 综合 偷拍 | 91麻豆精品国产91久久久更新资源速度超快 | 日日av | 一区二区三区欧美 | 精品伦精品一区二区三区视频 | 国产一区久久 | 久久只有精品 | 99热这里有精品 | 一级aaaaaa毛片免费同男同女 | 国产福利在线小视频 | 亚洲精品视频观看 | 久久久激情| 亚洲精品乱码久久久久久蜜桃 | 国产精品久久国产精品久久 | 成人影院在线观看 | 91久久精品一区二区二区 | 亚洲精品乱码久久久久久按摩 | 精品丝袜在线 | 色在线免费| 成人在线视频免费看 | 在线免费观看黄色av | 亚洲免费网站 | 一级免费毛片 | 欧美亚洲视频在线观看 | 国产麻豆乱码精品一区二区三区 | 黄色大片免费播放 | 欧美 日韩 中文 | 免费av观看 | 国产成人综合久久 | 一区二区三区视频在线观看 | 日日夜夜狠狠操 | 免费在线看黄 | 日本免费一区二区三区 |