版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第頁VC++串口上位機(jī)簡單例程(源碼及詳細(xì)步驟)VC++串口上位機(jī)簡單例程.rar(4.33MB)
VC++編寫簡單串口上位機(jī)程序
2010年4月13日10:23:40
串口通信,MCU跟PC通信經(jīng)常用到的一種通信方式,做界面、寫上位機(jī)程序的編程語言、編譯環(huán)境等不少,VB、C#、LABVIEW等等,我會的語言很少,C語言用得比較多,但是還沒有找到如何用C語言來寫串口通信上位機(jī)程序的資料,在圖書管理找到了用VC++編寫串口上位機(jī)的資料,參考書籍,用自己相當(dāng)蹩腳的C++寫出了一個簡單的串口上位機(jī)程序,分享一下,體驗一下單片機(jī)和PC通信的樂趣。
編譯環(huán)境:VC++6.0
操作系統(tǒng):VMWare虛擬出來的WindowsXP
程序?qū)崿F(xiàn)功能:
1、PC初始化COM1口,使用n81方式,波特率57600及單片機(jī)通信。PC的COM口編號可以通過如下方式修改:
當(dāng)然也可以通過上位機(jī)軟件編寫,通過按鈕來選擇COM端口號,但是此次僅僅是簡單的例程,就沒有弄那么復(fù)雜了。COM1口可用的話,會提示串口初始化完畢。否則會提示串口已經(jīng)打開Portalreadyopen,表示串口已經(jīng)打開,被占用了。
2、點擊開始轉(zhuǎn)換,串口會向單片機(jī)發(fā)送0xaa,單片機(jī)串口中斷接收到0xaa后啟動ADC轉(zhuǎn)換一次,并把轉(zhuǎn)換結(jié)果ADCL、ADCH共兩個字節(jié)的結(jié)果發(fā)送至PC,PC進(jìn)行數(shù)值轉(zhuǎn)換后在窗口里顯示。(見文章末尾圖)
3、為防止串口被一只占用,點擊關(guān)閉串口可以關(guān)閉COM1,供其它程序使用,點擊后按鈕變?yōu)榇蜷_串口,點擊可重新打開COM1。
程序的編寫:
1、打開VC++6.0建立基于對話框的MFC應(yīng)用程序Test,
2、在項目中插入MSComm控件:工程->增加到工程->ComponentsandControls->雙擊RegisteredActiveXControls->選擇MicrosoftCommunicationsControl,version6.0->Insert,按默認(rèn)值添加,你會發(fā)現(xiàn)多了個電話圖標(biāo),這是增加后串口通信控件。
3、刪除確認(rèn)、取消和提示框,添加“電話”、進(jìn)程、靜態(tài)文本、按鈕、編輯框,拖動添加的控件,根據(jù)喜好布局。
4、右擊編輯框Edit選擇屬性,在樣式里設(shè)置,勾選多行、垂直滾動,其它可按默認(rèn)值。
右擊靜態(tài)文本Text選擇屬性,在常規(guī)設(shè)置里,修改標(biāo)題。
右擊按鈕PushButton選擇屬性,在在常規(guī)設(shè)置里,修改標(biāo)題。
修改后界面如下,程序?qū)懗鰜磉\行時“電話”標(biāo)志會自動消失。
5、查看->建立類向?qū)FCClassWizard->MemberViariable,選擇ClassName為CTestDlg的類,ControlID為MSCOMM1,雙擊它,為它添加控制變量m_comm1。
類似的,選擇IDC_BUTTON2添加控制變量m_serial。
(建立類向?qū)б部梢杂覔羧缓笤趶棾龅目旖莶藛卫镞x擇建立類向?qū)В?/p>
至此,基本框架已經(jīng)出來了,編譯后運行可以看到如下所示的界面。(組建->全部組件,然后組建->執(zhí)行)
6、點擊左側(cè)的視圖窗口,可以在三種模式下切換,第三個是打開我們的源代碼窗口,第一個是類,第二個是窗體的資源視圖。
選擇FileView,展開testfiles->HeaderFiles,打開testDlg.h,在全局變量下添加如下代碼,然后保存:
intgllen;//定義整型標(biāo)量gllen,用于記錄接收數(shù)據(jù)的個數(shù)
CProgressCtrl*pbar;//指向進(jìn)度條的指針,用于操作進(jìn)度條
CStringstrRXDdata;//編輯框顯示的文本,記錄歷次轉(zhuǎn)換值
7、點擊RecourseView,展開testrecourses->Dialog,雙擊IDD_TEST_DIALOG,編輯我們的主界面對話框。
雙擊擊“電話”,彈出如下對話框,按確認(rèn)鍵:
VC會進(jìn)入源碼編輯窗口,這個函數(shù)是用來處理串口事件的,當(dāng)PC串口接收到數(shù)據(jù)時,會產(chǎn)生一個數(shù)據(jù)緩沖區(qū)有數(shù)據(jù)的消息事件,然后調(diào)用執(zhí)行這個函數(shù)。添加如下代碼,進(jìn)行數(shù)據(jù)處理,窗口更新等操作:
VARIANTvariant1;//定義VARIANT型變量,用于存放接收到的數(shù)據(jù)
COleSafeArraysafearray;//定義safearray型變量
LONGlen,k;//定義長整型變量len,k
BYTErxdata[2048];//定義BYTE型數(shù)組
CStringstremp1,stremp2;//定義兩個字符串
if(m_comm1.GetCommEvent()==2)//判斷引起OnComm時間的原因
{//如果是接收到特定個字節(jié)數(shù),則讀取接收到的數(shù)據(jù)
variant1=m_comm1.GetInput();//把接收到的數(shù)據(jù)存放到VARIANT型變量里
safearray=variant1;//VARIANT型變量轉(zhuǎn)換為ColeSafeArray型變量
len=safearray.GetOneDimSize();
for(k=0;k<len;k++)
{
safearray.GetElement(&k,rxdata+k);//得到接接收到的數(shù)據(jù)放到BYTE型數(shù)組rxdata里
}
for(k=0;k<len;k++)
{
BYTEbt=(*(unsignedchar*)(rxdata+k));//讀取AD轉(zhuǎn)換的高字節(jié)
if((k%2)==0)
if((k+1)<len)
{
gllen++;//全局的變量,對接收到的轉(zhuǎn)換結(jié)果的個數(shù)進(jìn)行計算
stremp2.Format("第%d次轉(zhuǎn)換結(jié)果:",gllen);//顯示第幾次轉(zhuǎn)換
inttemp=bt*4+((*(unsignedchar*)(rxdata+k+1))>>6);//高低字節(jié)合并成實際的轉(zhuǎn)換結(jié)果,注意轉(zhuǎn)換結(jié)果是左對齊
stremp1.Format("%2.2f",(2.56*temp/1024));//計算成實際電壓值
SetDlgItemText(IDC_STATIC,("當(dāng)前電壓值為:"+stremp1+"V"));//更新靜態(tài)文本控件
pbar->SetPos(temp);//更新進(jìn)度條的當(dāng)前位置
strRXDdata+=stremp2;//把新的數(shù)據(jù)放到全局的字符串里
strRXDdata+=stremp1;
strRXDdata+="V\r\n";//字符串加單位V后換行
}
}
}
SetDlgItemText(IDC_EDIT1,strRXDdata);//更新文本控件的顯示
這時重新編譯一下,看會不會有什么錯誤,出現(xiàn)下面提示,可以選擇全部組建來清除。
LINK:LNK4073:cannotcreatemapfor.ILKfile;linkingnonincrementally
出現(xiàn)下面錯誤,請關(guān)閉運行的test.exe后重試。
LINK:fatalerrorLNK1104:cannotopenfile"Debug/test.exe"
出現(xiàn)下面錯誤兩種錯誤,是由于空間編號問題引起的,當(dāng)我們添加了編輯框或者“電話”后再添加,其編號自動加一,就會出現(xiàn)控件沒定義。
Z:\vc++串口上位機(jī)\test\testDlg.cpp(32):errorC2065:'IDC_MSCOMM1':undeclaredidentifier
Z:\vc++串口上位機(jī)\test\testDlg.cpp(139):errorC2065:'IDC_EDIT1':undeclaredidentifier
解決方法是,在RecourseView里,打開窗體IDD_TEST_DIALOG,右擊“電話”或者編輯框等其它出錯的控件,右擊選擇屬性,在常規(guī)里修改ID,這里的程序,除BUTTON有1、2兩個之外,其它都是1
全部組建編譯一下,看看有沒有錯誤,沒有錯誤就可以運行一下,可以看到界面更原來是一樣的。有錯誤就修改一下,省得弄多了,錯在哪里都不知道,查起來麻煩。
8、在源碼編輯里,打開testDlg.cpp文件,進(jìn)行窗口初始化函數(shù)的編寫。
找到BOOLCTestDlg::OnInitDialog()函數(shù),
在SetIcon(m_hIcon,FALSE);
//Setsmallicon
//TODO:Addextrainitializationhere
后面添加如下初始化代碼:
gllen=0;//記錄轉(zhuǎn)換次數(shù)全局變量清零
if(!m_comm1.GetPortOpen())//判斷串口是否已經(jīng)打開
{
m_comm1.SetCommPort(1);//選擇串口號1
m_comm1.SetPortOpen(TRUE);//打開串口
m_comm1.SetRThreshold(2);//收到兩個字節(jié)引發(fā)OnComm事件
m_comm1.SetInputMode(1);//輸入模式選為二進(jìn)制
m_comm1.SetSettings("57600,n,8,1");//設(shè)置串口參數(shù),波特率57600,無奇偶校驗,1位停止位,8位數(shù)據(jù)位
MessageBox("串口初始化完畢","提示");//提示串口成功初始化
}
elseMessageBox("串口被占用","提示");//如果已經(jīng)打開串口,消息框提醒
pbar=(CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);//獲得指向IDC_PROGRESS1的指針
pbar->SetRange(0,1023);//設(shè)置進(jìn)度條的范圍0~1023
pbar->SetPos(0);//當(dāng)前位置為0
m_serial.SetWindowText("關(guān)閉串口");//按鈕顯示狀態(tài)改變
可以看到,串口的參數(shù)等等都在在這里初始化的,可以根據(jù)自己的需要修改的,具體可以查看VC++里的詳細(xì)介紹,看看有哪些參數(shù)可以給我們修改來用。
添加后再編譯一下,運行后可以看到多了一個串口初始化的提示信息窗口。
至此,我們已經(jīng)完成了主要的串口操作及界面,剩下的就是兩個按鈕的操作了。
9、回到資源視圖的IDD_TEST_DIALOG窗口,雙擊開始轉(zhuǎn)換按鈕,給它添加事件,點擊后PC通過串口發(fā)送0xaa出來,給單片機(jī)接收。
添加如下代碼:
CByteArraym_Array;//定義字節(jié)數(shù)組
m_Array.RemoveAll();//字節(jié)數(shù)組清空
m_Array.SetSize(1);//設(shè)定維數(shù)為1
m_Array.SetAt(0,0xaa);//給m_array[0]賦值0
m_comm1.SetOutput(COleVariant(m_Array));//由于SetOutput函數(shù)的參數(shù)為VARIANT型,必須強(qiáng)制轉(zhuǎn)換后才能發(fā)送
同樣地,雙擊另外一個按鈕,給串口操作按鈕添加代碼,用于關(guān)閉或者打開串口。添加如下代碼:
if(!m_comm1.GetPortOpen())//判斷串口是否已經(jīng)打開
{
m_comm1.SetPortOpen(TRUE);//如果串口是關(guān)閉的,則打開串口
m_serial.SetWindowText("關(guān)閉串口");//按鈕顯示狀態(tài)改變
}
else
{
m_comm1.SetPortOpen(FALSE);//如果已經(jīng)打開串口,則關(guān)閉串口
m_serial.SetWindowText("打開串口");//按鈕顯示狀態(tài)改變
}
至此,一個簡單的串口上位機(jī)軟件編寫完成了,可以用來測試下,通過單片機(jī)往串口里發(fā)送數(shù)據(jù),可以看到主窗口的的轉(zhuǎn)換結(jié)果,已經(jīng)進(jìn)度條顯示電壓值變化。要把這個程序拿出來用,只需把…\vc++串口上位機(jī)\test\Release的test.exe拷出來用就行。Release可以在編譯窗口里選擇win32release,然后重新編譯一下就出來了。
1。建立mfc工程,都會撒。
將控件加進(jìn)來:打開“Project->AddToProject->ComponentsandControls->RegisteredActivexControls”,然后選擇控件:MicrosoftCommunicationControl,version6.0插入到當(dāng)前的工程中。這樣就將類CMSComm的相關(guān)文件mscomm.cpp和mscomm.h一并加入到了工程中。編程時只需將控件對話中的MSComm控件拖至你的應(yīng)用對話框中就OK了2。定義串口對象:
CMSComm
m_MSComm;3。串口初始化:
DWORDstyle=WS_VISIBLE;
m_MSComm.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM);
if(m_MSComm.GetPortOpen())//如果串口是打開的,則行關(guān)閉串口
{
m_MSComm.SetPortOpen(FALSE);
}
m_MSComm.SetCommPort(1);//選擇COM1
m_MSComm.SetInBufferSize(1024);//接收緩沖區(qū)
m_MSComm.SetOutBufferSize(1024);//發(fā)送緩沖區(qū)
m_MSComm.SetInputLen(0);//設(shè)置當(dāng)前接收區(qū)數(shù)據(jù)長度為0,表示全部讀取
m_MSComm.SetInputMode(1);//以二進(jìn)制方式讀寫數(shù)據(jù)
m_MSComm.SetRThreshold(1);//接收緩沖區(qū)有1個及1個以上字符時,將引發(fā)接收數(shù)據(jù)的OnComm事件
m_MSComm.SetSettings("9600,n,8,1");//波特率9600無檢驗位,8個數(shù)據(jù)位,1個停止位
if(!m_MSComm.GetPortOpen())//如果串口沒有打開則打開
m_MSComm.SetPortOpen(TRUE);//打開串口
else
{
m_MSComm.SetOutBufferCount(0);
AfxMessageBox("OpenTheSerialPort1Failurre!");
}
4。串口數(shù)據(jù)讀寫:MSComm類的讀寫函數(shù)比較簡單:GetInput()和SetOutput()。函數(shù)原形分別為VARIANTGetInput()和voidSetOutput(constVARIANTnewValue),均使用VARIANT類型。但PC機(jī)發(fā)送和接收數(shù)據(jù)時習(xí)慣用字符串形式。MSDN中查閱VARIANT類型,可以用BSTR表示字符串,但所有的BSTR都包含寬字符,而只有WindowsNT支持寬字符,Windows9X并不支持。所以要完成一個適應(yīng)各平臺的串口應(yīng)用程序必須解決這個問題。這里使用CbyteArray即可解決之。發(fā)數(shù)據(jù):在對話框?qū)尤氚粹o控件并給你添加消息
voidCTest_mscommDlg::OnSend()
{
//TODO:Addyourcontrolnotificationhandlercodehere
inti,Count;
CStringm_SendData;
m_SendData="Hello!";
Count=m_SendData.GetLength();
CByteArraym_Array;
m_Array.RemoveAll();
m_Array.SetSize(Count);
for(inti=0;i<count;i++)
{
m_Array.SetAt(i,m_SendData.GetAt(i));
}
m_mscomm.SetOutput(COleVariant(m_Array);
收數(shù)據(jù):給串口控件添加消息
voidCTest_mscommDlg::OnOnCommMscomm()
{
VARIANTm_input;
char*str,*str1;
intk,nEvent,i;
CStringstr2,m_RcvData;
nEvent=m_MSComm.GetCommEvent();
switch(nEvent)
{
case2:
k=m_MSComm.GetInBufferCount();
//接收緩沖區(qū)的字符數(shù)目
if(k>0)
{
m_input=m_MSComm.GetInput();
str=(char*)(unsignedchar*)m_input.parray->pvData;
}
i=0;
str1=str;
while(im_disp+=m_RcvData;UpdateData(false);首先,在對話框中創(chuàng)建通信控件,若Control工具欄中缺少該控件,可通過菜單Project-->AddtoProject-->ComponentsandControl插入即可,再將該控件從工具箱中拉到對話框中。此時,你只需要關(guān)心控件提供的對Windows通訊驅(qū)動程序的API函數(shù)的接口。換句話說,只需要設(shè)置和監(jiān)視MSComm控件的屬性和事件。打開所需串口后,需要考慮串口通信的時機(jī)。在接收或發(fā)送數(shù)據(jù)過程中,可能需要監(jiān)視并響應(yīng)一些事件和錯誤,所以事件驅(qū)動是處理串行端口交互作用的一種非常有效的方法。使用OnComm事件和CommEvent屬性捕捉并檢查通訊事件和錯誤的值。發(fā)生通訊事件或錯誤時,將觸發(fā)OnComm事件,CommEvent屬性的值將被改變,應(yīng)用程序檢查CommEvent屬性值并作出相應(yīng)的反應(yīng)//若是在SDI中使用該控件則要調(diào)用下兩句,在對話框程序中該語句有MFC自己創(chuàng)建
//所以不用人為添加
DWORDstyle=WS_VISIBLE;
VC++下用MSComm控件實現(xiàn)串口通訊http://tech.163/school·2019-10-0817:59:47·來源:天極網(wǎng)
m_MSComm.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM1);
//串口控件的初始化
DWORDstyle=WS_VISIBLE;
m_MSComm.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM1);
if(m_MSComm.GetPortOpen())//如果串口是打開的,則行關(guān)閉串口
{
m_MSComm.SetPortOpen(FALSE);
}
m_MSComm.SetCommPort(1);//選擇COM1
m_MSComm.SetInBufferSize(1024);//接收緩沖區(qū)
m_MSComm.SetOutBufferSize(1024);//發(fā)送緩沖區(qū)
m_MSComm.SetInputLen(0);//設(shè)置當(dāng)前接收區(qū)數(shù)據(jù)長度為0,表示全部讀取
m_MSComm.SetInputMode(1);//以二進(jìn)制方式讀寫數(shù)據(jù)
m_MSComm.SetRThreshold(1);//接收緩沖區(qū)有1個及1個以上字符時,將引發(fā)接收數(shù)據(jù)的OnComm事件
m_MSComm.SetSettings("9600,n,8,1");//波特率9600無檢驗位,8個數(shù)據(jù)位,1個停止位
if(!m_MSComm.GetPortOpen())//如果串口沒有打開則打開
m_MSComm.SetPortOpen(TRUE);//打開串口
else
m_MSComm.SetOutBufferCount(0);
//控件事件的響應(yīng)聲明
//*.h
//{{AFX_MSG(CGolfView)
afx_msgBOOLOnComm();
DECLARE_EVENTSINK_MAP()
//}}AFX_MSG
//*.cpp
BEGIN_EVENTSINK_MAP(CGolfView,CView)
//{{AFX_EVENTSINK_MAP(CAboutDlg)
ON_EVENT(CGolfView,IDC_MSCOMM1,1/*OnCom
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 支付勞務(wù)工資的供銷合同
- 二零二五年度解除房屋租賃合同解除通知協(xié)議
- 二零二五年度生態(tài)旅游基地租用院子合同
- 2025年度混凝土攪拌車租賃與施工材料運輸合同
- 2025年度航空貨運物品安全保管與運輸服務(wù)合同
- 二零二五年度新材料研發(fā)團(tuán)隊勞動合同范本
- 二零二五年度國際教育合作項目合同協(xié)議書
- 二零二五年度帶屋頂花園簡易版房屋租賃合同
- 2025年度清雪承包合同-城市廣場冬季積雪清除與景觀維護(hù)
- 2025年度商業(yè)連鎖店鋪裝修工程承包給項目經(jīng)理合同
- (二模)遵義市2025屆高三年級第二次適應(yīng)性考試試卷 地理試卷(含答案)
- 二零二五隱名股東合作協(xié)議書及公司股權(quán)代持及回購協(xié)議
- 2025年計算機(jī)二級WPS考試題目
- 高管績效考核全案
- 2024年上海市中考英語試題和答案
- 對合同條款有異議函
- 中醫(yī)館工作細(xì)則
- 尋夢緣古法駐顏培訓(xùn)課件
- 建設(shè)用地報批服務(wù)投標(biāo)方案(技術(shù)方案)
- 2023年11月英語二級筆譯真題及答案(筆譯實務(wù))
- 元明時期左江上思州黃姓土司問題研究
評論
0/150
提交評論