靖衛(wèi)兵 紀(jì)松波
摘 要:隨著科技的迅速發(fā)展,精密用電設(shè)備也越來越多,它們對電流、電壓、功率等基本參數(shù)要求較高。為了完整地反映用電設(shè)備的運(yùn)行狀態(tài),需要對多個(gè)用電參數(shù)進(jìn)行采集。在Linux操作系統(tǒng)開發(fā)環(huán)境下,通過分析智能電表使用的通信協(xié)議Dl645-1997,編寫串口驅(qū)動,使用RS-485接口與智能電表通信,最后通過編寫、移植QT應(yīng)用程序,完成對電量、電流、電壓和功率的采集和精確顯示。該系統(tǒng)能夠?qū)崟r(shí)采集用電器的用電參數(shù),為其安全運(yùn)行提供保障,也為今后工業(yè)電量數(shù)據(jù)采集和遠(yuǎn)程傳輸提供參考,具有良好的應(yīng)用前景。
關(guān)鍵詞:智能電表;嵌入式Linux;通信協(xié)議;Qt移植
DOI:10.11907/rjdk.172440
中圖分類號:TP319 文獻(xiàn)標(biāo)識碼:A 文章編號:1672-7800(2017)009-0158-03
Abstract:With the rapid development of science and technology, precision electrical equipment is also increasing, they are the current, voltage, power and other basic parameters require a higher. In order to be able to complete the operation of the electrical equipment, the need for multiple electrical parameters to be collected. In this paper, the Linux operating system development environment, through the analysis of smart meters using the communication protocol Dl645-1997, the preparation of serial port driver, the use of RS-485 interface and smart meter communication, and finally through the preparation, transplantation QT application to complete the power, Voltage, and power acquisition and accurate display. This system can collect the electrical parameters of the electrical appliance in real time, provide security for its safe operation, and provide reference for the later industrial data acquisition and remote transmission, and has high application prospect.
Key Words:smart meter; embedded linux; communication protocol; Qt transplant
0 引言
我國經(jīng)濟(jì)的快速發(fā)展帶動了各行業(yè)對電能的大量需求,因而迫切需要對電能供應(yīng)進(jìn)行科學(xué)管理。與此同時(shí),越來越多的智能電表在生產(chǎn)生活中得到廣泛應(yīng)用,通過讀取智能電表中的電量、電流、電壓和功率,從而監(jiān)測用電設(shè)備的運(yùn)行狀態(tài),為用電設(shè)備的安全運(yùn)行提供安全保障。Dl645-1997協(xié)議成為國際智能電表普遍采用的一種主流通信協(xié)議,只是采集用電量作為電費(fèi)征收依據(jù)的傳統(tǒng)方式很難滿足工業(yè)實(shí)際中電力系統(tǒng)采集數(shù)據(jù)的全面性、可靠性方面的需要[1]。本文基于中華人民共和國電力行業(yè)標(biāo)準(zhǔn)Dl645-1997多功能電表通信規(guī)約,提出了一種基于Tiny4412為核心處理器的嵌入式智能電表數(shù)據(jù)采集的設(shè)計(jì)方案和實(shí)現(xiàn)方法。利用RS-485接口并結(jié)合智能電表通信規(guī)約,使用智能電表完成智能電表數(shù)據(jù)的采集。通過移植Qt完成電表數(shù)據(jù)采集工作。
1 Dl645-1997通信協(xié)議
Dl645-1997協(xié)議是中華人民共和國電力行業(yè)標(biāo)準(zhǔn)關(guān)于多功能電表的通信規(guī)約,制定該標(biāo)準(zhǔn)是為了統(tǒng)一和規(guī)范多功能電能表與數(shù)據(jù)終端設(shè)備進(jìn)行數(shù)據(jù)交換時(shí)的物理連接和協(xié)議。采用一對多的主從工作方式,主機(jī)至少可以與一臺從機(jī)通信,而從機(jī)的地址必須唯一[2]。
1.1 字節(jié)格式
該協(xié)議的每字節(jié)含8位二進(jìn)制碼,傳輸時(shí)加上一個(gè)起始位(0)表示傳輸方向、一個(gè)偶校驗(yàn)位P和一個(gè)停止位(1)共11位。D0是字節(jié)的最低有效位,D7是字節(jié)的最高有效位,字節(jié)格式如圖1所示。
1.2 幀格式
幀是傳輸信息的基本單位,讀取智能電表的信息時(shí),主機(jī)必須按照此幀格式給電表發(fā)送數(shù)據(jù),電表在收到正確的主機(jī)數(shù)據(jù)幀時(shí),會查看主機(jī)幀格式中的地址會否與本地址相符合,只有兩個(gè)地址一致時(shí),電表才會將正確的電表數(shù)據(jù)回傳給主機(jī)[3]。幀格式如表1所示。
BCD碼:地址長度為12位十進(jìn)制數(shù),低地址位在先,高地址位在后??刂拼a的格式如圖2所示,其中D7=0時(shí)表示由主站發(fā)出的命令幀,D7=1:由從站發(fā)出的應(yīng)答幀;D6=0:從站正確應(yīng)答,D6=1:從站對異常信息的應(yīng)答;D5=0:無后續(xù)數(shù)據(jù)幀;D5=1:有后續(xù)數(shù)據(jù)幀;D4-D0:請求及應(yīng)答功能碼,當(dāng)其為00001表示讀數(shù)據(jù),00010時(shí)表示讀后續(xù)數(shù)據(jù),00011時(shí)重讀數(shù),00100為寫數(shù)據(jù),01010:寫設(shè)備地址,01100:更改通信速率??刂拼a決定是向電表讀數(shù)據(jù)還是寫數(shù)據(jù),既能夠讀電表中的各種數(shù)據(jù),也能寫數(shù)據(jù)改變設(shè)備的地址和通信波特率。endprint
數(shù)據(jù)長度表示數(shù)據(jù)域的字節(jié)數(shù)。數(shù)據(jù)域DATA:數(shù)據(jù)域包括數(shù)據(jù)標(biāo)識和數(shù)據(jù)、密碼等,其結(jié)構(gòu)隨控制碼的功能而改變。其中,數(shù)據(jù)標(biāo)示指電表裝置中各種不同類型、不同屬性的數(shù)據(jù)。該協(xié)議使用2個(gè)字節(jié)的4個(gè)字段分別標(biāo)示數(shù)據(jù)的類型和屬性。這2個(gè)字節(jié)為DI1和DI0,4個(gè)字段分別為DI1H、DI1L、DI0H、DI0L,其中DI0L為最低級標(biāo)識字段,DI1H為最高級標(biāo)識段,如圖3所示。當(dāng)DI1H為1001,DI1L為0000時(shí),表示為當(dāng)前有功電能量,DI0H為0001,DI0L為0000時(shí),表示正向總電能。如果要讀取電表的正向有功總電能,數(shù)據(jù)域data從高到低位為1001 0000 0001 0000。其它類型的數(shù)據(jù)域data類似,
可參考協(xié)議附錄A。傳輸時(shí)發(fā)送方按字節(jié)進(jìn)行加33H處理,接收方按字節(jié)進(jìn)行減33H處理且所有數(shù)據(jù)項(xiàng)均先傳送低位字節(jié),后傳送高位字節(jié)。
校驗(yàn)碼CS:從幀起始符開始到校驗(yàn)碼之前的所有各字節(jié)的模256的和,即各字節(jié)二進(jìn)制算術(shù)和,不計(jì)超過256的溢出值。結(jié)束符號16H:標(biāo)識一幀信息的結(jié)束,其值為16H=00010110B。
1.3 主機(jī)請求幀
當(dāng)主機(jī)需要讀取數(shù)據(jù)時(shí)需要按照表1幀格式發(fā)送給電表。例如若要讀取電表的正向總電能,通過上述分析可知,需要向電表發(fā)送0x68,0x11,0x11,0x11,0x11,0x11,0x11,0x68,0x1,0x2,0x43,0xc3,0xd9,0x16。其中,0x68和0x16分別是幀頭和幀尾,0x11,0x11,0x11,0x11,0x11,0x11是為了方便自己提前設(shè)置的設(shè)備地址。0x1是控制碼表示由主站發(fā)出的命令幀,0x2表示數(shù)據(jù)域有兩個(gè)字節(jié),數(shù)據(jù)域data為1001000000010000B,數(shù)據(jù)域需要經(jīng)過加33H處理,且數(shù)據(jù)傳輸先低位再高位。校驗(yàn)碼是各字節(jié)之和的后8位即oxd9。讀取電表其它數(shù)據(jù)也類似,只是控制碼、數(shù)據(jù)域data和校驗(yàn)碼不同。
1.4 從機(jī)應(yīng)答幀
電表收到主機(jī)發(fā)的請求幀后,會給主機(jī)返回一個(gè)應(yīng)答幀。應(yīng)答幀的幀格式與主機(jī)的請求幀很類似。讀取數(shù)據(jù)的數(shù)據(jù)域后,數(shù)據(jù)也經(jīng)過加33H自動處理,且先接收低位數(shù)據(jù)。
2 系統(tǒng)結(jié)構(gòu)
2.1 Linux操作系統(tǒng)
Linux是一套免費(fèi)使用和自由傳播的類Unix操作系統(tǒng),是一個(gè)基于POSIX和UNIX的多用戶、多任務(wù)、支持多線程和多CPU的操作系統(tǒng)。它能運(yùn)行主要的Unix工具軟件、應(yīng)用程序和網(wǎng)絡(luò)協(xié)議。Linux繼承了Unix以網(wǎng)絡(luò)為核心的設(shè)計(jì)思想,是一個(gè)性能穩(wěn)定的多用戶網(wǎng)絡(luò)操作系統(tǒng)。Linux可以運(yùn)行在多種硬件平臺上,如具有X86、SPARC、Alpha等處理器的平臺。此外,Linux還是一種嵌入式操作系統(tǒng),可以運(yùn)行在平板電腦、機(jī)頂盒或游戲機(jī)上。Linux內(nèi)核是Linux系統(tǒng)的核心程序,主要完成任務(wù)調(diào)度、內(nèi)存管理、IO設(shè)備管理等功能[5],主要為應(yīng)用程序提供一個(gè)穩(wěn)定良好的運(yùn)行環(huán)境。應(yīng)用程序是為方便用戶操作而提供的程序,驅(qū)動程序?qū)崿F(xiàn)了操作系統(tǒng)對硬件的有效管理,應(yīng)用程序?qū)崿F(xiàn)了方便用戶操作的目的。
2.2 串口驅(qū)動
在認(rèn)識串口驅(qū)動之前必須先了解Linux tty子系統(tǒng)。Linux tty子系統(tǒng)包含tty核心、tty線路規(guī)程和tty驅(qū)動。tty核心是對整個(gè)tty設(shè)備的抽象,對用戶提供統(tǒng)一的接口,tty線路規(guī)程是對傳輸數(shù)據(jù)的格式化,tty驅(qū)動則是面向tty設(shè)備的硬件驅(qū)動[6],在此即是串口驅(qū)動。當(dāng)用戶使用write()函數(shù)向串口發(fā)送數(shù)據(jù)時(shí),write函數(shù)會通過系統(tǒng)調(diào)用來找到file_operations里的.write函數(shù)指針,其中tty_write()函數(shù)與.write指針相對應(yīng)。ttt_write()函數(shù)又會找到線路規(guī)程中的tty_ldisc_ops,并調(diào)用其中的n_tty_write()函數(shù)。n_tty_write()函數(shù)又會引用tty_operation結(jié)構(gòu)中的uart_write()函數(shù)。uart_write()函數(shù)最終找到串口驅(qū)動里的write()函數(shù),最終將數(shù)據(jù)發(fā)送給硬件設(shè)備。當(dāng)應(yīng)用程序讀串口時(shí),首先響應(yīng)tty核心中的tty_read()函數(shù),然后在該函數(shù)中調(diào)用線路規(guī)程中的n_tty_read()函數(shù),該函數(shù)不會繼續(xù)調(diào)用其它函數(shù),首先會設(shè)置應(yīng)用程序?yàn)樽枞麪顟B(tài)[7],如果沒有數(shù)據(jù)可讀,則通過調(diào)度讓阻塞生效。如果有數(shù)據(jù)可讀,在線路規(guī)程read_buffer()函數(shù)中將數(shù)據(jù)讀走,read_buffer()函數(shù)中的數(shù)據(jù)來源于串口驅(qū)動,串口驅(qū)動接受到硬件的數(shù)據(jù)后,就會送到線路規(guī)程中的read_buffer()函數(shù)中去,當(dāng)應(yīng)用程序需要讀數(shù)據(jù)時(shí),只需在read_buffer()函數(shù)中讀取即可。串口驅(qū)動接收數(shù)據(jù)的途徑為:串口驅(qū)動通過注冊接受中斷,然后讀取UFCON和UFSTAT兩個(gè)寄存器中的數(shù)據(jù),通過UFSTAT寄存器可以判斷RxFIFO中數(shù)據(jù)量的大小,如果為0,退出中斷處理,若非0則在URXH寄存器中取出接受到的數(shù)據(jù),然后通過調(diào)用uart_insert_char()函數(shù)將數(shù)據(jù)存放到串口驅(qū)動中的buf中[8],數(shù)據(jù)接受完畢后,再調(diào)用tty_filp_buffer_push函數(shù)將串口驅(qū)動接受到的數(shù)據(jù)送到線路規(guī)程中的read_buf中,讀串口數(shù)據(jù)完畢。讀寫過程如圖4所示。
3 Qt移植
Qt是一個(gè)跨平臺的C++應(yīng)用程序開發(fā)框架,廣泛應(yīng)用于GUI程序。Qt中所有類型的GUI組件如按鈕、標(biāo)簽等都派生于QWiget。Qt利用信號與槽機(jī)制代替?zhèn)鹘y(tǒng)的Callback來進(jìn)行對象之間的溝通。當(dāng)操作事件發(fā)生時(shí),對象會發(fā)出一個(gè)信號,而槽則是一個(gè)函數(shù)接受一個(gè)特定的信號并且運(yùn)行槽本身而設(shè)置的動作。信號與槽之間通過Qobject的靜態(tài)方法connect來鏈接[9]。在Qt中沒有特定的串口控制類,該項(xiàng)目中使用第三方的QextSerialPort類通過添加posix_qextserialport.h、qextserialbase.h及posix_qextserialport.cpp、qextserialbase.cpp實(shí)現(xiàn)電表的串口數(shù)據(jù)傳輸[10]。在界面文件widget.ui中,添加PushButton和LineEdit控件向串口中發(fā)送要讀取數(shù)據(jù)的命令和顯示數(shù)據(jù)。在讀寫串口之前需要先打開串口驅(qū)動文件,然后設(shè)置波特率、數(shù)據(jù)位、停止位和校驗(yàn)位。當(dāng)PushButton被按下后,會將不同的讀命令送到與其相關(guān)的槽函數(shù)中,在槽函數(shù)中調(diào)用寫串口函數(shù)myCom->write((char*)s,14),s是存放命令的地址,14代表命令的大小,電表收到讀命令后會返回相應(yīng)的數(shù)據(jù),Qt應(yīng)用程序利用讀串口函數(shù)QByteArray temp = myCom->readAll();QDataStream out(&temp,QIODevice::ReadWrite);接收電表返回的字符串,然后經(jīng)過數(shù)據(jù)格式轉(zhuǎn)換和數(shù)據(jù)分離后顯示在LineEdit控件中,將數(shù)據(jù)代碼調(diào)試正確后,使用qmake工具生成Makefile,然后使用make命令即可生成可執(zhí)行應(yīng)用程序myCom。將可執(zhí)行文件拷貝到開發(fā)板中,修改啟動腳本,即可開機(jī)運(yùn)行此Qt程序。endprint
4 系統(tǒng)測試
將智能電表的RS485接口和開發(fā)板的RS485相連接,智能電表接一個(gè)用電器。啟動開發(fā)板,會自動運(yùn)行移植好的Qt應(yīng)用程序,在應(yīng)用程序中設(shè)置好串口工作時(shí)的波特率、數(shù)據(jù)位、停止位等參數(shù)。點(diǎn)擊相應(yīng)的按鈕就能讀取并顯示相應(yīng)的數(shù)據(jù)。測試表明,該系統(tǒng)能夠準(zhǔn)確讀取電表中的總電能、瞬時(shí)電流、瞬時(shí)電壓和瞬時(shí)功率。
5 結(jié)語
該智能電表采集系統(tǒng)以tiny4412處理器作為硬件平臺,采用Linux技術(shù),首先分析電表使用協(xié)議,結(jié)合RS-485接口,讀取所需要的電表數(shù)據(jù),然后通過移植Qt顯示數(shù)據(jù)。經(jīng)過測試,整個(gè)系統(tǒng)具有數(shù)據(jù)準(zhǔn)確、穩(wěn)定可靠、人機(jī)界面友好等特點(diǎn),能夠很好地適用于現(xiàn)代工業(yè)需求,應(yīng)用前景十分廣闊。
參考文獻(xiàn):
[1] 王平,張新東.基于智能儀表的數(shù)據(jù)采集系統(tǒng)設(shè)計(jì)[J].自動化與儀表,2009,24(4):9-10.
[2] 樊龍,張文愛.基于Modbus協(xié)議的智能電表數(shù)據(jù)采集傳輸系統(tǒng)的實(shí)現(xiàn)[J].制造業(yè)自動化,2014(2):120-121.
[3] 耿建坡,王永輝,陶鵬,等.智能電能表檢測裝置應(yīng)用分析[J].河北電力技術(shù),2012(3):4-5.
[4] 程淼,智能電能表的主要功能及其選用[J].知識經(jīng)濟(jì),2011(4):127.
[5] 于海彬,王斌,陳興林,等.基于Linux的SC16IS752的串口驅(qū)動程序設(shè)計(jì)[J].自動化與儀表,2013(12):38-39.
[6] 宋寶華.Linux設(shè)備驅(qū)動詳解[M].北京:人民郵電出版社,2010.
[7] 于海彬,王斌,陳興林.基于Linux的SC16IS752的串口驅(qū)動程序設(shè)計(jì)[J].自動化與儀表,2013(12):36-41.
[8] 吳俊安,江澤濤,涂斌.Linux下PC機(jī)串口與智能儀器間的數(shù)據(jù)通信[J].計(jì)算機(jī)與現(xiàn)代化,2005(7):39-42.
[9] 吳燕燕,賀鋒濤.基于ARM9平臺上Qt/Eebedded的移植與開發(fā)[J].液晶與顯示,2013(12):261-263.
[10] 全威.基于Linux系統(tǒng)與Qt開發(fā)框架的虛擬儀表的顯示應(yīng)用研究[D].哈爾濱:哈爾濱理工大學(xué),2017.
(責(zé)任編輯:孫 娟)endprint