Customization Features of the MAXQ3120 Energy Meter Reference Design

Publisher:jingyanLatest update time:2015-03-13 Source: eechinaKeywords:MAXQ3120 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
The MAXQ3120 Electricity Meter (EM) reference design builds a multi-function, multi-rate electricity meter that complies with all applicable standards worldwide. The reference design forms a prototype of an electricity meter that can be adapted to local requirements and performance requirements. This document will guide the software engineer to customize the code to implement some special requirements. 

Intended Audience

This document assumes that the reader is familiar with C, the MAXQ20 microcontroller architecture, and assembly language. The reader should also be familiar with the basics of fully electronic electricity meters. 

Tools 

The electricity meter reference design is compiled using the IAR Embedded Workbench tool. With one exception, the software avoids IAR-related language features to facilitate porting to other development environments. The exception is in the assembly language files, which include some IAR-specific extensions to the standard assembly pseudo-instruction set. These special IAR extensions not only tell the linker how to allocate different sections, but also tell the debugger about changes in certain machine resources. These pseudo-instructions can be removed when building the project in other development environments. 

High-Level Hardware Description 

The core of the hardware is the MAXQ3120 microcontroller. The MAXQ3120 includes nearly all the features needed to implement a multifunction, multirate meter, including a dual-channel, high-precision A/D converter (ADC), a multiply-accumulate (MAC), communications ports, and a display controller. Only a few external components are needed to complete a meter design. 

In the reference design, two communications channels are provided: an infrared channel that includes a receiver module that can decode the 38kHz carrier frequency and an infrared LED driven directly by the microcontroller, a fully isolated RS-485 channel, a 128kb I2C EEPROM for nonvolatile memory, a visible LED and an isolated optocoupler channel to indicate meter pulses, a button for setting the network address, and an LCD for display. 

This hardware configuration implies the following application information. The choice of an external I2C EEPROM means that the system must include I2C software instead of providing a hardware I2C master. The meter pulse hardware means that the software must be able to generate extremely accurate pulse timing. The two communication ports mean that the limited resources of the microcontroller are shared between the two channels. 

Software System Overview 

The software system must keep track of multiple processes simultaneously. First and foremost, the software system must monitor the ADC, calculate power usage, and report additional information, including RMS voltage and current, power factor, and peak power. This basic process is critical, and no other process can interfere with this most important basic task. While continuously monitoring power usage, the software must also drive the display, monitor two communication ports, monitor pushbuttons and power failure events on the power line, complete requests for information from an external EEPROM, and track changes in rate periods. 

Task Management 

At first glance, the completion of these multiple real-time tasks urgently requires some kind of real-time operating system (RTOS) to manage scheduling and resource allocation. However, further analysis will reveal two good reasons not to use a traditional RTOS. 

First, the ADC interrupt requires immediate response. When the ADC has sample data available, the sample data must be extracted within 48μs. And when a zero crossing is detected, the power cycle handler must monopolize the CPU resources in order to complete execution before the next power cycle. (The power cycle handler will consume 25% to 30% of the CPU computing power.) Although an RTOS can meet these requirements, it does not use resources in the most efficient way. 

Second, there is limited space for task context. Most RTOSes give each task a full virtual processor to execute on, which requires context for each task. With only 256 16-bit words of RAM available, a small number of tasks can run out of memory. 

Therefore, a simple task wheel was chosen for this reference design. In this configuration, tasks are called sequentially, and each task must relinquish control of the CPU when a lock event occurs. A lock event is an event that all other tasks must wait for, such as fetching data from an EEPROM, waiting for a power cycle, or waiting for a character on a communication channel. A lock event is also generated if the current task needs to wait for another task to complete before it can terminate. In any lock event, the task must store its current state and return to the task wheel. This cooperative multitasking mechanism allows a relatively low-power controller to do the job. 

Communication between tasks is accomplished through a set of common data structures that are modified according to a strict set of rules. The most important of these data structures is the message board, where a task sets a set of bits to notify another task when an event occurs. For example, if a message is received and decoded correctly, the Message Decoder task will notify another task that needs the message (such as the Register Manager) that the message has been received and that the second task must perform some action. 

