软件大体框架如下:
§4.3 各模块功能分配及调用关系
软件大体按功能分为多个模块, 其功能分配及调用关系如下: .1. I2C通讯模块:
从PCF8583中读出或向PCF8583写入若干个数据。
.2. 掉电中断(INT0)服务程序:
保存脉冲计数值, 显示项号和当前时间, 中止程序执行。 调用:
.1. I2C通讯模块
.3. 电能脉冲中断(INT1)服务程序:
接收脉冲信号, 并判断是否需要修改总电量, 及按当前时段峰平谷值指示修改分电量。 调用:
.1. I2C通讯模块
.4. T0中断服务程序:
软件WATCHDOG监视器, 将 H增1, 并判是否大于3, 是则转出错处理。 .5. 更新显示缓冲区模块(READ):
将DSPNUM(显示项号)所指示的数据送入显示缓冲区。 调用:
.1. I2C通讯模块
.6. 编程数据记录模块: 记录修改过的编程数据。 调用:
.1. I2C通讯模块。 .7. 上电初始化模块:
各单元送初始值, 初始化各特殊寄存器, 各变量送缺省值。 调用:
.1. I2C通讯模块
.5. 更新显示缓冲区模块(READ) .8. 抄表模块:
记录抄表数据, 重置工作单元, 记录需量数据。 调用:
.1. I2C通讯模块 .9. 掉电恢复模块:
恢复掉电保护数据, 记录停电时间, 如需要则抄表。 判断当前时段, 恢复正常工作。 调用:
.1. I2C通讯模块
.5. 更新显示缓冲区模块(READ) .8. 抄表模块 .10. 键处理模块:
分析键码, 并按程序不同状态执行对应操作。 调用:
.1. I2C通讯模块
.5. 更新显示缓冲区模块(READ) .8. 抄表模块
.11. 显示模块:
将显示缓冲区数据送数码管显示。 .12. 主程序模块:
根据系统时钟及时切换时段, 调用各模块完成系统功能。
§4.4 几处关键算法的说明
(1) 秒信号的获得:
PCF8583的INT脚有开放中断,当它不作闹钟功能时,此引脚上为以秒为周期的方波信号,读该引脚,如有由高到低跳变记为1秒,秒计数在8951里完成,满一分钟时读PCF8583内时间,修改8951 内时间以和8583保持一致。
(2) 需量的计算:
设有滑差队列指针QUETHIS, 抄表后自动回到队列头QUEHEAD, 当
QUETHIS指向队列最后一个元素时置队列满标志QUEFALL,软件检测到有这个标志时开始计算当前需量,及判读并记录最大需量。
(3) 循环显示的实现:
非编程态当循环键(
(4) 判当前时段(SD_NOW):
程序先判断用户定义了多少个时段, 由于规定最后一个时段为23:59, 软件从时段02 开始检测最后一个时段值不为23:59 的时段, 则SYSDS (使用时段数)等于这个时段号,再看该时段的费率是否为谷, 不为谷SYSDS再增1, 这样就得到用户定义的时段数目。
根据当前时间, 程序搜索最后一个小于当前时间的时段值, 它即为当前时段,将当前时段费率填入DQSDFPG (当前时段峰平谷值, 它指示分电量的记录), 并将下个时段值填入 XGSD (下个时段), 以供软件在出现分信号时检测,若时钟等于XGSD则更新DQSDFPG和XGSD。
(5) 时段的切换
系统设有 XGSD (下个时段值, 两个字节, 分别为下个时段点的小时和分钟值), 以供软件在出现分信号(秒计时为00H)时检测,若时钟等于XGSD则更新DQSDFPG和XGSD。 将当前时段费率填入DQSDFPG(当前时段峰平谷值, 它指示分电量的记录), 并将下个时段值填入XGSD (下个时段), 以供下次检测。
(6) 数据的显示
显示由两部分共同完成,显示程序 DISPLAY和显示缓冲区更新程序READ。
DISPLAY负责把显示缓冲区的内容送到八个七段上显示出来,做法是:关闭P1口(送00H), 显示缓冲区一个字节送P0, P1口开放( 每次开放一位, 如01000000B开放左数第二个七段), 顺次从高则低送八个七段同时开放该数码管。
READ负责把显示项号DSPNUM 指示的数据送到显示缓冲区 DSPNUM<50 时为普通(非编程态)显示, DSPNUM≥50时为编程态显示。 做法是利用类似高级语言Switch的机构, 用 CJNE A,#项号1,#标号1 AJMP #(功能子程序)标号2 标号1:
CJNE A,#项号2,#标号3 AJMP #(功能子程序)标号4 标号3:
: :
(功能子程序)标号2:
送项号为项号1的数据; AJMP READ_END
(功能子程序)标号4:
送项号为项号2的数据; AJMP READ_END : :
READ_END(更新程序结束点):
语句来实现跳转到该项数据处理处, 这使和分折和处理两相分离, 程序易读、易编制、易调试, 更方便后续工作的开展和维护如需增加显示项仅增加
CJNE A,#新项号,#处理 AJMP #新处理标号 新处理标号: 处理??
AJMP READ_END 即可。
若READ数据在PCF8583中,则先调用READPCF子程序将数据读入读缓冲区(R_BUF), 然后将之分解送入DSPBUF, 同时根据对该数据意义的解释对相应位置小数点位, 如DSPNUM=01时是总电量, 此时若为两位小数, 则DSPBUF的37H第4bit置1, 送显示时即有小数点被点亮。
(7) 编程数据记忆(FWRITE):
对数据编程时, 有一个MODI_F位,若该位为1 时,则说明该项数据系统修改过, 则调用FWRITE记忆之, 否则不修改原值。 FWRITE先按DSPNUM的不同解释显示缓冲区数据的意义, 将数据装配起来, 例由六字节变为三字节压缩 BCD码, 且不含小数点信息( 小数点只在显示时按对该数据的解释加上)。 同样对 DSPNUM采用了类似 Switch的机构。 若数据存放在PCF8583则调用WRITEPCF写入之。