Electricity Meter (EM) Reference Design Based on the MAXQ3120 Microcontroller

Publisher:devilcoreLatest update time:2012-01-13 Source: 互联网 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 language, 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 device 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 buttons and power failure events on the power line, complete requests for information from the external EEPROM, and track changes in rate periods.

Task Management Methods

At first glance, to complete the above multiple real-time tasks, it is imperative that some kind of real-time operating system (RTOS) is urgently needed 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 CPU resources in order to complete execution before the next power cycle. (The power cycle handler will use 25% to 30% of the CPU's computing power.) Although an RTOS can meet these requirements, it is not the most efficient use of resources.

Second, the space available for storing task context is very limited. Most RTOS give each task a complete virtual processor to execute operations on, which requires storing the context of each task. With only 256 16-bit words of RAM available, a small number of tasks will run out of memory.

Therefore, this reference design chose a simple task wheel. In this configuration, tasks are called in sequence, 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, which can include: extracting data from the 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 other tasks to complete before it can complete its task. 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 part of these data structures is the message board, which is a set of bits that one task sets 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 certain actions.

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 sends the first character as the "active" channel. The channel will remain 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 based on time and other events.

Message Formatter: Prepares replies to messages interpreted by the Message Decoder.

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

Register Manager: Performs read/write EEPROM operations.

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

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

Adding Tasks

As defined in the Energy Meter Reference Design, a task is a single-threaded section 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 to break them 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 the task anywhere in the execution flow and call it as often as you want. You will find 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 cannot be left idle for several cycles and the SerialPortDriver task cannot miss any input characters.

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

Global Variables

Since a true multitasking operating system is not used, there is no true 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 the other channel); a TBE bit to prepare the idle channel for operation; and a data loss bit that is set high when the idle channel receives a character while the other channel is busy communicating.

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

g_CommBuffer: A 50-byte array containing the message just received or the message 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 transmit 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 carry data between the register manager and the various tasks. For example, the contents of a register that needs to be sent are placed in g_MessageFormatterData by the register manager.

g_AEMRegisterNeeded; g_DispFormatterRegRequest; g_RequestScheduleManager; g_LCLRegRequest: These registers contain the registers that need to be read or written for a specific task. 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 valid tariff number. This function has its own global variables so that it does not need to perform multiple EEPROM read operations to determine where to store the sampled values ​​each time the energy is accumulated.
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 relevant 4 bits of data in g_PW will be cleared.

g_LoadCurveUsage; g_LoadCurvePeak; g_LoadCurveTimeStamp: Variables associated with the load profile logging task. g_LoadCurveUsage accumulates the power usage and will eventually be reported to the load profile logging task. The load profile logging 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 profile and record the interval and time when the peak power occurs.

AEMState: Contains a group of variables related to asynchronous events. When a set meter address message is received, the msg_rx flag is set high. After the address setting logic circuit is activated, the variable timer contains the number of seconds required to restore normal display. The DSPState and Register variables track the process of register power usage information being transferred 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 sent at the 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 for the next message.

g_TransmitDelay: Some RS-485 converters delay a fixed time after the last character is sent 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 the fixed delay for the transmit state to be maintained before 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.

Custom Functionality

This reference design complies with DL/T 645 - Multifunction, Watt-Hour Meter Communication Protocol. However, this document does more than just describe the communication protocol. DL/T 645 does define the operations that a multifunction meter needs to perform, including measurement, time period management, and reporting functions. Therefore, if you choose another 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 the modification are beyond the scope of this article.

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


Display Customization

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

If you just want to use a different LCD module in the meter, you only need to modify UpdateLCD. So we will start with the customization of this module. If you want to change the type of information displayed, you will have to modify the DisplayManager and may need to provide additional hook functions for other parts of the meter.

Customizing UpdateLCD

UpdateLCD receives two parameters: a 32-bit value to be displayed 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 need to modify the LCDFont structure. It is defined as a static const type. After the structure defined in this way is compiled and linked, it will reside in the program space instead of the data space.

LCD space allocation table:



There is an important assumption here: each character can be filled into one LCD register. If the LCD structure used is such that some segments of the 1-bit display occupy more than one LCD register, the entire UpdateLCD program needs to be modified. In