Default Task List 

The following is the default task list used in the reference design:  

DSP: For each power cycle, this program calculates all parameters of the power line and accumulates the power consumption of this power cycle.  

Serial port driver: Checks the status of the two communication channels and sets the channel that first sends a character as the "active" channel. The channel remains active until the message checker task determines that the message is complete or a timeout occurs. 

Message checker: Verifies that the input string conforms to the protocol specification and notifies the message decoder when the message is completely received.  

Message decoder: Interprets the received message and performs the requested action accordingly.  

Asynchronous event manager: Performs event tasks that are not scheduled, such as peak detection and energy accumulation.  

Time table manager: Periodically checks the clock and adjusts the value of the rate register according to the time table. 
Display manager: Refreshes the LCD display according to time and other events.  

Message formatter: Prepares reply information for messages interpreted by the message decoder.  

Message Builder: Receives formatted messages and adds headers and trailers for transmission.

Register Manager: Performs read/write operations on the EEPROM.  

Timing Manager: Notifies tasks to be started on a fixed time base.  

Load Profile Recorder: When requested, logs power usage to the EEPROM for future reporting.

Adding Tasks 

As defined in the Energy Meter Reference Design, a task is a single-threaded piece of code that performs a function required by the meter and returns to the calling function quickly (usually within a few milliseconds). However, most tasks take longer than this to complete. For example, sending a message at any reasonable rate requires multiple cycles. Therefore, most tasks require a state variable so that they can be broken down into subtasks. 

Once the task is written, you can add it to the task list in the spintaskwheel.c file. Note that you can add a task anywhere in the execution flow and call it as often as you like. You will notice that the DSP task is called very frequently and the SerialPortDriver task is called several times as well. To maintain the integrity of the energy measurement, the DSP task must not be stalled for several cycles, and the SerialPortDriver task must not miss input characters. 

Finally, test your code. Your new task will be called along with the other tasks as the task loops. 

Global Variables

Since a true multitasking operating system is not used, there is no real message passing, semaphores, or other mechanisms as programmers are familiar with. Communication is achieved through the message board mentioned above and a set of global variables that each task must set and read according to strict rules. These global variables are listed below:  

g_CommSystEMState: This variable contains a set of communication channel control bits. Specifically, each channel includes: an active bit to indicate that a particular channel is active (thus discarding characters arriving on another channel); a TBE bit to make the idle channel ready for work; and a data loss bit that is set high when the idle channel receives a character while another channel is busy communicating. g_TransmitByte 

; g_ReceiveByte: Hold the next byte to be transmitted and the most recently received byte, respectively. 

g_CommBuffer: A 50-byte array containing the message that has just been received or is about to be sent. Note that the system has only one communication buffer. It is shared not only by the two communication channels, but also by the send and receive channels.

g_MeterAddress: A 6-byte array containing the network address of the meter. This information is read from the EEPROM during initialization and stored in RAM.

g_MessageFormatterData; g_DispFormatterData; g_ScheduleManagerData; g_AEMData; g_LCLRegData: These registers convey data between the Register Manager and the various tasks. For example, the contents of a register that needs to be sent are placed into g_MessageFormatterData by the Register Manager.

g_AEMRegisterNeeded; g_DispFormatterRegRequest; g_RequestScheduleManager; g_LCLRegRequest: These registers contain the registers that a particular task needs to read or write. Note that the message decoder does not have a global address register: the Register Manager can intelligently find this information from the message buffer.

g_LCDMode: Contains the mode byte of the display. See the Display Customization section below.

g_TariffInEffect: Contains the currently active tariff number. This function has its own global variables so that each time the energy is accumulated, there is no need to perform multiple EEPROM read operations to determine where to store the sampled values.

g_PW: Contains the password number of each communication channel that is currently valid.

g_irTimer; g_rsTimer: Timers used to count the validity time of each channel password. Once a password is received, it is valid for 60 seconds. After the validity time of a password expires, the related 4-bit data in g_PW will be cleared.

