VC++編寫簡單串口上位機程序


參考資源:VC++編寫簡單串口上位機程序

串口通信,MCU跟PC通信經常用到的一種通信方式,做界面、寫上位機程序的編程語言、編譯環境等不少,VB、C#、LABVIEW等等,我會的語言很少,C語言用得比較多,但是還沒有找到如何用C語言來寫串口通信上位機程序的資料,在圖書管理找到了用VC++編寫串口上位機的資料,參考書籍,用自己相當蹩腳的C++寫出了一個簡單的串口上位機程序,分享一下,體驗一下單片機和PC通信的樂趣。 編譯環境:VC++6.0 
操作系統:Windows XP

 程序實現功能:  1、 PC初始化COM1口,使用n81方式,波特率9600與單片機通信。PC的COM口編號可以通過如下方式修改:

當然也可以通過上位機軟件編寫,通過按鈕來選擇COM端口號,但是此次僅僅是簡單的例程,就沒有弄那么復雜了。COM1口可用的話,會提示串口初始化完畢。否則會提示串口已經打開Port already open,表示串口已經打開,被占用了。

2、 點擊開始轉換,串口會向單片機發送0xaa,單片機串口中斷接收到0xaa后啟動ADC轉換一次,並把轉換結果ADCL、ADCH共兩個字節的結果發送至PC,PC進行數值轉換后在窗口里顯示。(見文章末尾圖)

3、 為防止串口被一只占用,點擊關閉串口可以關閉COM1,供其它程序使用,點擊后按鈕變為打開串口,點擊可重新打開COM1。 

程序的編寫:
1、 打開VC++6.0建立基於對話框的MFC應用程序Test,

2、 在項目中插入MSComm控件:工程->增加到工程->Components and Controls->雙擊Registered ActiveX Controls->選擇Microsoft Communications Control, version 6.0->Insert,按默認值添加,你會發現多了個電話圖標,這是增加后串口通信控件。

3、 刪除確認、取消和提示框,添加“電話”、進程、靜態文本、按鈕、編輯框,拖動添加的控件,根據喜好布局。

4、 右擊編輯框Edit選擇屬性,在樣式里設置,勾選多行、垂直滾動,其它可按默認值。
右擊靜態文本Text選擇屬性,在常規設置里,修改標題。
右擊按鈕PushButton選擇屬性,在在常規設置里,修改標題。

修改后界面如下,程序寫出來運行時“電話”標志會自動消失。

5、 查看->建立類向導MFC ClassWizard->Member Viariable,選擇ClassName為CTestDlg的類,Control ID為MSCOMM1,雙擊它,為它添加控制變量m_comm1。
類似的,選擇IDC_BUTTON2添加控制變量m_serial。

(建立類向導也可以右擊然后在彈出的快捷菜單里選擇建立類向導)

至此,基本框架已經出來了,編譯后運行可以看到如下所示的界面。(組建->全部組件,然后 組建->執行) 

6、 點擊左側的視圖窗口,可以在三種模式下切換,第三個是打開我們的源代碼窗口,第一個是類,第二個是窗體的資源視圖。

選擇File View,展開test files->Header Files,打開testDlg.h,在全局變量下添加如下代碼,然后保存:
int gllen;//定義整型標量gllen,用於記錄接收數據的個數
CProgressCtrl * pbar; //指向進度條的指針,用於操作進度條

CString strRXDdata; //編輯框顯示的文本,記錄歷次轉換值

 

7、 點擊Recourse View,展開test recourses->Dialog,雙擊IDD_TEST_DIALOG,編輯我們的主界面對話框。
雙擊“電話”,彈出如下對話框,按確認鍵:

