微波EDA网,见证研发工程师的成长!
首页 > 测试测量 > 测试测量技术文库 > MAXQ3120电表参考设计的定制功能

MAXQ3120电表参考设计的定制功能

时间:09-13 来源:互联网 点击:
定制功能

本参考设计符合DL/T 645-多功能、瓦时电表通信协议。但这篇文档不仅仅对通信协议进行说明。DL/T 645确实对一个多功能电表需要执行的操作进行了规定,包括测量、时段管理和报告功能。因此,如果你要选择其它电表协议,你必须替换掉寄存器管理器以及除串口管理器之外的所有消息函数,或者至少对其进行重大修改。修改的细节不在本文讨论范畴内。

本文档将着重讨论三个定制领域:显示定制、寄存器映射定制和DSP函数定制。

显示定制

显示器完全由显示管理器控制。其它任何任务都不会向MAXQ3120的LCD寄存器写入数据。DisplayFormatter.c模块包含了显示管理器及其主要子程序UpdateLCD。

如果你只是想在电表中使用一个不同的LCD模块,则只需修改UpdateLCD。所以我们将从这个模块的定制开始说起。如果你想改变显示信息的类型,你就要修改DisplayManager,并且可能需要给电表的其它部分提供额外的钩子(hook)函数。

定制UpdateLCD

UpdateLCD接收两个参数:一个待显示的32位数值和一个8位信号指示器数值 。32位显示值包括8个4位数值。因此,UpdateLCD支持8位、7段显示器。注意,MAXQ3120支持112段显示,所以可以定制该程序以支持更大规模的显示器。 如果想用不同的显示器,你需要修改LCDFont结构。它被定义为static const类型。这样定义的结构进行编译和连接后,将驻留在程序空间,而不是数据空间。

LCD空间分配表:  



这里有个重要的假设:每个字符都可填入一个LCD寄存器。如果所采用的LCD结构中,属于1位显示的某些段要占用多个LCD寄存器,则需要修改整个UpdateLCD。  

数字的显示顺序是什么?

程序假设最右端的显示数字,是32位显示参数的低四位。这是最自然的顺序;如果你将“123456”传递给参数,则显示器会显示“123456”。

信号指示器

如果你想在显示特定信息的情况下,同时点亮特定的信号指示器,则需要另外一个8位变量来存储指示信息。UpdateLCD程序使用一个switch结构,以在显示数字之后马上点亮这些指示器。  

特殊状态显示

在displayformatter.c文件的最后还有一组程序。这些程序控制特殊状态显示,例如电表初始化、EEPROM初始化和程序故障(异常)。它们被直接写入LCD寄存器,而且要针对不同的显示进行定制。  

定制显示管理器

除了显示用电量、时间和日期以外,如果你还想显示其它信息,则需要修改显示管理器。  

显示管理器的第一部分,处理电表地址设置信息的显示。仅当地址设置按钮被按下时才起作用,不需要修改这一部分。

显示管理器的其它部分,通过全局变量g_LCDMode来获取类别。为确定要显示的下一个条目,这个变量在一个字节内包括了所有必要的信息。它的格式如下所示:  

总会显示电表使用过程中累计的总用电量,并显示由g_LCDMode字节所指定的条目。在本参考设计中,这个变量被固定为1―除了显示总用电量以外,只显示时间和日期。  

控制变量

显示管理器由状态变量disp所控制,该变量有两个元素:ItEM和State。由名字可以得知,disp.State存放显示控制器的当前状态,而disp.Item跟踪将要显示的信息,具体含义如下:



定制这个程序提供两种选项。你可以选择改变disp.Item的赋值,以及改变程序中它们的选择顺序,或者你可以选择完全替换掉该程序。后一种选择可能更好。如果为可能显示的每个条目指定一个独立位,或为可显示条目分配一个列表索引,显然这样的条目选择结构更加灵活。选择上面的结构是因为它需要的RAM空间最小。

添加寄存器

DL/T 645规定了大量寄存器,用于控制电表运行的各个方面。每个寄存器由一个16位寄存器号指定。在参考设计中,增加了很多寄存器来控制电表运行的各个方面;在代码中给出了这些寄存器的说明。本讨论内容提供了必要的信息,以便通过扩展寄存器映射从电表中获取更多信息,或者控制新的电表运行特性。

寄存器管理器如何工作

所有任务都不能挂起正常的任务轮操作,寄存器管理器任务要遵循这一原则有很大难度。这是因为寄存器管理器是唯一能够读/写EEPROM的任务,并且EEPROM写操作需要(相对)较长的时间―几个毫秒。因为每20ms (60Hz环境下是16.7ms)就要为DSP程序提供处理器时间,寄存器管理器在EEPROM写周期过程中,绝不允许将系统挂起几十毫秒的。  