g_LoadCurveUsage; g_LoadCurvePeak; g_LoadCurveTimeStamp: Variables related to the load curve recording task. g_LoadCurveUsage accumulates power usage and will eventually report it to the load curve recording task. The load curve recording task will 
periodically write this value to the EEPROM and then clear the variable.

g_LoadCurvePeak and g_LoadCurveTimeStamp track the maximum power value of the load curve and record the interval and time when the peak power is generated.

AEMState: Contains a group of variables related to asynchronous events. When a message to set the meter address is received, the msg_rx flag is set high. After the address setting logic is activated, the timer variable contains the number of seconds required to restore normal display. The DSPState and Register variables track the transfer of register power usage information from the DSP logic to the power usage reporting function. Typically, the register variables include all power usage types (active, reactive, positive and negative power, etc.).

g_new_baud: The DL/T 645 protocol specification provides a mechanism to change the baud rate of only a single message. When a baud rate change request is received and acknowledged, the next message is transmitted at a higher baud rate. The baud rate is then restored to its normal value (1,200 bps in this design). g_new_baud always holds the baud rate of the next message.

g_TransmitDelay: Some RS-485 converters delay a fixed time after sending the last character before switching back to receive mode. Therefore, when the host transmits a request, it may miss the first few characters sent by the meter because the RS-485 converter connected to the host serial port is still in transmit mode. This variable holds a fixed delay for the transmit state to be held, after which the host's RS-485 converter switches back to receive mode.

current_temp: If referenced, this variable will contain the most recent value read from the DS3231 RTC/temperature sensor. 

Customization

This reference design complies with DL/T 645, Multifunction, Watt-Hour Electricity Meter Communication Protocol. However, this document does more than just describe the communication protocol. DL/T 645 does define the operations that a multifunction electricity meter needs to perform, including measurement, time period management, and reporting functions. Therefore, if you choose a different meter protocol, you must replace the register manager and all message functions except the serial port manager, or at least modify them significantly. The details of these modifications are beyond the scope of this document.

This document will focus on three areas of customization: display customization, register map customization, and DSP function customization. [page]


Display Customization

The display is completely controlled by the display manager. No other task writes to the MAXQ3120's LCD registers. The DisplayFormatter.c module contains the display manager and its main subroutine, UpdateLCD.

If you simply want to use a different LCD module in your meter, you only need to modify UpdateLCD. So we'll start by customizing this module. If you want to change the type of information displayed, you'll need to modify the DisplayManager and probably provide additional hooks to other parts of the meter. 

Customizing UpdateLCD

UpdateLCD takes two parameters: a 32-bit value to display and an 8-bit signal indicator value. The 32-bit display value consists of eight 4-bit values. Therefore, UpdateLCD supports 8-bit, 7-segment displays. Note that the MAXQ3120 supports 112-segment displays, so the program can be customized to support larger displays. If you want to use a different display, you'll need to modify the LCDFont structure. It is defined as a static const. When a structure defined this way is compiled and linked, it resides in program space, not data space. 

LCD Space Allocation Table:  



An important assumption here is that each character can fit into one LCD register. If the LCD structure you're using has some segments that take up more than one LCD register for a 1-bit display, you'll need to modify the entire UpdateLCD function. In  

what order will the digits appear?

The program assumes that the rightmost display number is the lower four bits of the 32-bit display parameter. This is the most natural order; if you pass "123456" to the parameter, the display will display "123456". 

Signal Indicators

If you want to light up specific signal indicators while displaying specific information, you need another 8-bit variable to store the indication information. The UpdateLCD program uses a switch structure to light up these indicators immediately after displaying the number.  

Special State Displays

There is another group of routines at the end of the displayformatter.c file. These routines control special state displays, such as meter initialization, EEPROM initialization, and program failures (exceptions). They are written directly to the LCD registers and are customized for different displays.  

Customizing the Display Manager

If you want to display other information in addition to electricity usage, time, and date, you need to modify the display manager. The  

first part of the display manager handles the display of the meter address setting information. This only works when the address setting button is pressed and does not need to be modified. 

The rest of the display manager is obtained by the global variable g_LCDMode. This variable contains all the necessary information in a single byte to determine the next item to be displayed. Its format is as follows:  

