《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 設(shè)計應(yīng)用 > 基于VC++6.0的讀表軟件設(shè)計
基于VC++6.0的讀表軟件設(shè)計
來源:微型機與應(yīng)用2014年第5期
易 馳,,文小玲,,鄒艷華,周 洵
(武漢工程大學(xué) 電氣信息學(xué)院,,湖北 武漢 430205)
摘要: 利用VC++6.0設(shè)計了一種基于串口通信原理的直讀表軟件,,實現(xiàn)了PC上位機與RS485型/Mbus型水表、RS485型氣表和電表的串行數(shù)據(jù)通信,。同時,,該軟件能查抄表的實時數(shù)據(jù),完成重新設(shè)置表的地址和密碼等功能,。實際的測試結(jié)果證明了軟件設(shè)計的正確性,、有效性。
Abstract:
Key words :

摘  要: 利用VC++6.0設(shè)計了一種基于串口通信原理的直讀表軟件,,實現(xiàn)了PC上位機與RS485型/Mbus型水表,、RS485型氣表和電表的串行數(shù)據(jù)通信。同時,,該軟件能查抄表的實時數(shù)據(jù),,完成重新設(shè)置表的地址和密碼等功能。實際的測試結(jié)果證明了軟件設(shè)計的正確性,、有效性,。
關(guān)鍵詞: 串口通信;VC++,;抄表,;數(shù)據(jù)

 隨著城市化進程的加快、物業(yè)管理智能化的推進普及,,城市的供水,、供氣單位越來越多地投入使用新型智能遠(yuǎn)傳水表、氣表,。目前,,RS485,、M-bus遠(yuǎn)傳表已經(jīng)在居民小區(qū)廣泛地投入運用。但由于起步晚,、技術(shù)不成熟等種種因素,,安裝了自動抄表系統(tǒng)的小區(qū),都或多或少會出現(xiàn)一些問題,,如抄不到表讀數(shù),、表頭壞死等。同時,,新表的更替和使用也涉及到表地址的改寫,,表頭密碼的設(shè)置等問題。因此,,在抄表維護工作人員電腦上設(shè)計一種基于串口通信原理的直讀表軟件成為一種必然,。這將極大地方便水、氣表表頭模塊的檢測和抄表系統(tǒng)的日常維護等工作,。本文運用VC++6.0設(shè)計一種能夠讀取表讀數(shù)和表地址、設(shè)置表地址和表密碼,,并能測試串口通信情況的直讀表軟件,。
1 硬件系統(tǒng)組成原理
 硬件系統(tǒng)組成原理框圖如圖1所示,主要由表頭,、RS232-RS485轉(zhuǎn)換器,、PC機組成。RS232-RS485轉(zhuǎn)換器內(nèi)部包涵了485接口電路,、光電隔離和232接口電路,。通過該轉(zhuǎn)換器可以將485總線制設(shè)備(光電直讀表模塊)與計算機的串口相連,從而實現(xiàn)計算機與485總線制設(shè)備的通信,。表頭模塊內(nèi)部除了包含單片機,、光電隔離電路外,同時還集成了功能很強的可實現(xiàn)全雙工通信的485接口電路,,可以同時接收和發(fā)送數(shù)據(jù),,能夠方便地和遠(yuǎn)端上位機進行通信。

 硬件系統(tǒng)各組成部分之間的接線很方便,,將485型表的4根線準(zhǔn)確地接在RS232-RS485轉(zhuǎn)換器對應(yīng)的485端口上,,即A、B信號線和P,、G電源線分別正確連接,;同時232串口線一端連接轉(zhuǎn)換器,另一端連接電腦,,轉(zhuǎn)換器電源口接上12 V直流電源,,RS485轉(zhuǎn)換器可由P,、G線給表頭單片機模塊上電,指令信號則由A,、B信號線傳遞,,因此在計算機中用直讀表通信軟件即可讀得表數(shù)據(jù)。
