基于MAXQ3120微控制器的電表(EM)參考設(shè)計(jì)
MAXQ3120電表(EM)參考設(shè)計(jì)構(gòu)建了一款多功能、多費(fèi)率電表,它符合世界范圍的全部可用標(biāo)準(zhǔn)。參考設(shè)計(jì)構(gòu)成了一款能夠適合各地要求和各種性能要求的電表原型。這篇文檔將指導(dǎo)軟件工程師,通過(guò)定制代碼實(shí)現(xiàn)一些特殊的需求。
目標(biāo)讀者
本文檔假定讀者熟悉C語(yǔ)言、MAXQ20微控制器架構(gòu)以及匯編語(yǔ)言。讀者也需熟知全電子式電表的基理。
工具
電表參考設(shè)計(jì)采用IAR Embedded Workbench工具進(jìn)行編譯。為便于將軟件移植到其它開(kāi)發(fā)環(huán)境中,除了一種例外情況外,整個(gè)軟件避免了與IAR相關(guān)的語(yǔ)言特性。這種例外情況位于匯編語(yǔ)言文件中,其中包括了一些對(duì)標(biāo)準(zhǔn)匯編偽指令集的特定IAR擴(kuò)展。這些特定IAR擴(kuò)展命令,不僅可告知連接器各不同段的分配情況,而且告知調(diào)試器有關(guān)某些機(jī)器資源的變化情況。在其它開(kāi)發(fā)環(huán)境下構(gòu)建工程,可將這些偽指令去除。
高層硬件描述
硬件的核心器件是MAXQ3120微控制器。MAXQ3120幾乎囊括了實(shí)現(xiàn)多功能、多費(fèi)率電表所需要的所有功能,這些功能包括:雙通道、高精度A/D轉(zhuǎn)換器(ADC),一個(gè)乘法累加器(MAC),通信端口和一個(gè)顯示控制器。完成一個(gè)電表設(shè)計(jì),僅需要少量的外部元件。
在參考設(shè)計(jì)中,提供兩個(gè)通信通道:一路紅外通道,包含一個(gè)可解碼38kHz載波頻率的接收模塊和一個(gè)直接由微控制器驅(qū)動(dòng)的紅外LED,一路完全隔離的RS-485通道;用作非易失存儲(chǔ)器的128kb I2C EEPROM;一個(gè)可視LED和一路隔離光耦通道,用于指示電表脈沖;一個(gè)用于設(shè)置網(wǎng)絡(luò)地址的按鈕;和一個(gè)用于顯示的LCD。
這種硬件構(gòu)成預(yù)示著以下一些應(yīng)用信息。選擇一個(gè)外置I2C EEPROM,意味著系統(tǒng)中必須包含I2C軟件,而不提供硬件I2C主機(jī)。電表脈沖硬件意味著軟件必須能夠產(chǎn)生極為精確的脈沖定時(shí)。兩路通信端口表明,微控制器有限的資源要被兩路通道所共享。
軟件系統(tǒng)綜述
軟件系統(tǒng)必須同時(shí)跟蹤多個(gè)進(jìn)程。首先也是最重要的一點(diǎn),軟件系統(tǒng)必須監(jiān)測(cè)ADC,計(jì)算用電量并報(bào)告其它額外信息,這些信息包括RMS電壓和電流、功率因數(shù)和峰值功率。這個(gè)基本進(jìn)程非常關(guān)鍵,其它任何進(jìn)程都不能干擾這個(gè)最重要的基礎(chǔ)任務(wù)。在持續(xù)監(jiān)視用電量的同時(shí),軟件還必須驅(qū)動(dòng)顯示、監(jiān)視兩路通信端口、監(jiān)視按鈕以及電力線路上的電源失效事件,完成從外部EEPROM獲取信息的請(qǐng)求,并跟蹤費(fèi)率時(shí)段的變化。
任務(wù)管理方式
初始一看,要完成以上多個(gè)實(shí)時(shí)任務(wù),迫切需要某種實(shí)時(shí)操作系統(tǒng)(RTOS)來(lái)進(jìn)行調(diào)度管理和資源分配。但進(jìn)一步分析后,就會(huì)發(fā)現(xiàn)不用傳統(tǒng)RTOS的兩個(gè)充分理由。
首先,要求即時(shí)響應(yīng)ADC中斷。當(dāng)ADC有可用的采樣數(shù)據(jù)時(shí),必須在48μs內(nèi)提取該采樣數(shù)據(jù)。并且,當(dāng)檢測(cè)到一個(gè)過(guò)零點(diǎn)時(shí),電源周期處理程序?yàn)榱嗽谙乱粋€(gè)電源周期之前完成執(zhí)行操作,必須獨(dú)占CPU資源。(電源周期處理程序?qū)⒄加肅PU運(yùn)算能力的25%到30%。) 盡管RTOS可以滿足這些要求,卻不能最有效地利用資源。
其次,用于保存任務(wù)上下文的空間非常有限。大多數(shù)RTOS都要給每個(gè)任務(wù)提供一個(gè)完整的虛擬處理器,以在其中執(zhí)行操作,而這需要保存各個(gè)任務(wù)的上下文。由于僅有256個(gè)16位字RAM可供使用,少量任務(wù)就會(huì)耗盡存儲(chǔ)器空間。
所以,本參考設(shè)計(jì)選擇了一個(gè)簡(jiǎn)單的任務(wù)輪。在這種配置方式下,任務(wù)會(huì)被按順序調(diào)用,而每個(gè)任務(wù)在鎖定事件發(fā)生時(shí),都要釋放CPU的控制權(quán)。鎖定事件是指所有其它任務(wù)都必須等待的事件,它包括:從EEPROM中提取數(shù)據(jù),等待一個(gè)電源周期或是等待通信通道上的字符。如果當(dāng)前任務(wù)需要等待其它任務(wù)完成時(shí)才能結(jié)束自身任務(wù),這時(shí)也會(huì)產(chǎn)生一個(gè)鎖定事件。在任何鎖定事件中,任務(wù)必須存儲(chǔ)它的當(dāng)前狀態(tài)并返回任務(wù)輪。這種協(xié)作式多任務(wù)機(jī)制,使得一個(gè)處理能力相對(duì)低些的控制器就能夠勝任工作。
任務(wù)間的通信是通過(guò)一組公共數(shù)據(jù)結(jié)構(gòu)來(lái)完成的,這些數(shù)據(jù)結(jié)構(gòu)要根據(jù)一套嚴(yán)格的規(guī)則才允許被修改。這些數(shù)據(jù)結(jié)構(gòu)中最重要的部分是消息板,當(dāng)發(fā)生某個(gè)事件時(shí),一個(gè)任務(wù)要設(shè)置消息板中的一組數(shù)據(jù)位以通知另一個(gè)任務(wù)。例如,假設(shè)接收到一個(gè)消息并將其正確譯碼,則消息譯碼器任務(wù)會(huì)告知另一個(gè)需要該消息的任務(wù)(比如寄存器管理器)已經(jīng)收到了消息,并要求第二個(gè)任務(wù)必須執(zhí)行某些操作。
缺省任務(wù)列表
以下是參考設(shè)計(jì)中采用的缺省任務(wù)列表:
DSP:對(duì)應(yīng)每個(gè)電源周期,這個(gè)程序會(huì)計(jì)算電力線路的所有參數(shù),并累加本電源周期的用電量。
串口驅(qū)動(dòng)器:檢測(cè)兩路通信通道的狀態(tài),并將第一個(gè)發(fā)出字符的通道置為“活動(dòng)”通道。在消息檢查器任務(wù)確定消息完成或產(chǎn)生超時(shí)之前,通道將始終保持活動(dòng)狀態(tài)。
消息檢查器:驗(yàn)證輸入字符串符合協(xié)議規(guī)范,并在完整接收消息后通知消息譯碼器。
消息譯碼器:解釋接受到的消息并執(zhí)行相應(yīng)的請(qǐng)求操作。
異步事件管理器:執(zhí)行那些不是按照時(shí)間表進(jìn)行的事件任務(wù),比如峰值檢測(cè)和電能累計(jì)。
時(shí)段表管理器:周期性檢查時(shí)鐘,并按照時(shí)段表調(diào)整費(fèi)率寄存器的值。
顯示管理器:根據(jù)時(shí)間和其它事件刷新LCD顯示。
消息格式器:為消息譯碼器解釋的消息準(zhǔn)備回復(fù)信息。
消息構(gòu)建器:接收格式化后的消息并加上用于傳輸?shù)南㈩^和消息尾。
寄存器管理器:執(zhí)行讀/寫EEPROM操作。
計(jì)時(shí)管理器:通告按固定時(shí)基啟動(dòng)的任務(wù)。
負(fù)載曲線記錄器:被請(qǐng)求時(shí),向EEPROM記入用電量,便于將來(lái)報(bào)告這些數(shù)據(jù)。
添加任務(wù)
如電表參考設(shè)計(jì)中所定義,任務(wù)是一段單線程代碼,它執(zhí)行電表要求的某項(xiàng)功能,并快速(通常只有幾毫秒)返回調(diào)用函數(shù)。然而,大多數(shù)任務(wù)都需要比這更長(zhǎng)的時(shí)間才能完成。比如,在任何合理的速率下發(fā)送一個(gè)消息都需要多個(gè)周期。因此,大多數(shù)任務(wù)都需要一個(gè)狀態(tài)變量,以便將其分解為數(shù)個(gè)子任務(wù)。
一旦任務(wù)編寫完成,你就可以在spintaskwheel.c文件的任務(wù)列表中加入該調(diào)用。注意,你可以將任務(wù)加在執(zhí)行流程的任何位置,并根據(jù)你的需要多次頻繁調(diào)用它。你將發(fā)現(xiàn),DSP任務(wù)調(diào)用非常頻繁,串口驅(qū)動(dòng)器SerialPortDriver任務(wù)也被調(diào)用了幾次。因?yàn)橐3蛛娔軠y(cè)量的完整性,DSP任務(wù)不允許被擱置數(shù)個(gè)周期,同時(shí)不允許SerialPortDriver任務(wù)錯(cuò)過(guò)輸入字符。
最后,測(cè)試你的代碼。任務(wù)輪循環(huán)時(shí),你的新任務(wù)將伴隨其它任務(wù)被調(diào)用。
全局變量
由于未使用真正意義上的多任務(wù)操作系統(tǒng),也就意味著不會(huì)有編程人員所熟知的、真正意義上的消息傳遞、信號(hào)量或其它機(jī)制。通信是通過(guò)上文提到的消息板以及一組全局變量實(shí)現(xiàn)的,各個(gè)任務(wù)必須按照嚴(yán)格的規(guī)則來(lái)設(shè)置和讀取這些變量信息。這些全局變量列舉如下:
g_CommSystEMState: 這個(gè)變量包括一組通信通道控制位。具體來(lái)說(shuō),每個(gè)通道包括:一個(gè)active (活動(dòng))位,用于指明某個(gè)特定通道處于活動(dòng)狀態(tài)(從而可丟棄到達(dá)另一個(gè)通道的字符);一個(gè)TBE位,用于使閑置通道做好工作準(zhǔn)備;以及一個(gè)data loss (數(shù)據(jù)丟失)位,當(dāng)閑置通道收到字符而另一通道正忙于通信時(shí),該位被置高。
g_TransmitByte; g_ReceiveByte: 分別保存著下一個(gè)要傳送的字節(jié)和最新接收到的字節(jié)。
g_CommBuffer: 一個(gè)50字節(jié)數(shù)組,包含剛接收到的消息或要發(fā)送的消息。注意系統(tǒng)僅有一個(gè)通信緩存。它不僅被兩個(gè)通信通道所共享,也被發(fā)送和接收通道所共享。
g_MeterAddress: 一個(gè)包含電表網(wǎng)絡(luò)地址的6字節(jié)數(shù)組。初始化時(shí)從EEPROM內(nèi)讀取該信息,并存放在RAM中。
g_MessageFormatterData; g_DispFormatterData; g_ScheduleManagerData; g_AEMData; g_LCLRegData: 這些寄存器在寄存器管理器和各種任務(wù)間傳送數(shù)據(jù)。例如,一個(gè)需要發(fā)送的寄存器內(nèi)容,會(huì)被寄存器管理器放入g_MessageFormatterData中。
g_AEMRegisterNeeded; g_DispFormatterRegRequest; g_RequestScheduleManager; g_LCLRegRequest: 這些寄存器里,包含了特定任務(wù)需要讀或?qū)懙募拇嫫?。注意,消息譯碼器沒(méi)有全局地址寄存器:寄存器管理器可以智能地從消息緩存中找出這個(gè)信息。
g_LCDMode: 包含顯示器的模式字節(jié)。見(jiàn)下面的顯示定制部分。
g_TariffInEffect: 包含當(dāng)前有效的費(fèi)率號(hào)碼。這個(gè)函數(shù)有自己的全局變量,以便每次累計(jì)電能時(shí),無(wú)需通過(guò)多次EEPROM讀操作來(lái)確定將采樣值存在什么位置。
評(píng)論