The total electricity used during the meter's use is always displayed, and the item specified by the g_LCDMode byte is displayed. In this reference design, this variable is fixed to 1 - in addition to the total electricity used, only the time and date are displayed.  

Control Variables

The display manager is controlled by the state variable disp, which has two elements: ItEM and State. As the names suggest, disp.State holds the current state of the display controller, while disp.Item keeps track of the information to be displayed. The specific meanings are as follows: 



Customizing this program provides two options. You can choose to change the assignment of disp.Item and change the order in which they are selected in the program, or you can choose to replace the program completely. The latter option may be better. Obviously, such an item selection structure is more flexible if a separate bit is assigned to each item that may be displayed, or a list index is assigned to the displayable items. The above structure was chosen because it requires the least amount of RAM space. 

Adding Registers

DL/T 645 specifies a large number of registers that are used to control various aspects of the meter's operation. Each register is specified by a 16-bit register number. In the reference design, many registers have been added to control various aspects of the meter's operation; descriptions of these registers are provided in the code. This discussion provides the necessary information to obtain more information from the meter or to control new meter operating features by extending the register map.

How the Register Manager Works

The Register Manager task has a difficult time following the principle that all tasks must not suspend normal task operations. This is because the Register Manager is the only task that can read/write the EEPROM, and EEPROM write operations take a (relatively) long time - several milliseconds. Because the DSP program is provided processor time every 20ms (16.7ms at 60Hz), the Register Manager cannot allow the system to be suspended for tens of milliseconds during the EEPROM write cycle.  

An obvious way to solve the EEPROM write time problem is to put the I2C program in interrupt mode. This way, the Register Manager can start an EEPROM transfer process and then return to the main function entry point main(); each time it is called, the Register Manager will determine whether the task has completed by checking the status of the EEPROM subsystem. One problem with this approach is that the ADC cycle is so short that the ADC interrupt service routine needs to monopolize the interrupt subsystem. Therefore, some other protection mechanism must be adopted.

The solution is to use a global flag: EEPROMOpPending. When this flag is low, the task wheel is essentially an infinite loop process, repeatedly calling every task in the system. When the flag is high, the task wheel is executed once and returns when it is called, and the register manager is not called. Is this helpful? 

When the register manager needs to execute a time-consuming function, it starts this function and determines whether it is completed by polling. During the polling period, the register manager sets EEPROMOpPending high and recursively calls the task wheel. The following code gives a practical example:  