VC會進入源碼編輯窗口,這個函數是用來處理串口事件的,當PC串口接收到數據時,會產生一個數據緩沖區有數據的消息事件,然后調用執行這個函數。添加如下代碼,進行數據處理,窗口更新等操作:

 1 void CDavidDlg::OnOnCommMscomm1() 
 2 {
 3     // TODO: Add your control notification handler code here
 4     //****************************************
 5     VARIANT variant1;//定義VARIANT型變量,用於存放接收到的數據  
 6     COleSafeArray safearray;//定義safearray型變量  
 7     LONG LEN,k;//定義長整型變量len,k 
 8     BYTE rxdata[2048];//定義BYTE型數組 
 9     CString stremp1,stremp2;//定義兩個字符串   
10     if(m_comm1.GetCommEvent()==2) //判斷引起OnComm時間的原因  {//如果是接收到特定個字節數,則讀取接收到的數據  
11     variant1 = m_comm1.GetInput();//把接收到的數據存放到VARIANT型變量里 
12     safearray = variant1;//VARIANT型變量轉換為ColeSafeArray型變量  
13     LEN = safearray.GetOneDimSize();   
14     for(k=0;k<LEN;k++)  
15         {  
16         safearray.GetElement(&k,rxdata+k); //得到接接收到的數據放到BYTE型數組rxdata里  
17         }  
18     for(k=0;k<LEN;k++)  
19     {  
20         BYTE bt = (*(unsigned char*)(rxdata+k)); //讀取AD轉換的高字節  
21 
22         if((k%2)==0) 
23         if((k+1)<LEN)  
24         {  
25             gllen++;//全局的變量,對接收到的轉換結果的個數進行計算 
26             stremp2.Format("第%d次轉換結果:",gllen);//顯示第幾次轉換  
27             int temp = bt*4+((*(unsigned char *)(rxdata+k+1))>>6); //高低字節合並成實際的轉換結果,注意轉換結果是左 對齊  
28             stremp1.Format("%2.2f",(2.56*temp/1024));//計算成實際電壓值  
29             SetDlgItemText(IDC_STATIC,("當前電壓值為: "+stremp1+" V")); //更新靜態文本控件  
30             pbar -> SetPos(temp);//更新進度條的當前位置 
31             strRXDdata += stremp2;//把新的數據放到全局的字符串里   
32             strRXDdata += stremp1;  
33             strRXDdata += " V\r\n";//字符串加單位V后換行   
34         } 
35     }
View Code

這時重新編譯一下,看會不會有什么錯誤,出現下面提示,可以選擇全部組建來清除。
LINK : LNK4073: cannot create map for .ILK file; linking nonincrementally
出現下面錯誤,請關閉運行的test.exe后重試。
LINK : fatal error LNK1104: cannot open file "Debug/test.exe"
出現下面錯誤兩種錯誤,是由於空間編號問題引起的,當我們添加了編輯框或者“電話”后再添加,其編號自動加一,就會出現控件沒定義。
Z:\vc++串口上位機\test\testDlg.cpp(32) : error C2065: 'IDC_MSCOMM1' : undeclared identifier
Z:\vc++串口上位機\test\testDlg.cpp(139) : error C2065: 'IDC_EDIT1' : undeclared identifier
解決方法是,在RecourseView里,打開窗體IDD_TEST_DIALOG,右擊“電話”或者編輯框等其它出錯的控件,右擊選擇屬性,在常規里修改ID,這里的程序,除BUTTON有1、2兩個之外,其它都是1

全部組建編譯一下,看看有沒有錯誤,沒有錯誤就可以運行一下,可以看到界面更原來是一樣的。有錯誤就修改一下,省得弄多了,錯在哪里都不知道,查起來麻煩。

8、 在源碼編輯里,打開testDlg.cpp文件,進行窗口初始化函數的編寫。
找到BOOL CTestDlg::OnInitDialog()函數,

在SetIcon(m_hIcon, FALSE); // Set small icon 
// TODO: Add extra initialization here
后面添加如下初始化代碼:

 1     // TODO: Add extra initialization here
 2     //****************************************
 3     gllen = 0; //記錄轉換次數全局變量清零 
 4     if(! m_comm1.GetPortOpen())//判斷串口是否已經打開  
 5     {  
 6         m_comm1.SetCommPort(2); //選擇串口號2 
 7         m_comm1.SetPortOpen(TRUE); //打開串口  
 8         m_comm1.SetRThreshold(2); //收到兩個字節引發OnComm事件  
 9         m_comm1.SetInputMode(1);//輸入模式選為二進制  
10         m_comm1.SetSettings("57600,n,8,1"); //設置串口參數,波特率57600,無奇偶校驗,1位停止位,8位數據位  
11         MessageBox("串口初始化完畢","提示"); //提示串口成功初始化  
12     }  
13     else MessageBox("串口被占用","提示"); //如果已經打開串口,消息框提醒 
14     pbar = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);//獲得指向IDC_PROGRESS1的指針  
15     pbar -> SetRange(0,1023);//設置進度條的范圍0~1023  
16     pbar -> SetPos(0);//當前位置為0  
17     m_serial.SetWindowText("關閉串口");//按鈕顯示狀態改變  
18     //****************************************
View Code

可以看到,串口的參數等等都在在這里初始化的,可以根據自己的需要修改的,具體可以查看VC++里的詳細介紹,看看有哪些參數可以給我們修改來用。
添加后再編譯一下,運行后可以看到多了一個串口初始化的提示信息窗口。
至此,我們已經完成了主要的串口操作及界面,剩下的就是兩個按鈕的操作了。

9、 回到資源視圖的IDD_TEST_DIALOG窗口,雙擊開始轉換按鈕,給它添加事件,點擊后PC通過串口發送0xaa出來,給單片機接收。
添加如下代碼:

 1 void CDavidDlg::OnButton1() 
 2 {
 3     // TODO: Add your control notification handler code here
 4     //****************************************
 5     CByteArray m_Array; //定義字節數組 
 6     m_Array.RemoveAll(); //字節數組清空 
 7     m_Array.SetSize(1); //設定維數為1 
 8     m_Array.SetAt(0,0xaa); //給m_array[0]賦值0  
 9     m_comm1.SetOutput(COleVariant(m_Array));//由於SetOutput函數的參數為VARIANT型,必須強制轉換后才能發送  
10     //****************************************
11 }
View Code

同樣地,雙擊另外一個按鈕,給串口操作按鈕添加代碼,用於關閉或者打開串口。添加如下代碼:

 1 void CDavidDlg::OnButton2() 
 2 {
 3     // TODO: Add your control notification handler code here
 4     
 5     //****************************************
 6     if(! m_comm1.GetPortOpen())//判斷串口是否已經打開  
 7     {   
 8         m_comm1.SetPortOpen(TRUE); //如果串口是關閉的,則打開串口 
 9         m_serial.SetWindowText("關閉串口"); //按鈕顯示狀態改變  
10     } 
11     else  
12     {  
13         m_comm1.SetPortOpen(FALSE); //如果已經打開串口,則關閉串口 
14         m_serial.SetWindowText("打開串口");//按鈕顯示狀態改變  
15     }  
16 //****************************************
17 
18 }
View Code

至此,一個簡單的串口上位機軟件編寫完成了,可以用來測試下,通過單片機往串口里發送數據,可以看到主窗口的的轉換結果,已經進度條顯示電壓值變化。要把這個程序拿出來用,只需把…\vc++串口上位機\test\Release的test.exe拷出來用就行。Release可以在編譯窗口里選擇win32 release,然后重新編譯一下就出來了。

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM