黃 莉,顧 全,徐 擎,梁曉雄,范 越
(上海市計量測試技術研究院,上海 201203)
壓力記錄儀在工業(yè)現(xiàn)場中有著廣泛的應用,其可以穩(wěn)定準確地采集壓力儀表或壓力傳感器的數(shù)據(jù)值。而應用emwin 圖形界面開發(fā)平臺與傳統(tǒng)的開發(fā)模式相比,研發(fā)更快捷方便且窗體控件顯示效果更美觀大方,是一種較好的解決方案。壓力記錄儀數(shù)據(jù)采集后需要將記錄保存至數(shù)據(jù)庫文件系統(tǒng),且對儀表自身的執(zhí)行程序進行加密,為了便于操作者實現(xiàn)快捷記錄還應具有屏幕截屏功能,此外壓力記錄儀可以根據(jù)外置的供電方式進行動態(tài)的狀態(tài)顯示[1]。
壓力記錄儀需要對運行參數(shù)進行設置和保存,為了可靠便捷地實現(xiàn)此功能,需要應用儀表的DBF 數(shù)據(jù)庫存儲功能[2]。系統(tǒng)的配置屬性包括device 硬件接口類型,rate串口通訊波特率和check 串口通訊校驗。每一種配置包括不同的選項,硬件接口類型有MBUS、RS232、RS485、BLUETOOTH、IRDA_FAR 和BARCODE。rate 波特率包括600、1200、2400、4800 和9600。check 通訊校驗包括8 數(shù)據(jù)位1 停止位無校驗、8 數(shù)據(jù)位1 停止位奇校驗和8 數(shù)據(jù)位1 停止位偶校驗。
typedef struct {
U8 device; //硬件接口類型
U8 rate; //串口通訊波特
U8 check; //串口通訊校驗
}sSYSPARAM;
系統(tǒng)除了對sSYSPARAM 系統(tǒng)參數(shù)進行結構體定義之外,也對sCOMM 串口參數(shù)和sDBF 數(shù)據(jù)庫參數(shù)做了相應的定義; 應用DbfFieldCount 獲取數(shù)據(jù)庫的字段個數(shù)。返回大于等于0 表示獲取成功,也即指定數(shù)據(jù)庫的字段個數(shù);小于0 表示錯誤。DbfFieldGet 函數(shù)獲取當前記錄指定字段的數(shù)據(jù)內容。返回OK 表示獲取成功;小于0 表示錯誤。field變量是要獲取內容的字段號,0 代表數(shù)據(jù)庫的第1 個字段。數(shù)組data 存放字段內容的buffer。pParamDBF 是已打開數(shù)據(jù)庫的指針。data 數(shù)組中的字符串內容隨著字段序號循環(huán)不斷地變化更新,需要調用函數(shù)Lib_atoi 將字符串轉換為整數(shù)進行后續(xù)判斷和處理,具體的實現(xiàn)方式如下所示[3]。
int field,fieldcount; //字段數(shù)量
char data[100]; //保存數(shù)據(jù)的數(shù)組
fieldcount=DbfFieldCount(pParamDBF);
for(field=0;field DbfFieldGet(field,data,pParamDBF); switch(field){ case 0: Sysparam.device=Lib_atoi(data); break; case 1: Sysparam.rate=Lib_atoi(data); break; case 2: Sysparam.check=Lib_atoi(data);break; } } 上述的配置參數(shù)設置以后需要進行保存,以避免操作者下次使用需要重新設置的麻煩。壓力記錄儀的操作方式有觸屏操作和機械按鍵,兩種交互方式都可以實現(xiàn)配置參數(shù)的保存。數(shù)據(jù)庫函數(shù)DbfGotoRecord 可以定位到數(shù)據(jù)庫的某一條記錄。返回DBF_OPER_OK 表示成功,其它值表示失敗(小于0)。其中,第1 個參數(shù)record 是記錄位置,0代表第1 條數(shù)據(jù)庫記錄;第2 個參數(shù)dbf 是已打開數(shù)據(jù)庫的指針。首先,將數(shù)據(jù)庫定位在初始記錄的位置;然后,用Lib_sprintf 函數(shù)將各種數(shù)據(jù)類型的數(shù)據(jù)格式化后輸出到data 字符串中;最后,調用DbfFieldSet 函數(shù)設置當前記錄指定字段的數(shù)據(jù)內容。如下述代碼將不同控件的當前的顯示內容保存至數(shù)據(jù)庫0 和1 的字段中[4]。 WM_HWIN hObj; //定義句柄 char data[20]; //定義數(shù)據(jù)數(shù)組 DbfGotoRecord(0,pParamDBF); //定位數(shù)據(jù)庫記錄 hObj = WM_GetDialogItem(hDlg, GUI_ID_DROPDOWN0); Lib_sprintf(data,"%d",GetSel(hObj)); //格式化 DbfFieldSet(0,data,pParamDBF); //保存字段數(shù)據(jù) hObj = WM_GetDialogItem(hDlg, GUI_ID_DROPDOWN1); Lib_sprintf(data,"%d", GetSel(hObj)); //格式化 DbfFieldSet(1,data,pParamDBF); //保存字段數(shù)據(jù) DbfOpen 函數(shù)打開1 個數(shù)據(jù)庫。當成功打開后,當前記錄置于第1 條記錄(記錄號為0)。第1 個參數(shù)為數(shù)據(jù)庫名;第2 個參數(shù)用于存放打開數(shù)據(jù)庫的指針。操作時需先聲明DBF 結構并傳遞其地址進來,后續(xù)的數(shù)據(jù)庫操作也調用此指針。如果打開數(shù)據(jù)庫異常,則應用DbfCreate 函數(shù)創(chuàng)建給定的名字和字段信息的數(shù)據(jù)庫dbf 文件。保證數(shù)據(jù)庫存在的前提下DbfRecordAppend 函數(shù)在打開的數(shù)據(jù)庫后面新增1 條記錄,并切換記錄位置到新增的記錄。DbfFieldSet函數(shù)是設置當前記錄指定字段的數(shù)據(jù)內容[5]。第1 個參數(shù)是要設置內容的字段號,0 代表數(shù)據(jù)庫的第1 個字段。第2個參數(shù)代表存放字段內容的buffer;第3 個參數(shù)代表已打開數(shù)據(jù)庫的指針,如下述代碼所示在pParamDBF 數(shù)據(jù)庫的0、1、2 和3 字段內分別寫入0、3、0 和1。 pBaseDBF=&BaseDBF; //初始化 pParamDBF=&ParamDBF; //初始化 if(DbfOpen("param.dbf",&ParamDBF)!=0){ DbfCreate("param.dbf",7,(S8**)fieldname,fiel dsize); DbfOpen("param.dbf",&ParamDBF); DbfRecordAppend(pParamDBF); DbfFieldSet(0,"0",pParamDBF); DbfFieldSet(1,"3",pParamDBF); DbfFieldSet(2,"0",pParamDBF); DbfFieldSet(3,"1",pParamDBF); } 壓力記錄儀需要通過串口(RS232、RS485 或MBUS)采集連接設備的實時數(shù)據(jù)值,在協(xié)議處理的過程中需要調用數(shù)據(jù)轉換函數(shù)Ascii2Hex(S8 *O_data, U8 *N_data, int len) 和Hex2Ascii(U8 *O_data, S8 *N_data, int len) 以 實現(xiàn)HEX 和ASCII 字符的自由轉換,并調用和校驗函數(shù)CheckPackageSum(U8* data)對數(shù)據(jù)完整性進行判斷。而除了通訊采集功能之外,保證設備的加密運行也是關鍵的儀表功能。ProgramLock 函數(shù)用于加密程序,用戶利用該函數(shù)控制程序可以在某一個或者某一類機器上運行,如果不符合要求,程序將不執(zhí)行,系統(tǒng)將自動重啟。第1 個參數(shù)為程序密碼,可以通過通信軟件設置在機器里面,這樣程序可以運行在一批相同程序密碼的機器。為 NULL 空時不檢測,密碼最多30 個字符。通信管理器→系統(tǒng)菜單→切換到管理模式→參數(shù)設定→設置機器密碼下拉選擇“運行指定程序密碼”→輸入密碼→點擊“設置程序密碼”。第2 個參數(shù)如果不為NULL,則必須運行在指定的機器。不為NULL且參數(shù)不對時,屏幕會給出機器編碼,填入后重新編譯生成程序[6,7]。 int main(void){ U8 key; LcdClear(); ProgramLock("12345",NULL); while(1){ LcdPutString("Hello......",0,16); key = KeyWait(); if(key == KEY_ESC) break; } return 0; } 壓力記錄儀的屏幕截圖功能,需要進行截圖按鍵功能關聯(lián)和液晶顯示。LcdPutString 在當前位置顯示字符串。第1 個參數(shù)是要顯示的字符串;第2 個參數(shù)是顯示模式(0 反顯,1 正常,2 嵌入并反顯,3 嵌入并正常顯示);第3 個參數(shù)是字體大小,可選16、12、8 等大小。 void Bmp24Bit(void){ S8 name[32]; memset(name,0,sizeof(name)); RtcGetTimeString(name); name[2]='_'; name[5]='_'; strcat(name,".bmp"); LcdSaveToBmp24Bit(name); //以當前時間為文件名,保存當前顯示屏 } RtcGetTimeStrin 獲取時間字符串,返回的時間格式為“13:08:08”,SetKeyFuntion 函數(shù)是設置F1,F(xiàn)2,F(xiàn)n 按下后默認調用的函數(shù)。F1 系統(tǒng)默認為鍵盤背光功能,F(xiàn)2 默認為液晶背光調節(jié)功能,F(xiàn)n 在EDIT,MULTIEDIT 控件在獲取焦點時,按下默認調用中文輸入功能,但是操作者可以針對性調整上述按鍵對應的函數(shù)功能,如下述代碼所示將F1 鍵值設置為Bmp24Bit()截圖函數(shù)[8]。 int main( void ){ 圖1 電池電量手繪效果圖Fig.1 Hand-drawn renderings of battery power int count=0; LcdClear(); LcdPutString("截圖功能,按F1 截圖",1,16); SetKeyFuntion(Bmp24Bit,GUI_KEY_F1); while(KeyWait()!=KEY_ESC) { LcdMoveto(0,20); LcdPrintf(1,16,"按鍵次數(shù):%d",++count); } } 壓力記錄儀具有220V 交流供電和直流電池供電,交流供電時電量指示為滿格狀態(tài),直流電池供電時根據(jù)電路ADC 測量的電壓值顯示不同的電量狀態(tài)。將電池電壓值分為6 個檔位,分別對應6 個數(shù)組并對數(shù)組顯示效果做如圖1 所示的設置,acFontBatter_16_0 為剩余電池電量最低值,acFontBatter_16_5 為電量最高值,中間的_1、_2、_3 和_4分別對應不同的電池電量效果,如下所示: const GUI_CHARINFO GUI_FontBatter_16_CharInfo[] = { { 16, 16, 2, (void GUI_CONST_STORAGE *)&acFontBatter_16_0},/*0*/ { 16, 16, 2, (void GUI_CONST_STORAGE *)&acFontBatter_16_1},/*1*/ { 16, 16, 2, (void GUI_CONST_STORAGE *)&acFontBatter_16_2},/*2*/ { 16, 16, 2, (void GUI_CONST_STORAGE *)&acFontBatter_16_3},/*3*/ { 16, 16, 2, (void GUI_CONST_STORAGE *)&acFontBatter_16_4},/*4*/ { 16, 16, 2, (void GUI_CONST_STORAGE *)&acFontBatter_16_5},/*5*/ }; 在獲取窗體上控件的句柄后,根據(jù)實測的電池電壓值顯示不同的數(shù)組圖形,以得到刷新電池電量的效果。 本文闡述了應用emwin 平臺實現(xiàn)壓力記錄儀的研發(fā)過程。壓力記錄儀可以實現(xiàn)數(shù)據(jù)庫記錄保存,可執(zhí)行程序加密,屏幕截圖和電池電量動態(tài)顯示等功能,且具備較好的人機交互效果。經測試,壓力記錄儀可以穩(wěn)定高效地實現(xiàn)壓力儀表或壓力傳感器的數(shù)據(jù)采集和參數(shù)設置,達到了預期的設計效果。1.2 數(shù)據(jù)保存
2 通訊與加密
3 屏幕截圖
4 電池電量
5 結論