2 軟件設(shè)計
 讀表軟件的主要功能是通過對軟件界面窗口按鈕的操作,,設(shè)置串口通信參數(shù),、查詢表的通信情況和表的數(shù)據(jù)信息等,包括上位機與表之間發(fā)送,、接收指令的顯示,;查詢表的類型,實時讀取表的數(shù)據(jù),、密碼,、地址編碼;修改表的地址編碼,、密碼和開關(guān)閥門狀態(tài),。
 本軟件依據(jù)硬件設(shè)備廠家配套的通信協(xié)議進行相應(yīng)開發(fā),此數(shù)據(jù)通信協(xié)議適用于RS485型/Mbus型直讀水表,、RS485型氣表,、RS485型電表和總線制光電直讀直飲水表,采用異步串行方式(一位起始位/八位數(shù)據(jù)位/兩位停止位/無奇偶校驗/波特率2 400),,采用CRC-CCITT(循環(huán)冗余碼)檢驗技術(shù),,保證通信數(shù)據(jù)準(zhǔn)確、可靠,。通信用數(shù)據(jù)包以“數(shù)據(jù)包頭”開頭,,“數(shù)據(jù)包尾”結(jié)尾。從上位機到表的發(fā)送指令以及從表到上位機的返回指令格式如表1,、表2所示,。其中,CRC校驗碼為有效數(shù)據(jù)的校驗碼,。CRC校驗數(shù)據(jù)長度為2 B,,CRC—CCITT是一個17位生成多項式G=[1 0001 0000 0010 0001],用多項式形式表示為G(x)=x16+x12+x5+1,,由它產(chǎn)生的檢驗碼R的二進制位數(shù)是16 bit(2 B),。

 根據(jù)流程圖,具體設(shè)計步驟如下:
?。?)建立項目,,打開VC++6.0,建立一個基于對話框的MFC應(yīng)用程序COMTOOL,,在項目中插入MSComm控件,,對于軟件界面的設(shè)計,,在VC下運用dialog對話框,可以拖拽控件,,對控件布局,,極為方便[2];
?。?)在對話框中添加發(fā)送和接收數(shù)據(jù)框,。向主對話框中添加兩個編輯框,一個用于顯示接收數(shù)據(jù)包,,ID為IDC_ReceiveEdit,;另一個用于輸入發(fā)送數(shù)據(jù),ID為IDC_SendEdit,;再添加一個按鈕,,功能是按一次就把發(fā)送編輯框中的內(nèi)容發(fā)送一次,將其ID設(shè)為IDC_Send,。再打開ClassWizard->Member Viariables選項卡,,選擇CSCommTestDlg類,為IDC_ReceiveEdit添加CString變量m_strReceive,,為IDC_SendEdit添加CString變量m_strSend,。說明:m_strReceive和m_strSend分別用來放入接收和發(fā)送的字符數(shù)據(jù)。
?。?)設(shè)置串口參數(shù)和打開串口。串口參數(shù)設(shè)置區(qū)的設(shè)計是關(guān)鍵環(huán)節(jié),,在操作軟件時,,只有正確的設(shè)置好串口的配置參數(shù),才能保證串行口的正常通信,。同時需要設(shè)計一個按鈕來打開串口,,在界面做一個“打開串口”按鈕,點擊此按鈕打開串口時,,同時會顯示串口參數(shù)的配置信息,。
 串口參數(shù)設(shè)置區(qū)的設(shè)計主要是向主對話框界面中添加以上參數(shù)相應(yīng)的編輯框,并將編輯框命名相應(yīng)的參數(shù),,把串口選擇,、波特率、數(shù)據(jù)位,、停止位和校驗位等編輯框拖拽在一個顯示框內(nèi),,命名為“串口設(shè)置”,這樣方便串口參數(shù)的設(shè)置和顯示,,“串口設(shè)置”區(qū)的界面設(shè)計包括:串口選擇,、波特率,、數(shù)據(jù)位、停止位和校驗位的設(shè)置,。向主對話框界面中添加以上參數(shù)相應(yīng)的編輯框,,在工程COMTOOL的主程序文件中對串口選擇、波特率,、數(shù)據(jù)位,、停止位和校驗位進行初值定義,程序如下:
 int BaudRate[]={300,,600,,1 200,2 400,,4 800,,9 600,14 400,,19 200,,38 400,56 000,,57 600,,115 200,230 400,,460 800,,921 600};
 int ParitySelNum=5,;
 CString Parity[]={_T("None"),,_T("Odd"),_T("Even"),,_T("Mark"),,_T("Space")};
 int DataBits[]={5,,6,,7,8},;
 int StopBits[]={1,,2};
 在指令發(fā)送,、接收編輯框和串口參數(shù)配置設(shè)計完成后,,在軟件界面上設(shè)計一個用來決定串口通信開和關(guān)的按鈕,即Push Button控制鍵,將其命名為“打開串口/關(guān)閉串口”按鈕,。在該按鈕的處理函數(shù)中打開串口,,即在相應(yīng)的處理函數(shù)OnOpenClose()中添代碼即可實現(xiàn)按鈕功能。
?。?)構(gòu)造發(fā)送指令,。在串行通信的情況下,由于表的基本數(shù)據(jù)信息會以數(shù)據(jù)包的形式傳送,,為了上位機能獲取表的數(shù)據(jù)信息,,因此在程序設(shè)計起初階段必須構(gòu)造相應(yīng)的發(fā)送指令,使表頭模塊返回對應(yīng)的數(shù)據(jù)信息包(即返回指令),。先為發(fā)送按鈕添加一個單擊消息即BN_CLICKED處理函數(shù),,打開ClassWizard->Message Maps,選擇類CSCommTestDlg,,選擇IDC_BUTTON_MANUALSEND,,雙擊BN_CLICKED添加OnSend()函數(shù),并在函數(shù)中添加發(fā)送數(shù)據(jù)功能代碼,,現(xiàn)在可以連接設(shè)備測試軟件是否能發(fā)送和接收指令,,配置好串口參數(shù),點擊發(fā)送按鈕,,如數(shù)據(jù)通信成功,,進行下一步[3]。
 不同的功能按鈕對應(yīng)不同的發(fā)送指令,,將每個按鈕賦予一個變量參數(shù),,當(dāng)按鈕操作一次,設(shè)定的發(fā)送指令字符串便賦給變量參數(shù),,同時發(fā)送指令數(shù)據(jù)包就發(fā)送出去,,因此才能完成軟件的讀取表讀數(shù)、改寫表地址等不同功能,。例如“手動讀表”按鈕的功能代碼如下:
CString temp;
    rec_w=1,;    
    UpdateData(true),;
    m_strSend = _T("");
    m_strReceive = _T(""),;
    if(m_strStatus=="關(guān)閉")
    {
        AfxMessageBox("請首先打開串口"),;
        return;
    }    
    m_strSend=_T("FE FE FE 42 42 42 42 53 FF FF FF FF 52 2D 3E 45"),;
    ClearBuffer(),;
    temp=m_strSend;
    temp=ChangeCharstr2Hexstr(temp);
    m_SerialPort.WriteToPort(temp.GetBuffer(temp.GetLength()),,temp.GetLength()),;
    m_nSendBytes+=temp.GetLength();
    m_strSendBytes.Format("%d",,m_nSendBytes),;
    UpdateData(false);
 為了實現(xiàn)對表不同的數(shù)據(jù)信息的讀取,,即為了發(fā)送不同的指令從而獲取相應(yīng)不同的返回數(shù)據(jù)包,,軟件界面上會設(shè)計不同的功能按鈕,如“手工讀表”,、“地址設(shè)置”,、“密碼設(shè)置”等,每個功能按鈕會有不同的發(fā)送指令,,這樣就能實現(xiàn)不同的功能,。每個按鈕的處理函數(shù)中會設(shè)計相應(yīng)的發(fā)送指令。例如:m_strSend=_T("FE FE FE 42 42 42 42 53 FF FF FF FF 52 2D 3E 45")這條廣播讀表指令以字符串形式賦值給“手動讀表”按鈕的變量參數(shù)m_strSend,,這樣每當(dāng)操作“手動讀表”或其他按鈕,,就會發(fā)送一條指令。
?。?)CRC校驗,。點擊發(fā)送指令按鈕,每發(fā)送一條指令,,正常情況下表模塊會返回一條指令,。在主體程序的設(shè)計中,這里添加一個接收返回數(shù)據(jù)包的功能區(qū),,將返回的指令數(shù)據(jù)包暫時存儲,,以便對其進行CRC校驗,判斷返回的數(shù)據(jù)包是否是有效數(shù)據(jù),。CRC校驗環(huán)節(jié)是為了測試返回數(shù)據(jù)包是否是所需要的有效返回指令,,即是否是發(fā)送指令對應(yīng)的返回指令,實現(xiàn)CRC校驗環(huán)節(jié)的主要程序段如下:
CrcA=s[0],;
CrcB=s[1],;
CrcC=s[2];
  for(i=2,;i<j,;i++)
   {
    CRC(&CrcA,&CrcB,,&CrcC),;
    CrcC=s[i+1],;
   }
  s[j]=CrcA;                        
  s[j+1]=CrcB,;
?。?)解析數(shù)據(jù)包程序。在CRC校驗無誤后,,才對返回的數(shù)據(jù)包進行解析,,故實現(xiàn)解析功能的程序設(shè)計是本設(shè)計的重要一環(huán),解析的目的是將返回數(shù)據(jù)包中的有效數(shù)據(jù)段轉(zhuǎn)換成表的相應(yīng)信息,,并正確地顯示在軟件界面上,。如實現(xiàn)地址改寫的主要解析程序如下所示:
CString temp=_T(""),temp2,;
    GetDlgItemText(IDC_AddrEdit,,temp);
    UpdateData(true),;
   rec_w=2,;
    m_strSend=_T("");
    m_strReceive=_T(""),;
    ChangeHexstr(temp,, New_data);
   for(int j=0,;j<4,;j++)
       NewSend[13+j]=New_data[3-j];//獲取新地址
    for(j=0,;j<4,;j++)
        NewSend[8+j]=Rec_data[j+5];//獲取舊地址
    getCRCCCITT(&NewSend[8] ,,result ,, 9);//獲取CRC
    NewSend[17]=result[0],;
   NewSend[18]=result[1],;
    for( j=0;j<20,;j++)
    m_strSend+=DevideHexChar(NewSend[j])+_T(" "),;
    temp2=m_strSend;
    temp2=ChangeCharstr2Hexstr(temp2),;
    ClearBuffer();
    m_SerialPort.WriteToPort(temp2.GetBuffer(temp2.GetLength()),,temp2.GetLength()),;
    UpdateData(false);
 (7)添加表數(shù)據(jù)顯示框和設(shè)置按鈕,。為了清楚反映表的數(shù)據(jù)信息,,故設(shè)在軟件界面上添加不同的數(shù)據(jù)顯示框,也是設(shè)計的一部分,?;就ㄐ懦晒螅驮趯υ捒蛑刑砑影l(fā)送和接收數(shù)據(jù)框類似,,添加表的數(shù)據(jù)顯示框,,并對每個顯示框設(shè)置函數(shù)變量,變量的值就是表的數(shù)據(jù),;添加表的設(shè)置按鈕,,如“地址設(shè)置”等按鈕,并添加相應(yīng)的處理函數(shù),,在處理函數(shù)中編寫代碼就能實現(xiàn)按鈕的相應(yīng)功能,。
 (8)解析重置和清空緩存,。程序設(shè)計中,,“解析重置,緩存清空”這一環(huán)節(jié)的設(shè)計是為了在一次通信結(jié)束,,表的數(shù)據(jù)正確顯示后,,將緩存數(shù)據(jù)包的功能區(qū)清空,以便下一次通信返回數(shù)據(jù)包的緩存,,從而使軟件能夠多次,、反復(fù)地對表模塊發(fā)送相同或不同指令,快捷地完成“讀表”,、“修改地址”等各種功能,。這里在“解析重置”的設(shè)計中參數(shù)rec_w起到關(guān)鍵作用。例如,,在“手動讀表”中rec_w=1,,同時對應(yīng)這條發(fā)送指令的解析代碼中也將rec_w=1,故不同的發(fā)送指令會有不同的解析函數(shù)段,,這樣,,完成一次讀表操作后需要將rec_w的值重置為0,以便下次rec_w重新賦值進行不同的操作,。而對于“緩存清空”的代碼設(shè)計如下所示:
void CCOMTOOLDlg::ClearBuffer()//接收清零
{
    for(int i=0,;i<30;i++)
    {
        All_data[i]=0x00,;
        Rec_data[i]=0x00,;
    }
    m_strReceive="",;
}
 如程序設(shè)計流程圖所示,基于這種設(shè)計思想,,實際操作時軟件的工作流程如下:程序配置好通信串口參數(shù)后,,一直處于等待OnComm事件狀態(tài)。上位機需要讀取表的數(shù)據(jù)時,,通過讀表軟件發(fā)送一條讀表指令數(shù)據(jù)包,,當(dāng)接收到表模塊返回的數(shù)據(jù)包后放入程序中的緩存功能函數(shù)中,再經(jīng)過CRC校驗返回數(shù)據(jù)包是否正確,,校驗成功后才調(diào)用解析子函數(shù)[4],,對接收指令數(shù)據(jù)包進行解析,然后將解析出的表的參數(shù)完整顯示在讀表軟件界面上,,最后將解析函數(shù)重置并將緩存功能函數(shù)中數(shù)據(jù)清空,,結(jié)束本次數(shù)據(jù)通信。
3 測試結(jié)果分析
 經(jīng)過調(diào)試運行成功后,,設(shè)計好的界面如圖3所示,。

 

 

 從圖3中可以看到,使用該軟件調(diào)試串口通信,、讀取表數(shù)據(jù)非常方便,、直觀。當(dāng)連接好表等相關(guān)設(shè)備時,,用戶根據(jù)實際情況選擇相應(yīng)的串行端口,,設(shè)定所需的波特率(在此選用2 400),再設(shè)置奇偶校驗位,、數(shù)據(jù)位,、停止位;點擊“串口打開”按鈕串口便打開,,再點擊“手工讀表”便可以進行指令的傳送和接收,,并能正確顯示表的讀數(shù)、地址等相關(guān)信息,;當(dāng)在表與上位機通信正常情況下,,點擊“地址設(shè)置”按鈕便可以將表的地址更改;“密碼設(shè)置”等按鈕的操作與“地址設(shè)置”類似,,并且實現(xiàn)其相應(yīng)的功能,。同時,可以通過“清空顯示”按鈕清除接收數(shù)據(jù)在接收文本框中的顯示,。
 本軟件經(jīng)過測試后可以進行上位機與表之間數(shù)據(jù)包的發(fā)送與接收,,并能正確解析出返回指令中表的實時數(shù)據(jù),如表的讀數(shù),,表的地址等表的信息清楚地顯示在軟件界面上,;同時,,表地址的重新設(shè)置,表密碼的修改等功能均能實現(xiàn),。軟件適用于常見的RS485型/Mbus型水表、RS485型氣表和RS485型電表,,對遠(yuǎn)傳抄表系統(tǒng)的維護和安裝工作有一定的現(xiàn)實意義,。
參考文獻
[1] 封亞斌.采用串口通信技術(shù)實現(xiàn)Modbus數(shù)據(jù)通信[J].自動化儀表,2004,,25(10):56-58.
[2] 張新村,,嚴(yán)殊.基于ARM的Linux系統(tǒng)下Qt串口助手的設(shè)計[J].軟件導(dǎo)刊,2011,,(8):64-66.
[3] 龔建偉,,熊光明.Visual C++/Turbo C串口通信編程實踐[M].北京:電子工業(yè)出版社,2007.
[4] 宋國清,,劉暢.基于BTF340開發(fā)板的Modbus從機協(xié)議實現(xiàn)[J].雞西大學(xué)學(xué)報,,2011,11(1):44-45.

此內(nèi)容為AET網(wǎng)站原創(chuàng),,未經(jīng)授權(quán)禁止轉(zhuǎn)載,。