what order are the digits displayed?

The program assumes that the rightmost display digit 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 show "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 information other than power 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, so there is no need to modify this part.

The rest of the display manager uses the global variable g_LCDMode to obtain the category. 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 power usage accumulated 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 power usage, 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 stores the current state of the display controller, while disp.Item tracks the information to be displayed. The specific meanings are as follows:

There are two options for customizing this program. You can choose to change the values ​​assigned to disp.Item and the order in which they are selected in the program, or you can choose to replace the program entirely. The latter option is probably better. Obviously, the 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 given 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

All tasks cannot suspend normal task wheel operation, and the Register Manager task has a great deal of difficulty in following this principle. 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 processor time is provided to the DSP program every 20ms (16.7ms at 60Hz), the register manager cannot allow the system to hang for tens of milliseconds during the EEPROM write cycle.

An obvious way to solve the EEPROM write time problem is to set the I2C program to interrupt processing mode. In this way, the register manager can start an EEPROM transfer process and then return to the main function entry main(); each time it is called, the register manager will check the status of the EEPROM subsystem to determine whether the task has been completed. The problem with this solution 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, without calling the register manager. Does this help?

When the register manager needs to execute a long function, it starts this function and polls to determine whether it has completed. During polling, the register manager sets EEPROMOpPending high and recursively calls the task round. 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, only 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. Also, most read-only registers are not in the EEPROM: typically, 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 meter's operation, 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.



Generally, 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 a read-write register 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 file contains a data type named 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 that the member occupies. 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 each register defined in the meter, sorted by number. Each member consists of:

The register number, a 16-bit unsigned value.

The physical data unit number, which is used to calculate the actual register value. For example, register 9110 requests the total forward reactive power usage for the month. It is the sum of two energy accumulators: the power usage in quadrant 1 and the power usage 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.

The type of data 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 need 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 out of order, 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 effect, the register manager must send a message to the additional task or update the RAM contents involved in performing the additional 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

This code is executed after the register data in the EEPROM has been updated. Under this condition, the host requests to change the meter constants. After the meter constant registers stored in the EEPROM have 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 does not make 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 of the register manager. For each read-only register, the program provides the corresponding condition in the switch branch selection statement. For example:

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 this type of read-only register, it is not necessary to add a structure to the MAXQ3120RD.h file to reserve EEPROM storage space. It is also not necessary to add members to the ProcessRegisterNumber table. The main register manager routine always calls GetSpecialRegister before processing EEPROM-based registers.

Customizing the DSP Routine

The reference design's DSP routine is a set of assembly language modules that handle the entire signal flow from the ADC to pulse generation and reporting of voltage, current, power, and power usage. Most of the routines should not require modification, but you may want to modify the following:

Use a different current or voltage converter that 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 routine works and which elements you can safely change.

Note: The DSP modules are publicly available as precompiled object files. Assembly language source code is available only under a nondisclosure agreement (NDA). Contact Dallas Semiconductor/Maxim for more information. The DSP routines

are stored

in the lower portion of RAM space. 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

Some of the built-in routines can be used directly by the user program. 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 program will notify 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 to A[0].

Get_Frequency: Returns the line frequency in 0.1mHz steps. 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 reactive or active power, depending on the parameter.

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 parameter.

Get_RMS: Returns the most recently requested RMS value.

set_E_pulse: Accepts a meter constant and sets the appropriate DSP variables to make the meter constant effective.

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 sampling period is 48μs, the ISR actually finishes its work and returns to the main code very quickly—only 384 instruction cycles between interrupts!

The ISR 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 Total: Accumulate the most recent energy sample into all appropriate registers.

Accumulate RMS: Accumulate I2 or V2 if requested.

Check Voltage Lower Limit: If the voltage is below the threshold, increment a counter.

Zero-crossing detection: If the voltage signal crosses zero in the positive direction, a flag is set.

break;



Reference address:Electricity Meter (EM) Reference Design Based on the MAXQ3120 Microcontroller

Previous article:Energy Efficient Solar Charge Controller Design Example
Next article:Brief description of power factor control scheme for power supply

Latest Power Management 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号