01: uint8 ReadEEPROM(uint16 Address, uint8 Length, uint8 *pData)
02: {
03: int i;
04: g_MessageBoard.EEPROMOpPending = 1;
05: for(i=0; i 06: {
07: if(i>0)SpinTaskWheel();
08: eeprom_address = Address++;
09: while(eeprom_read_byte())
10: S 
pinTaskWheel();
11: *pData++ = eeprom_data;
12: } // for
13: g_MessageBoard.EEPROMOpPending = 0;
14: return 1;
15: } 

In line 4 above, the EEPROMOpPending flag is set high. In lines 7 and 10, SpinTaskWheel is called. If the task wheel is called while the EEPROM flag is high, the SpinTaskWheel function runs once and returns without calling the register manager. This allows the rest of the meter to continue operating normally even if the register manager is stalled waiting for the EEPROM to complete an operation.  

Which tasks know about these registers?

Only two tasks know the register numbers: the register manager and the message decoder. Of these routines, the register manager is usually the only one that needs to be modified. The message decoder identifies registers that are relevant to password management and other monitoring functions and must obtain this information before normal processing rules can be used. Therefore, to build your own registers, you only need to be familiar with the register manager. Three Classes of Registers

Typically, there are three classes of registers: read-only, read-write, and read-write registers with additional functions. An example of a read-only register is B611, RMS Volts, phase A. Writing to this register by the host is not executable; in fact, the meter discards the write data if it receives it. Furthermore, most read-only registers are not located in EEPROM: usually, the results of these registers are calculated online and reported as needed.  

An example of a read-write register is C032, Meter Number. Writing a value has no effect on the operation of the meter, and the data can be retrieved at any time. Finally, an example of a read-write register with additional functionality is C030, Meter Constant, active. When this register is written, the register manager must update not only the EEPROM, but also the meter constant used by the DSP program. 

Which tasks require register information?

The following table lists the tasks that require register information. 



In general, you will consider adding registers that are accessible through the message decoder. You can add registers for display (or other tasks, but as a rule, you will consider registers that are retrieved through the communication port). 

Read-Write Registers

First consider the first case, which is storing and reading read-write registers with no additional functionality. To add a register that is stored in the EEPROM, you must add information in two places: the MAXQ3120RD.h file and the ProcessRegisterNumber procedure in the register manager. 

The MAXQ3120RD.h contains a data type called EEPROM_DATA, which is defined by typedef. This definition is not actually instantiated; it is merely a template for defining how data is stored in the EEPROM. Below the EEPROM_DATA definition, two macros are defined that return two values: the offset address of a member in the structure and the number of bytes occupied by the member. The first step in defining a new register is to add members to the structure (preferably at the end) to allocate EEPROM storage space for the register.  

The next step is to define the register number. This requires editing the RegParmTable structure defined in the Register Manager. This table contains every register defined in the meter, sorted by number. Each member consists of:  

Register number, a 16-bit unsigned value.

Physical data unit number, which is used to calculate the actual register value. For example, register 9110 requests the total forward reactive power consumption for the month. It is the sum of two energy accumulators: the power consumption in quadrant 1 and the power consumption in quadrant 4. Therefore, the number of physical units is two. The register manager must extract the data from the specified cell (CurrentQuadrant1AccumTariff) and the next cell (CurrentQuadrant4AccumTariff) and sum them to get the required information.

The length of each cell, in bytes. [page]

Data type stored: INT_REG, indicating that the register contains binary data that is treated as an integer;

BCD_REG, indicating that the register contains BCD data that does not require further conversion before transmission; or MDH_REG, indicating that the register contains date information (month:day:hour).

The offset of the data in the EEPROM (in bytes).

To save processing time, the ProcessRegisterNumber procedure uses a binary search algorithm to find the register address. Therefore, it is very important that the table remains sorted. If the register table becomes unordered, the results are unpredictable. 

Once the table is updated, the new register can be read and written through the communication channel. Exactly how the meter handles this information is the subject of the next section. 

Reading and Writing Registers with Additional Functionality

There is also an application case where you want a write event to trigger additional functionality. To achieve this, the register manager must send a message to the extra task or update the RAM contents involved in performing the extra function. As an example, search for C030 in the register manager and you will find the following code:  

switch(Register.Word)
{
case 0xC030: // Meter constant, real
action_value = 0;
for(i=4; i>1; i--)
{
action_value *= 100;
action_value += (g_CommBuffer.Message[ i] & 0xf) +
(g_CommBuffer.Message[ i] >> 4) * 10;
}
set_E_pulse(action_value); // this will set E_pulse
break; 

This code runs after the EEPROM register data has been updated. In this condition, the host requests a change in the meter constant. After the meter constant register stored in the EEPROM has been updated, the millisecond value transferred to the communication buffer is converted into internal meter units and sent to the DSP program through the set_E_pulse function. 

Read-Only Registers

Some read-only registers are simply read from the EEPROM (such as power usage) and updated by other processes in the meter. However, other read-only registers (such as RMS voltage) are not stored in the EEPROM. It makes no sense to store these registers in the EEPROM, and if you do so and update the data continuously, you will quickly wear out the EEPROM! You can find these registers in the table comments in ProcessRegisterNumber, which state "not stored in EEPROM". 

These registers are controlled by the GetSpecialRegister procedure in the register manager. For each read-only register, the procedure provides the corresponding condition in the switch branch selection statement.例如:  

case 0xB611:// voltage (phase A)
g_MessageBoard.EEPROMOpPending = 1;
Request_RMS(RMS_VOLTAGE_REQUEST);
SpinTaskWheel();
while(!(DSP_CTRL & 0x20))
SpinTaskWheel();
*value = Get_RMS() / 1000;
g_MessageBoard.EEPROMOpPending = 0;
*size = 2;
break;  

This example illustrates an important fact, that no task can hang the task wheel. The first statement in the case sets the EEPROMOpPending flag in the message board high. It then asks the DSP function to calculate the RMS voltage value and recursively calls the task wheel while the DSP function is busy. After the EEPROMOpPending flag is set high, the task wheel loop is executed once and the register manager is not called, thus avoiding infinite recursion. Once the DSP function is completed, the RMS value is extracted and the EEPROMOpPending flag is cleared. 

Note that for read-only registers of this type, it is not necessary to add a structure to the MAXQ3120RD.h file to reserve the EEPROM storage space. It is also not necessary to add a member to the ProcessRegisterNumber table. The main register manager routine always calls GetSpecialRegister before processing EEPROM-based registers. 

Customizing the DSP Program

The reference design's DSP program is a set of assembly language modules that handle the entire signal flow from the ADC to pulse generation and reporting voltage, current, power, and power usage. Most of the program does not need to be modified, but you may want to modify the following aspects:

using a different current or voltage converter, which requires a different gain factor.

Change the way the system generates meter pulses.

Change the front-end filtering.

The following sections provide a high-level description of how the DSP routines work and which elements you can safely change. 

Note: The DSP modules are released publicly as precompiled object files. Assembly language source code is available only under a nondisclosure agreement (NDA). Contact Dallas Semiconductor/Maxim for more information.  The lower portion of the RAM space used to

store

the DSP routines. Searching for "Data Memory Map" in the DSP module will reveal a list of RAM variables used by the DSP routines. The first two bytes are a set of bits that control the operation of the DSP functions. 

Constants

Two constants can be adjusted to set the full-scale readings for the voltage and current channels. These are W_V_Scale and W_I_Scale. By default, these constants are set to 400V and 250A. The voltage is set to a level that will not be exceeded under normal conditions (above 280VRMS), while the current setting is consistent with the possible meter shunt values ​​(250μ to 500μ, typical). 

Interface Routines

User programs can directly use the return values ​​of some built-in routines. If possible, you should interface with the DSP functions through these built-in routines rather than directly with the internal variables used by the DSP functions.  

Get_and_Clear_Usage: This is the main C code routine used to extract the accumulated power value. Normally, the DSP routine notifies the asynchronous event manager when the power usage needs to be accumulated. However, this routine can be called at any time to obtain an accurate reading of the power usage (as of now). Note that the IAR compiler automatically passes the function parameters in A[0] and returns the result in A[0]. 

Get_Frequency: Returns the line frequency in 0.1mHz steps. It is important to note that this routine is not loaded by default; the DL/T 645 standard does not require a frequency result.

Get_Power_Factor: Returns the power factor of the load.

Get_Power: Returns the reactive or active power, depending on the parameters. 

Get_MaxD: Returns the maximum demand (power) value recorded by the meter since the last call to this function.

Request_RMS: Requests the DSP to calculate the RMS current or voltage value, depending on the parameters. 

Get_RMS: Returns the most recently requested RMS value. 

set_E_pulse: Accepts a meter constant and sets the appropriate DSP variables to take effect.

Interrupt Service Routine

The reference design has only one interrupt enabled: the AFE interrupt, which is generated when a new set of samples is available on the ADC. Because the ADC sample period is 48μs, the interrupt service routine actually finishes its work very quickly and returns to the main code—only 384 instruction cycles between interrupts! 

The interrupt service routine performs the following functions:  

Generate Output Pulse: If a pulse is required, start it. If a pulse is in progress, decrement the duration counter and terminate the pulse when the counter reaches zero. 

Accumulate Sum: Accumulate the most recent energy sample into all appropriate registers.

Accumulate RMS Value: Accumulate I2 or V2 if requested.

Check Voltage Lower Limit: Increment a counter if the voltage is below the threshold.

Zero Crossing Detect: Set a flag if the voltage signal crosses zero in a positive direction.
Keywords:MAXQ3120 Reference address:Customization Features of the MAXQ3120 Energy Meter Reference Design

Previous article:Gesture tracking is the future of interaction, so how to solve tactile feedback
Next article:Coverage Testing of Embedded Software

Latest Security Electronics Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号