㈠ 是用Visual c++開發串口通信程序還是用C++開發串口通信程序
VC++包含windows的API
可以很方便調用win驅動 訪問串口
所以 用VC多一些
其實 用C或者C++都可以 是否使用VC作為IDE一樣不重要
不管是什麼IDE 用什麼語言 ,都可以開發串口的。
㈡ 用vc++實現usb介面通信編程的一般步驟
我來說下我做過的USB通信,我沒有做過DSP跟上位機的通信,我只做過ARM類的STM32跟上位機的數據傳遞,雖然做過但是也不是很 懂,只是略知一二,我來說說我怎麼做的吧,我是這么實現的:
USB是個很復雜的協議,你如果完全搞懂,我估計沒有幾個月專心鑽研是不行的,但是如果只是能實現你的這個功能,我估計不是很復雜。
首先來說說USB通信:
USB通信傳輸方式分為四種:控制,中斷,批量,同步傳輸四種,這個你可以看看網上資料,然後我用STM32通信,因為數據量不是很大,我用的是中斷傳輸方式,但是DSP數據量應該會比較大,不知道中斷傳輸行不行,但是一般問題不大。
傳輸方式說完了,再說說USB設備類型,你每次插usb設備到電腦上的時候就會有提示,這是一個什麼設備,USB設備類型就是說的這個意思,是滑鼠還是鍵盤還是別的什麼的,如果你選用標準的類,你就不用自己寫上位機(PC)的驅動程序,但是如果不用標準的類,就是用自定義的類就要自己寫上層的設備驅動程序,就是所謂的DDK,WDM,WDF什麼的,你沒寫過這方面的還真有點棘手,但是也不一定要寫驅動程序,你可以試試有個類叫HID類,這個類在USB通信的時候用的還挺多的,不過這個類也有缺點,這個地方還要說一點,USB還分低速,全速,高速三種,不太了解DSP,不知道他支持什麼模式,但是USB2.0的全速應該至少可以支持的。
USB2.0全速模式HID用中斷方式每秒最多可以傳輸64KB的數據,不知道能不能達到你的要求,但是我估計一般問題不大了,如果你這歀DSP能支持高速模式,每秒用這種方式可以傳輸高達22MB的數據,這個速度一般問題不大了。
你可以照著我說的思路,去網上搜搜人家寫好的程序,肯定有人做過DSP的USB通信,然後你按照自己的要求改一改,主要應該是USB的設備描述符部分要自己修改,然後可能還要根據自己的電路改改配置什麼的,上位機軟體網上有源代碼的多的是,然後自己摸索摸索,我估計你要是編程水平還可以的話,只是摸索USB,一兩個星期完全沒有問題,祝你好運!
㈢ visual c++ 串口編程 初學,求救
給你點代碼
void Com::init_com_interface()
{
hcom = CreateFile("COM1", // 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
0, // Async I/O
NULL); // template must be 0 for comm devices
DCB dcb;
COMMTIMEOUTS tout;
GetCommState(hcom,&dcb);
dcb.BaudRate = 115200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
SetCommState(hcom,&dcb);
tout.ReadTotalTimeoutConstant = 0;
tout.WriteTotalTimeoutConstant = 0;
tout.WriteTotalTimeoutMultiplier = 0;
tout.ReadTotalTimeoutMultiplier = 0;
tout.ReadIntervalTimeout = -1;
SetCommTimeouts(hcom,&tout);
//DWORD len;
//if (!ReadFile(hcom,rxbuf,200,&len,NULL))
//{
// return FALSE;
//}
//else return TRUE;
}
以上是串口初始化代碼
以下是發送字元串代碼
void Com::SendCommand(CString str)
{
CString m_vHexshow="";
//mm[1]=100;
// m_vStaticFasong=str;
// m_vEditJieshou="";
// UpdateData(FALSE);
str.MakeLower();
int m=0,n=0,mn=0;
for(int i=0;i<str.GetLength();i+=3)
{
m=(str[i]<58)?(str[i]-48):(str[i]-87);
n=(str[i+1]<58)?(str[i+1]-48):(str[i+1]-87);
mn=m*16+n;
//if(mn==239)
//
m_vHexshow+= char(mn);
}
//
//if (m_vHexshow[0]==-17)
memcpy(txbuf,m_vHexshow,m_vHexshow.GetLength());
//if (txbuf[0]==239)
DWORD len;
if (!WriteFile(hcom,txbuf,m_vHexshow.GetLength(),&len,NULL))
{
}
}
㈣ 用visual c 6.0實現串口數據收發及採集數據的波形顯示
給現金差不多。否則沒人會幫你做。
如果讓我來,我會用Labview做。一個小時就做好。初學者1星期搞定。
建議使用Labview吧,電驢上有的是下載。
㈤ c++ 編寫串口通信程序
c++ 編寫串口通信程序
推薦 看書
Visual C++_Turbo C串口通信編程實踐
㈥ Visual C++串口通信技術詳解的目錄
前言
第一篇 基礎理論和基本方法
第1章 串口通信理論基礎
1.1 介面技術
1.1.1 介面的定義
1.1.2 介面的基本功能
1.1.3 介面的基本控制方式
1.1.4 並行介面技術
1.1.5 串列介面技術
1.2 RS-232C標准
1.2.1 RS-232C電氣特性
1.2.2 RS-232C連接器機械特性
1.2.3 RS-232C的介面信號
1.2.4 RS-232C的通信方式
1.3 RS-422/RS-485標准
1.3.1 RS-422簡介
1.3.2 RS-485簡介
1.3.3 RS-422/RS-485網路安裝注意點
1.4 SPI匯流排標准
1.4.1 SPI匯流排原理
1.4.2 SPI匯流排特點
1.5 USB匯流排標准
1.5.1 USB匯流排總體結構
1.5.2 USB數據傳輸邏輯結構
1.5.3 傳輸類型
1.6 使用串口通信的典型外設
1.6.1 Modem
1.6.2 傳真機
1.6.3 GPS接收機
1.7 實踐拓展
第2章 Visual C++集成開發環境簡介
2.1 面向對象程序設計與C++語言
2.1.1 面向對象程序設計概述
2.1.2 C++語言基礎
2.1.3 C++的面向對象特性
2.2 Visual C++6.0集成開發環境
2.2.1 visual C++6.0開發環境
2.2.2 項目與項目工作區
2.2.3 應用程序向導App Wizard
2.2.4 集成開發基本操作
2.2.5 聯機幫助文件
2.3 MFC應用程序的創建
2.4 實踐拓展
第3章 MSComm控制項串口編程
3.1 MSComm控制項簡介
3.1.1 MSComm控制項描述
3.1.2 MsComm控制項常用屬性
3.1.3 MSComm控制項其他屬性
3.1.4 MSComm控制項的事件
3.2 MSComm控制項編程步驟
3.2.1 載入MSComm控制項到項目
3.2.2 初始化並打開串列埠
3.2.3 捕獲串列埠事件
3.2.4 串列埠數據讀寫
3.2.5 關閉串列埠
3.2.6 程序發布問題
3.3 使用MsComm控制項實現串口通信接收
3.4 實踐拓展
第4章 Windows API串口編程
4.1 windows API串列編程概述
4.1.1 串列編程的數據結構
4.1.2 串列編程的Win32API函數
4.2 win32 API串口通信編程方式
4.2.1 打開串列埠
4.2.2 配置串列埠
4.2.3 讀寫串列埠
4.2.4 關閉串列埠
4.3 基於win32API函數實現串口通信發送程序
4.4 實踐拓展
第5章 TAPI串口編程
5.1 TAPI概述
5.1.1 TAPI的含義
5.1.2 TAPI的體系結構
5.1.3 TAPI的服務類型
5.2 windows TAPI 2.x函數集
5.2.1 Windows TAPI編程流程
5.2.2 TAPI 2.x常用函數
5.3 使用TAPI實現電話撥打程序
5.4 實踐拓展
第二篇 串口編程基礎應用
第6章 串口實現雙機互連
6.1 概述
6.2 通信協議及實現方案
6.2.1 非同步串列通信
6.2.2 同步串列通信
6.3 實現代碼分析
6.3.1 程序主體設計及關鍵模塊分析
6.3.2 使用API通信
6.4 實踐拓展
第7章 串口調試精靈
7.1 串口調試工具實現的基本要求
7.2 串口調試精靈的編程實現
7.2.1 軟體功能及流程設計
7.2.2 程序界面分析
7.2.3 編程實現
7.2.4 使用測試
7.3 實踐拓展
第8章 串口控制Modem設備
8.1 Modem介面
8.1.1 Modem簡介
8.1.2 Modem工作流程
8.1.3 Modem通信方案
8.2 AT指令簡介
8.2.1 Modem工作狀態
8.2.2 AT指令集
8.3 使用Modem實現遠程通信
8.3.1 使用單片機和Modem通信
8.3.2 使用PC和Modem通信
8.4 實踐拓展
第9章 串口控制單片機
9.1 串口通信硬體設計
9.1.1 MCS.5 1系列單片機的串口原理
9.1.2 常用的介面晶元介紹
9.1.3 介面電路設計
9.2 串口通信參數設置
9.2.1 波特率設置
9.2.2 奇偶校驗位的使用方法
9.2.3 通信協議約定
9.3 系統總體設計
9.4 單片機的串口編程方法
9.5 計算機端通信界面設計
9.6 計算機端程序設計
9.6.1 頭文件引用及變數聲明
9.6.2 控制項載入及控制項屬性設置
9.6.3 發出讀數據請求
9.6.4 接收數據的處理
9.6.5 關閉串口
9.7 實踐拓展
第10章 串口控制PLC
10.1 PLC概述
10.1.1 PLC基本結構
10.1.2 PLC串列介面規范
10.1.3 通信協議
10.2 PLC串口通信
10.2.1 計算機與PLC之間的通信流程
10.2.2 PLC通信編程
10.3 實現代碼分析
10.3.1 界面設計
10.3.2 程序設計核心代碼
10.4 實踐拓展
第11章 串口控制射頻卡
11.1 射頻卡概述
11.1.1 射頻卡原理
11.1.2 射頻卡分類及應用
11.1.3 典型射頻卡模塊
11.2 射頻卡應用設計
11.2.1 讀寫器設計
11.2.2 基於射頻卡模塊的設計
11.3 實現代碼分析
11.3.1 界面設計
11.3.2 串口通信程序設計
11.4 實踐拓展
第12章 串口控制GPS模塊
12.1 GPS系統的基礎知識
12.1.1 GPS定位原理
12.1.2 GPS系統
12.2 LEA-4H型GPS模塊的性能及其應用
12.3 NMEA-0183協議分析
12.3.1 NMEA-0183協議的定義
12.3.2 NMEA-0183數據信息
12.4 主機與GPS模塊串口通信的程序實現
12.4.1 MSComm控制項屬性
12.4.2 添加MSComm控制項
12.4.3 添加串口事件消息處理函數OnComm()
12.4.4 數據的接收與提取
12.4.5 實驗結果及數據的顯示
12.5 實踐拓展
第三篇 串口編程高級應用
第13章 串口控制雲台攝像頭
13.1 雲台攝像頭
13.1.1 雲台簡介
13.1.2 攝像頭及控制電路
13.2 雲台控制協議
13.3 控製程序分析
13.3.1 添加控制項
13.3.2 設置界面
13.3.3 主控程序
13.3.4 初始化
13.3.5 配置按鈕
13.3.6 通信參數的設置
13.3.7 雲台控制命令
13.3.8 旋轉控制按鈕和鏡頭控制按鈕
13.4 實踐拓展
第14章 智能報警系統
14.1 系統描述
14.2 系統分析與設計
14.3 關鍵技術
14.3.1 建立安防信息資料庫
14.3.2 埠設置和定時讀取I/O埠數據
14.3.3 判斷是否有觸發事件
14.3.4 啟動並口控制的報警設備
14.3.5 根據設置撥打報警電話
14.3.6 安防日誌管理
14.3.7 I/O埠通信
14.4 實現代碼分析
14.4.1 創建項目
14.4.2 界面設計與實現
14.4.3 加入資料庫支持
14.4.4 關鍵程序類的實現
14.5 實踐拓展
第15章 語音自動應答系統
15.1 功能描述
15.1.1 TAPI介紹
15.1.2 功能介紹
15.1.3 實驗要求
15.2 設計流程實現
15.2.1 程序設計流程圖
15.2.2 TAPI 3.0方法介紹
15.2.3 串處理分析介紹
15.3 具體功能實現
15.3.1 程序主界面
15.3.2 參數配置
15.3.3 選擇語音界面
15.4 實踐拓展
第16章 USB轉RS-232串口實例
16.1 USB匯流排技術簡介
16.1.1 USB的特點
16.1.2 USB的體系結構
16.1.3 USB的電氣特性
16.1.4 USB的數據通信協議
16.2 功能描述
16.3 USB匯流排轉換晶元CH341簡介
16.3.1 CH341非同步串口工作方式
16.3.2 CH341功能配置
16.4 USB轉RS-232橋接器硬體設計
16.5 驅動程序安裝
16.6 實踐拓展
附錄 Modem AT命令集
參考文獻
㈦ VC串口通信問題
串口的操作可以有兩種操作方式:同步操作方式和重疊操作方式(又稱為非同步操作方式)。同步操作時,API函數會阻塞直到操作完成以後才能返回(在多線程方式中,雖然不會阻塞主線程,但是仍然會阻塞監聽線程);而重疊操作方式,API函數會立即返回,操作在後台進行,避免線程的阻塞。
無論那種操作方式,一般都通過四個步驟來完成:
(1) 打開串口
(2) 配置串口
(3) 讀寫串口
(4) 關閉串口
(1) 打開串口
Win32系統把文件的概念進行了擴展。無論是文件、通信設備、命名管道、郵件槽、磁碟、還是控制台,都是用API函數CreateFile來打開或創建的。該函數的原型為:
lpFileName:將要打開的串口邏輯名,如「COM1」;
dwDesiredAccess:指定串口訪問的類型,可以是讀取、寫入或二者並列;
dwShareMode:指定共享屬性,由於串口不能共享,該參數必須置為0;
lpSecurityAttributes:引用安全性屬性結構,預設值為NULL;
dwCreationDistribution:創建標志,對串口操作該參數必須置為OPEN_EXISTING;
dwFlagsAndAttributes:屬性描述,用於指定該串口是否進行非同步操作,該值為FILE_FLAG_OVERLAPPED,表示使用非同步的I/O;該值為0,表示同步I/O操作;
hTemplateFile:對串口而言該參數必須置為NULL;
同步I/O方式打開串口的示例代碼:
HANDLE hCom; //全局變數,串口句柄
hCom=CreateFile("COM1",//COM1口
GENERIC_READ|GENERIC_WRITE, //允許讀和寫
0, //獨占方式
NULL,
OPEN_EXISTING, //打開而不是創建
0, //同步方式
NULL);
if(hCom==(HANDLE)-1)
{
AfxMessageBox("打開COM失敗!");
return FALSE;
}
return TRUE;
(2)、配置串口
在打開通訊設備句柄後,常常需要對串口進行一些初始化配置工作。這需要通過一個DCB結構來進行。DCB結構包含了諸如波特率、數據位數、奇偶校驗和停止位數等信息。在查詢或配置串口的屬性時,都要用DCB結構來作為緩沖區。
一般用CreateFile打開串口後,可以調用GetCommState函數來獲取串口的初始配置。要修改串口的配置,應該先修改DCB結構,然後再調用SetCommState函數設置串口。
typedef struct _DCB{
………
//波特率,指定通信設備的傳輸速率。這個成員可以是實際波特率值或者下面的常量值之一:
DWORD BaudRate;
CBR_110,CBR_300,CBR_600,CBR_1200,CBR_2400,CBR_4800,CBR_9600,CBR_19200, CBR_38400,
CBR_56000, CBR_57600, CBR_115200, CBR_128000, CBR_256000, CBR_14400
DWORD fParity; // 指定奇偶校驗使能。若此成員為1,允許奇偶校驗檢查
…
BYTE ByteSize; // 通信位元組位數,4—8
BYTE Parity; //指定奇偶校驗方法。此成員可以有下列值:
EVENPARITY 偶校驗 NOPARITY 無校驗
MARKPARITY 標記校驗 ODDPARITY 奇校驗
BYTE StopBits; //指定停止位的位數。此成員可以有下列值:
ONESTOPBIT 1位停止位 TWOSTOPBITS 2位停止位
ONE5STOPBITS 1.5位停止位
………
} DCB;
winbase.h文件中定義了以上用到的常量。如下:
#define NOPARITY 0
#define ODDPARITY 1
#define EVENPARITY 2
#define ONESTOPBIT 0
#define ONE5STOPBITS 1
#define TWOSTOPBITS 2
#define CBR_110 110
#define CBR_300 300
#define CBR_600 600
#define CBR_1200 1200
#define CBR_2400 2400
#define CBR_4800 4800
#define CBR_9600 9600
#define CBR_14400 14400
#define CBR_19200 19200
#define CBR_38400 38400
#define CBR_56000 56000
#define CBR_57600 57600
#define CBR_115200 115200
#define CBR_128000 128000
#define CBR_256000 256000
GetCommState函數可以獲得COM口的設備控制塊,從而獲得相關參數: BOOL GetCommState(
HANDLE hFile, //標識通訊埠的句柄
LPDCB lpDCB //指向一個設備控制塊(DCB結構)的指針
);
SetCommState函數設置COM口的設備控制塊:
BOOL SetCommState(
HANDLE hFile,
LPDCB lpDCB
);
除了在BCD中的設置外,程序一般還需要設置I/O緩沖區的大小和超時。Windows用I/O緩沖區來暫存串口輸入和輸出的數據。如果通信的速率較高,則應該設置較大的緩沖區。調用SetupComm函數可以設置串列口的輸入和輸出緩沖區的大小。 BOOL SetupComm(
HANDLE hFile, // 通信設備的句柄
DWORD dwInQueue, // 輸入緩沖區的大小(位元組數)
DWORD dwOutQueue // 輸出緩沖區的大小(位元組數)
);
在用ReadFile和WriteFile讀寫串列口時,需要考慮超時問題。超時的作用是在指定的時間內沒有讀入或發送指定數量的字元,ReadFile或WriteFile的操作仍然會結束。
要查詢當前的超時設置應調用GetCommTimeouts函數,該函數會填充一個COMMTIMEOUTS結構。調用SetCommTimeouts可以用某一個COMMTIMEOUTS結構的內容來設置超時。
讀寫串口的超時有兩種:間隔超時和總超時。間隔超時是指在接收時兩個字元之間的最大時延。總超時是指讀寫操作總共花費的最大時間。寫操作只支持總超時,而讀操作兩種超時均支持。用COMMTIMEOUTS結構可以規定讀寫操作的超時。
COMMTIMEOUTS結構的定義為: typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout; //讀間隔超時
DWORD ReadTotalTimeoutMultiplier; //讀時間系數
DWORD ReadTotalTimeoutConstant; //讀時間常量
DWORD WriteTotalTimeoutMultiplier; // 寫時間系數
DWORD WriteTotalTimeoutConstant; //寫時間常量
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
COMMTIMEOUTS結構的成員都以毫秒為單位。總超時的計算公式是:
總超時=時間系數×要求讀/寫的字元數+時間常量
例如,要讀入10個字元,那麼讀操作的總超時的計算公式為:
讀總超時=ReadTotalTimeoutMultiplier×10+ReadTotalTimeoutConstant
可以看出:間隔超時和總超時的設置是不相關的,這可以方便通信程序靈活地設置各種超時。
如果所有寫超時參數均為0,那麼就不使用寫超時。如果ReadIntervalTimeout為0,那麼就不使用讀間隔超時。如果ReadTotalTimeoutMultiplier 和 ReadTotalTimeoutConstant 都為0,則不使用讀總超時。如果讀間隔超時被設置成MAXDWORD並且讀時間系數和讀時間常量都為0,那麼在讀一次輸入緩沖區的內容後讀操作就立即返回,而不管是否讀入了要求的字元。
在用重疊方式讀寫串口時,雖然ReadFile和WriteFile在完成操作以前就可能返回,但超時仍然是起作用的。在這種情況下,超時規定的是操作的完成時間,而不是ReadFile和WriteFile的返回時間。
配置串口的示例代碼: SetupComm(hCom,1024,1024); //輸入緩沖區和輸出緩沖區的大小都是1024
COMMTIMEOUTS TimeOuts;
//設定讀超時
TimeOuts.ReadIntervalTimeout=1000;
TimeOuts.ReadTotalTimeoutMultiplier=500;
TimeOuts.ReadTotalTimeoutConstant=5000;
//設定寫超時
TimeOuts.WriteTotalTimeoutMultiplier=500;
TimeOuts.WriteTotalTimeoutConstant=2000;
SetCommTimeouts(hCom,&TimeOuts); //設置超時
DCB dcb;
GetCommState(hCom,&dcb);
dcb.BaudRate=9600; //波特率為9600
dcb.ByteSize=8; //每個位元組有8位
dcb.Parity=NOPARITY; //無奇偶校驗位
dcb.StopBits=TWOSTOPBITS; //兩個停止位
SetCommState(hCom,&dcb);
PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
在讀寫串口之前,還要用PurgeComm()函數清空緩沖區,該函數原型: BOOL PurgeComm(
HANDLE hFile, //串口句柄
DWORD dwFlags // 需要完成的操作
);
參數dwFlags指定要完成的操作,可以是下列值的組合: PURGE_TXABORT 中斷所有寫操作並立即返回,即使寫操作還沒有完成。
PURGE_RXABORT 中斷所有讀操作並立即返回,即使讀操作還沒有完成。
PURGE_TXCLEAR 清除輸出緩沖區
PURGE_RXCLEAR 清除輸入緩沖區
(3)、讀寫串口
我們使用ReadFile和WriteFile讀寫串口,下面是兩個函數的聲明:
BOOL ReadFile(
HANDLE hFile, //串口的句柄
// 讀入的數據存儲的地址,
// 即讀入的數據將存儲在以該指針的值為首地址的一片內存區
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead, // 要讀入的數據的位元組數
// 指向一個DWORD數值,該數值返回讀操作實際讀入的位元組數
LPDWORD lpNumberOfBytesRead,
// 重疊操作時,該參數指向一個OVERLAPPED結構,同步操作時,該參數為NULL。
LPOVERLAPPED lpOverlapped
);
BOOL WriteFile(
HANDLE hFile, //串口的句柄
// 寫入的數據存儲的地址,
// 即以該指針的值為首地址的nNumberOfBytesToWrite
// 個位元組的數據將要寫入串口的發送數據緩沖區。
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite, //要寫入的數據的位元組數
// 指向指向一個DWORD數值,該數值返回實際寫入的位元組數
LPDWORD lpNumberOfBytesWritten,
// 重疊操作時,該參數指向一個OVERLAPPED結構,
// 同步操作時,該參數為NULL。
LPOVERLAPPED lpOverlapped
);
在用ReadFile和WriteFile讀寫串口時,既可以同步執行,也可以重疊執行。在同步執行時,函數直到操作完成後才返回。這意味著同步執行時線程會被阻塞,從而導致效率下降。在重疊執行時,即使操作還未完成,這兩個函數也會立即返回,費時的I/O操作在後台進行。
ReadFile和WriteFile函數是同步還是非同步由CreateFile函數決定,如果在調用CreateFile創建句柄時指定了FILE_FLAG_OVERLAPPED標志,那麼調用ReadFile和WriteFile對該句柄進行的操作就應該是重疊的;如果未指定重疊標志,則讀寫操作應該是同步的。ReadFile和WriteFile函數的同步或者非同步應該和CreateFile函數相一致。
ReadFile函數只要在串口輸入緩沖區中讀入指定數量的字元,就算完成操作。而WriteFile函數不但要把指定數量的字元拷入到輸出緩沖區,而且要等這些字元從串列口送出去後才算完成操作。
如果操作成功,這兩個函數都返回TRUE。需要注意的是,當ReadFile和WriteFile返回FALSE時,不一定就是操作失敗,線程應該調用GetLastError函數分析返回的結果。例如,在重疊操作時如果操作還未完成函數就返回,那麼函數就返回FALSE,而且GetLastError函數返回ERROR_IO_PENDING。這說明重疊操作還未完成。
您可以觀察返回的字元串,其中有和儀表顯示值相同的部分,您可以進行相應的字元串操作取出儀表的顯示值。
打開ClassWizard,為靜態文本框IDC_DISP添加CString類型變數m_disp,同時添加WM_CLOSE的相應函數: void CRS485CommDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
CloseHandle(hCom); //程序退出時關閉串口
CDialog::OnClose();
}
程序的相應部分已經在代碼內部作了詳細介紹。連接好硬體部分,編譯運行程序,細心體會串口同步操作部分。
常式2
打開VC++6.0,新建基於對話框的工程RS485Comm,在主對話框窗口IDD_RS485COMM_DIALOG上添加兩個按鈕,ID分別為IDC_SEND和IDC_RECEIVE,標題分別為「發送」和「接收」;添加一個靜態文本框IDC_DISP,用於顯示串口接收到的內容。在RS485CommDlg.cpp文件中添加全局變數:
HANDLE hCom; //全局變數,
串口句柄在RS485CommDlg.cpp文件中的OnInitDialog()函數添加如下代碼:
hCom=CreateFile("COM1",//COM1口
GENERIC_READ|GENERIC_WRITE, //允許讀和寫
0, //獨占方式
NULL,
OPEN_EXISTING, //打開而不是創建
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重疊方式
NULL);
if(hCom==(HANDLE)-1)
{
AfxMessageBox("打開COM失敗!");
return FALSE;
}
SetupComm(hCom,100,100); //輸入緩沖區和輸出緩沖區的大小都是100
COMMTIMEOUTS TimeOuts;
//設定讀超時
TimeOuts.ReadIntervalTimeout=MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier=0;
TimeOuts.ReadTotalTimeoutConstant=0;
//在讀一次輸入緩沖區的內容後讀操作就立即返回,
//而不管是否讀入了要求的字元。
//設定寫超時
TimeOuts.WriteTotalTimeoutMultiplier=100;
TimeOuts.WriteTotalTimeoutConstant=500;
SetCommTimeouts(hCom,&TimeOuts); //設置超時
DCB dcb;
GetCommState(hCom,&dcb);
dcb.BaudRate=9600; //波特率為9600
dcb.ByteSize=8; //每個位元組有8位
dcb.Parity=NOPARITY; //無奇偶校驗位
dcb.StopBits=TWOSTOPBITS; //兩個停止位
SetCommState(hCom,&dcb);
PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
分別雙擊IDC_SEND按鈕和IDC_RECEIVE按鈕,添加兩個按鈕的響應函數: void CRS485CommDlg::OnSend()
{
// TODO: Add your control notification handler code here
OVERLAPPED m_osWrite;
memset(&m_osWrite,0,sizeof(OVERLAPPED));
m_osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
char lpOutBuffer[7];
memset(lpOutBuffer,''\0'',7);
lpOutBuffer[0]=''\x11'';
lpOutBuffer[1]=''0'';
lpOutBuffer[2]=''0'';
lpOutBuffer[3]=''1'';
lpOutBuffer[4]=''0'';
lpOutBuffer[5]=''1'';
lpOutBuffer[6]=''\x03'';
DWORD dwBytesWrite=7;
COMSTAT ComStat;
DWORD dwErrorFlags;
BOOL bWriteStat;
ClearCommError(hCom,&dwErrorFlags,&ComStat);
bWriteStat=WriteFile(hCom,lpOutBuffer,
dwBytesWrite,& dwBytesWrite,&m_osWrite);
if(!bWriteStat)
{
if(GetLastError()==ERROR_IO_PENDING)
{
WaitForSingleObject(m_osWrite.hEvent,1000);
}
}
}
void CRS485CommDlg::OnReceive()
{
// TODO: Add your control notification handler code here
OVERLAPPED m_osRead;
memset(&m_osRead,0,sizeof(OVERLAPPED));
m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
COMSTAT ComStat;
DWORD dwErrorFlags;
char str[100];
memset(str,''\0'',100);
DWORD dwBytesRead=100;//讀取的位元組數
BOOL bReadStat;
ClearCommError(hCom,&dwErrorFlags,&ComStat);
dwBytesRead=min(dwBytesRead, (DWORD)ComStat.cbInQue);
bReadStat=ReadFile(hCom,str,
dwBytesRead,&dwBytesRead,&m_osRead);
if(!bReadStat)
{
if(GetLastError()==ERROR_IO_PENDING)
//GetLastError()函數返回ERROR_IO_PENDING,表明串口正在進行讀操作
{
WaitForSingleObject(m_osRead.hEvent,2000);
//使用WaitForSingleObject函數等待,直到讀操作完成或延時已達到2秒鍾
//當串口讀操作進行完畢後,m_osRead的hEvent事件會變為有信號
}
}
PurgeComm(hCom, PURGE_TXABORT|
PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
m_disp=str;
UpdateData(FALSE);
}
打開ClassWizard,為靜態文本框IDC_DISP添加CString類型變數m_disp,同時添加WM_CLOSE的相應函數: void CRS485CommDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
CloseHandle(hCom); //程序退出時關閉串口
CDialog::OnClose();
}
這是我看過的一個資料。打開、設置和讀寫串口的方法都說的很詳細了。由於網路知道回答問題是有長度限制的。有些例子被我刪了。如果需要就加我QQ。給你發信息了。
㈧ 用visual C++怎樣編一個最簡單的串口程序
用VC++6.0實現PC機與單片機之間
串列通信的方法
湖南大學(長沙410082) 於小億 王 輝 張志學
摘 要 詳細介紹了在Windows環境下應用VC++實現PC機與單片機的幾種串列通信方法,給出了用Visual C++6.0編寫的PC機程序和用C51編寫的單片機通信程序。經實際應用系統運行穩定可靠。
關鍵詞 Visual C++ 類 串列通信
--------------------------------------------------------------------------------
工業控制領域(如DCS系統),經常涉及到串列通信問題。為了實現微機和單片機之間的數據交換,人們用各種不同方法實現串列通信,如DOS下採用匯編語言或C語言,但在Windows 環境下卻存在一些困難和不足。在Windows操作系統已經占據統治地位的情況下(何況有些系統根本不支持DOS如Windows2000)開發Windows 環境下串列通信技術就顯得日益重要。
VC++6.0是微軟公司於1998年推出的一種開發環境,以其強大的功能,友好的界面,32位面向對象的程序設計及Active X的靈活性而受廣大軟體開發者的青睞,被廣泛應用於各個領域。應用VC++開發串列通信目前通常有如下幾種方法:一是利用Windows API通信函數;二是利用VC的標准通信函數_inp、_inpw、_inpd、_outp、_outpw、_outpd等直接對串口進行操作;三是使用Microsoft Visual C++的通信控制項(MSComm);四是利用第三方編寫的通信類。以上幾種方法中第一種使用面較廣,但由於比較復雜,專業化程度較高,使用較困難;第二種需要了解硬體電路結構原理;第三種方法看來較簡單,只需要對串口進行簡單配置,但是由於使用令人費解的VARIANT 類,使用也不是很容易;第四種方法是利用一種用於串列通信的CSerial類(這種類是由第三方提供),只要理解這種類的幾個成員函數,就能方便的使用。筆者利用CSerial類很方便地實現了在固定式EBM氣溶膠滅火系統分區啟動器(單片機系統)與上位機的通信。以下將結合實例,給出實現串列通信的幾種方法。
1 Windows API通信函數方法
與通信有關的Windows API函數共有26個,但主要有關的有:
CreateFile() 用 「comn」(n為串口號)作為文件名就可以打開串口。
ReadFile() 讀串口。
WriteFile() 寫串口。
CloseHandle() 關閉串口句柄。初始化時應注意CreateFile()函數中串口共享方式應設為0,串口為不可共享設備,其它與一般文件讀寫類似。以下給出API實現的源代碼。
2 利用埠函數直接操作
這種方式主要是採用兩個埠函數_inp(), _outp()實現對串口的讀寫,其中讀埠函數的原型為:
int _inp(unsigned shot port)
該函數從埠讀取一個位元組,埠號為0~65535。
寫埠的函數原型為:
int _outp(unsigned shot port, int databyte)
該函數向指定埠寫入一個位元組。
不同的計算機串口地址可能不一樣,通過向串口的控制及收發寄存器進行讀寫,可以實現靈活的串口通信功能,由於涉及具體的硬體電路討論比較復雜,在此不加贅述。
3 MSComm控制項
MSComm控制項是微軟開發的專用通信控制項,封裝了串口的所有功能,使用很方便,但在實際應用中要小心對其屬性進行配置。下面詳細說明該類應用方法。
3.1 MSComm控制項的屬性
CommPort:設置串口號,類型 short :1-comm1 2-comm2.
Settings:設置串口通信參數,類型 CString :B波特率,P奇偶性(N無校驗,E偶校驗,O奇校驗),D位元組有效位數,S停止位。
PortOpen:設置或返回串口狀態,類型 BOOL:TURE打開,FALSE關閉。
InputMode:設置從接收緩沖區讀取數據的格式,類型 long: 0-Text 1-Bin。
Input:從接收緩沖區讀取數據,類型 VARIANT。
InBufferCount:接收緩沖區中的位元組數,類型:short。
InBufferSize:接收緩沖區的大小,類型:short。
Output:向發送緩沖區寫入數據,類型:VARIANT。
OutBufferCount:發送緩沖區中的位元組數,類型:short。
OutBufferSize:發送緩沖區的大小,類型:short。
InputLen:設置或返回Input讀出的位元組數,類型:short。
CommEvent:串口事件,類型:short。
3.2 程序示例
串口初始化
if (!m_comm.GetPortOpen())
m_comm.SetPortOpen(TURE); /*打開串口*/
m_comm.SetSettings( "4800,n,8,1 "); /*串口參數設置*/
m_comm.SetInputMode(0); /*設置TEXT緩沖區輸入方式*/
m_comm.SetRthresHold(1); /*每接收一個字元則激發OnComm()事件*/
接收數據
m_comm.SetInputLen(1); /*每次讀取一個字元
VARINAT V1=m_comm.GetInput();
/*讀入字元*/
m_V1=V1.bstrval;
發送字元 m_comm.SetOutput(Colevariant ( "Hello "); /*發送 「Hello」 */
3.3 注意
SetOutput方法可以傳輸文本數據或二進制數據。用SetOutput方法傳輸文本數據,必須定義一個包含一個字元串的 Variant。發送二進制數據,必須傳遞一個包含位元組數組的Variant 到 Output 屬性。正常情況下,如果發送一個 ANSI 字元串到應用程序,可以以文本數據的形式發送。如果發送包含嵌入控制字元、Null 字元等的數據,要以二進制形式發送。此處望引起讀者注意,筆者曾經在此犯錯。
4 VC++類CSerial
4.1 串列通信類CSerial簡介
Cserial 是由MuMega Technologies公司提供的一個免費的VC++類,可方便地實現串列通信。以下為該類定義的說明部分。
class CSerial
{
public:
CSerial();
~CSerial();
BOOL Open( int nPort = 2, int nBaud = 9600 );
BOOL Close( void );
int ReadData( void *, int );
int SendData( const char *, int );
int ReadDataWaiting( void );
BOOL IsOpened( void ){ return( m_bOpened ); }
protected:
BOOL WriteCommByte( unsigned char );
HANDLE m_hIDComDev;
OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
BOOL m_bOpened;
}
4.2 串列通信類Cserial 成員函數簡介
1. CSerial::Cserial是類構造函數,不帶參數,負責初始化所有類成員變數。
2. CSerial:: Open這個成員函數打開通信埠。帶兩個參數,第一個是埠號,有效值是1到4,第二個參數是波特率,返回一個布爾量。
3. CSerial:: Close函數關閉通信埠。類析構函數調用這個函數,所以可不用顯式調用這個函數。
4. CSerial:: SendData函數把數據從一個緩沖區寫到串列埠。它所帶的第一個參數是緩沖區指針,其中包含要被發送的資料;這個函數返回已寫到埠的實際位元組數。
5. CSerial:: ReadDataWaiting函數返回等待在通信埠緩沖區中的數據,不帶參數。
6. CSerial:: ReadData函數從埠接收緩沖區讀入數據。第一個參數是void*緩沖區指針,資料將被放入該緩沖區;第二個參數是個整數值,給出緩沖區的大小。