要解决EEPROM写入时间问题,一个显而易见的方法是将I2C程序置为中断处理方式。这样一来,寄存器管理器可以启动一个EEPROM传输过程,随即返回主函数入口main();之后每次被调用时,寄存器管理器都会通过检查EEPROM子系统的状态,来确定任务是否已经完成。采用这种方案带来一个问题,ADC周期非常短,以至于ADC中断服务程序需要独占中断子系统。因此,必须采取一些其它保障机制。

解决的方法是采用一个全局标志位:EEPROMOpPending。当这个标志位为低时,任务轮实质上是一个无限循环过程,反复调用系统中的每一个任务。当标志位为高时,任务轮被调用时执行一次并返回,并不调用寄存器管理器。这样有什么帮助吗?

当寄存器管理器需要执行一个耗时很长的功能时,它启动这个功能并通过轮询来确定其是否完成。在轮询期间,寄存器管理器将EEPROMOpPending置为高,并递归调用任务轮。下面的代码给出了一个实际例子:  

01: uint8 ReadEEPROM(uint16 Address, uint8 Length, uint8 *pData)
02: {
03: int i;
04: g_MessageBoard.EEPROMOpPending = 1;
05: for(i=0; i<length; 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: }

在上面的第4行,EEPROMOpPending标志位被置为高。在第7和10行中,SpinTaskWheel被调用。如果EEPROM标志位为高时调用任务轮,则SpinTaskWheel函数运行一次,并在不调用寄存器管理器的情况下返回。这样,即使由于寄存器管理器等候EEPROM完成操作而停止下来,电表的其它部分仍可持续正常运行。  

哪些任务知晓这些寄存器?

只有两个任务知道寄存器号:寄存器管理器和消息译码器。这些程序中,通常只需要对寄存器管理器进行修改。消息译码器识别出与口令管理和其它监控功能有关的寄存器,并且必须在采用正常处理规则之前获取这些信息。因此,要构建自己的寄存器,只需要熟悉寄存器管理器。 三类寄存器

通常,有三类寄存器:只读、读写和具有额外功能的读写寄存器。只读寄存器的一个例子是B611,RMS Volts、phase A。主机向这个寄存器写数据是不能执行的;实际上,如果电表收到写数据会将其丢弃。而且,多数只读寄存器都不在EEPROM中:通常,在线计算这些寄存器的结果,并根据需要报告结果。  

读写寄存器的一个例子是C032,Meter Number (电表号)。写入数值不会对电表操作产生任何影响,而且可以随时提取该数据。最后,一个具有额外功能的读写寄存器例子是C030,Meter Constant, active (有效电表常数)。当这个寄存器被写入数据时,寄存器管理器不仅要更新EEPROM,同时也要更新DSP程序使用的电表常数。

哪些任务需要寄存器信息?

下表列出了需要寄存器信息的任务。



通常,你主要考虑添加可通过消息译码器访问的寄存器。你可以增加用于显示的寄存器(或者用于其它任务的寄存器,但是依据惯例,你会主要考虑那些可通过通信端口检索的寄存器)。

读写寄存器

首先考虑第一种情况,即存储和读取无额外功能的读写寄存器。为了添加一个存储于EEPROM内的寄存器,你必须添加两处信息:MAXQ3120RD.h文件和寄存器管理器中的ProcessRegisterNumber程序。

MAXQ3120RD.h包含一个由typedef定义的名为EEPROM_DATA的数据类型。这个定义并没有被真正实例化;而仅仅是作为模板,用于定义数据如何存入EEPROM。在EEPROM_DATA定义的下面,还定义了两个宏,用来返回两个值,分别是结构中某成员的偏移地址和某成员占用的字节数。定义新寄存器的第一步,是在结构中添加成员(最好是在尾部),从而为寄存器分配EEPROM存储空间。  

下一步是定义寄存器号。这需要编辑寄存器管理器中定义的RegParmTable结构。这个表包含了电表中定义的每个寄存器,并按编号排序。每个成员包括:  

寄存器号,16位无符号值。

物理数据单元编号,用于计算实际寄存器值。例如,寄存器9110请求当月总的正向无功用电量。它是两个电能累加器的和:包括1象限的用电量和4象限的用电量。因此,物理单元的个数是二。寄存器管理器必须提取指定单元(CurrentQuadrant1AccumTariff)和下一个单元(CurrentQuadrant4AccumTariff)的数据,并求和以获得所需信息。

每个单元的长度,以字节为单位。

存储的数据类型:INT_REG,表示寄存器包含被视为整数的二进制数据;

BCD_REG,表示寄存器包含的是传输前无需进一步转换的BCD码数据;或者MDH_REG,表示寄存器包含的是日期信息(月:日:小时)。

EEPROM中数据的偏移量(单位为字节数)。

为了节约处理时间,ProcessRegisterNumber程序采用二元搜索算法找出寄存器地址。因此,表格保持排序状态是非常重要的。如果寄存器表变得无序,结果就无法预料了。

一旦表格被更新,新的寄存器可以通过通信通道进行读写。电表到底如何处理该信息,是下一部分的主要内容。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top