《VC++串口上位機簡單例程(源碼及詳細(xì)步驟)》由會員分享,可在線閱讀,更多相關(guān)《VC++串口上位機簡單例程(源碼及詳細(xì)步驟)(14頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、VC++串口上位機簡單例程(源碼及詳細(xì)步驟)
VC++串口上位機簡單例程.rar (4.33 MB)
VC++編寫簡單串口上位機程序
2010年4月13日10:23:40
串口通信,MCU跟PC通信經(jīng)常用到的一種通信方式,做界面、寫上位機程序的編程語言、編譯環(huán)境等不少,VB、C#、LABVIEW等等,我會的語言很少,C語言用得比較多,但是還沒有找到如何用C語言來寫串口通信上位機程序的資料,在圖書管理找到了用VC++編寫串口上位機的資料,參考書籍,用自己相當(dāng)蹩腳的C++寫出了一個簡單的串口上位機程序,分享一下,體驗一下單片機和PC通信的樂趣。
編譯環(huán)境:VC++6.0
2、
操作系統(tǒng):VMWare虛擬出來的Windows XP
程序?qū)崿F(xiàn)功能:
1、 PC初始化COM1口,使用n81方式,波特率57600與單片機通信。PC的COM口編號可以通過如下方式修改:
當(dāng)然也可以通過上位機軟件編寫,通過按鈕來選擇COM端口號,但是此次僅僅是簡單的例程,就沒有弄那么復(fù)雜了。COM1口可用的話,會提示串口初始化完畢。否則會提示串口已經(jīng)打開Port already open,表示串口已經(jīng)打開,被占用了。
2、 點擊開始轉(zhuǎn)換,串口會向單片機發(fā)送0xaa,單片機串口中斷接收到0xaa后啟動ADC轉(zhuǎn)換一次,并把轉(zhuǎn)換結(jié)果ADCL、ADCH共兩個字節(jié)的結(jié)果發(fā)送至
3、PC,PC進行數(shù)值轉(zhuǎn)換后在窗口里顯示。(見文章末尾圖)
3、 為防止串口被一只占用,點擊關(guān)閉串口可以關(guān)閉COM1,供其它程序使用,點擊后按鈕變?yōu)榇蜷_串口,點擊可重新打開COM1。
程序的編寫:
1、 打開VC++6.0建立基于對話框的MFC應(yīng)用程序Test,
2、 在項目中插入MSComm控件:工程->增加到工程->Components and Controls->雙擊Registered ActiveX Controls->選擇Microsoft Communications Control, version 6.0->Insert,
4、按默認(rèn)值添加,你會發(fā)現(xiàn)多了個 圖標(biāo),這是增加后串口通信控件。
3、 刪除確認(rè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ū)FC ClassWizard->Member Viariable,選擇Cla
5、ssName為CTestDlg的類,Control ID為MSCOMM1,雙擊它,為它添加控制變量m_comm1。
類似的,選擇IDC_BUTTON2添加控制變量m_serial。
(建立類向?qū)б部梢杂覔羧缓笤趶棾龅目旖莶藛卫镞x擇建立類向?qū)В?
至此,基本框架已經(jīng)出來了,編譯后運行可以看到如下所示的界面。(組建->全部組件,然后 組建->執(zhí)行)
6、 點擊左側(cè)的視圖窗口,可以在三種模式下切換,第三個是打開我們的源代碼窗口,第一個是類,第二個是窗體的資源視圖。
選擇File View,展開test files->Header Files,打開testDlg.h,在
6、全局變量下添加如下代碼,然后保存:
int gllen;//定義整型標(biāo)量gllen,用于記錄接收數(shù)據(jù)的個數(shù)
CProgressCtrl * pbar; //指向進度條的指針,用于操作進度條
CString strRXDdata; //編輯框顯示的文本,記錄歷次轉(zhuǎn)換值
7、 點擊Recourse View,展開test recourses->Dialog,雙擊IDD_TEST_DIALOG,編輯我們的主界面對話框。
雙擊擊“ ”,彈出如下對話框,按確認(rèn)鍵:
VC會進入源碼編輯窗口,這個函數(shù)是用來處理串口事件的,當(dāng)PC串口接收到數(shù)據(jù)時,會產(chǎn)生一個數(shù)據(jù)緩沖區(qū)有數(shù)據(jù)的消
7、息事件,然后調(diào)用執(zhí)行這個函數(shù)。添加如下代碼,進行數(shù)據(jù)處理,窗口更新等操作:
VARIANT variant1;//定義VARIANT型變量,用于存放接收到的數(shù)據(jù)
COleSafeArray safearray;//定義safearray型變量
LONG len,k;//定義長整型變量len,k
BYTE rxdata[2048];//定義BYTE型數(shù)組
CString stremp1,stremp2;//定義兩個字符串
if(m_comm1.GetCommEvent()==2) //判斷引起OnComm時間的原因
{//如果是接收到特定個字節(jié)數(shù),則讀取接收到的數(shù)據(jù)
varian
8、t1 = m_comm1.GetInput();//把接收到的數(shù)據(jù)存放到VARIANT型變量里
safearray = variant1;//VARIANT型變量轉(zhuǎn)換為ColeSafeArray型變量
len = safearray.GetOneDimSize();
for(k=0;k
9、高字節(jié)
if((k%2)==0)
if((k+1)>6); //高低字節(jié)合并成實際的轉(zhuǎn)換結(jié)果,注意轉(zhuǎn)換結(jié)果是左對齊
stremp1.Format("%2.2f",(2.56*temp/1024));//計算成實際電壓值
SetDlgItemText(IDC_STATIC,("當(dāng)前電壓值為: "+strem
10、p1+" V")); //更新靜態(tài)文本控件
pbar -> SetPos(temp);//更新進度條的當(dāng)前位置
strRXDdata += stremp2;//把新的數(shù)據(jù)放到全局的字符串里
strRXDdata += stremp1;
strRXDdata += " V\r\n";//字符串加單位V后換行
}
}
}
SetDlgItemText(IDC_EDIT1,strRXDdata);//更新文本控件的顯示
這時重新編譯一下,看會不會有什么錯誤,出現(xiàn)下面提示,可以選擇全部組建來清除。
LINK : LNK4073: cannot create map for
11、.ILK file; linking nonincrementally
出現(xiàn)下面錯誤,請關(guān)閉運行的test.exe后重試。
LINK : fatal error LNK1104: cannot open file "Debug/test.exe"
出現(xiàn)下面錯誤兩種錯誤,是由于空間編號問題引起的,當(dāng)我們添加了編輯框或者“ ”后再添加,其編號自動加一,就會出現(xiàn)控件沒定義。
Z:\vc++串口上位機\test\testDlg.cpp(32) : error C2065: 'IDC_MSCOMM1' : undeclared identifier
Z:\vc++串口上位機\test\te
12、stDlg.cpp(139) : error C2065: 'IDC_EDIT1' : undeclared identifier
解決方法是,在RecourseView里,打開窗體IDD_TEST_DIALOG,右擊“ ”或者編輯框等其它出錯的控件,右擊選擇屬性,在常規(guī)里修改ID,這里的程序,除BUTTON有1、2兩個之外,其它都是1
全部組建編譯一下,看看有沒有錯誤,沒有錯誤就可以運行一下,可以看到界面更原來是一樣的。有錯誤就修改一下,省得弄多了,錯在哪里都不知道,查起來麻煩。
8、 在源碼編輯里,打開testDlg.cpp文件,進行窗口初始化函數(shù)的編寫。
找到BO
13、OL CTestDlg::OnInitDialog()函數(shù),
在SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
后面添加如下初始化代碼:
gllen = 0; //記錄轉(zhuǎn)換次數(shù)全局變量清零
if(! m_comm1.GetPortOpen())//判斷串口是否已經(jīng)打開
{
m_comm1.SetCommPort(1); //選擇串口號1
m_comm1.SetPortOpen(TRUE); //打開串口
m_comm1.SetRThreshold(2); /
14、/收到兩個字節(jié)引發(fā)OnComm事件
m_comm1.SetInputMode(1);//輸入模式選為二進制
m_comm1.SetSettings("57600,n,8,1"); //設(shè)置串口參數(shù),波特率57600,無奇偶校驗,1位停止位,8位數(shù)據(jù)位
MessageBox("串口初始化完畢","提示"); //提示串口成功初始化
}
else MessageBox("串口被占用","提示"); //如果已經(jīng)打開串口,消息框提醒
pbar = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);//獲得指向IDC_PROGRESS1的指針
pbar
15、-> SetRange(0,1023);//設(shè)置進度條的范圍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)換按鈕,給它添加事
16、件,點擊后PC通過串口發(fā)送0xaa出來,給單片機接收。
添加如下代碼:
CByteArray m_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型,必須強制轉(zhuǎn)換后才能發(fā)送
同樣地,雙擊另外一個按鈕,給串口操作按鈕添加代碼,用于關(guān)閉或者打開串口。添加如下代碼:
if
17、(! 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)改變
}
至此,一個簡單的串口上位機軟件編寫完成了,可以用來測試下,通過單片機往串口里發(fā)送數(shù)據(jù),可以看到主窗口的的轉(zhuǎn)換結(jié)果,已經(jīng)進度條顯示電壓值變化。要把這個程序拿出來用,只需把…\vc++串口上位機\test\Release的test.exe拷出來用就行。Release可以在編譯窗口里選擇win32 release,然后重新編譯一下就出來了。
參考書籍:陳冬云、杜敬倉、任柯燕等,《Atmega128單片機原理與開發(fā)指導(dǎo)》,2005,機械工業(yè)出版社。