📄 acc_energy.s51
字号:
/*
2006/09/20 - Petre M
This function accumulates the energy in assembly in order to work in BCD format
The energy is accumulated in Active_Energy.B4-B1 structure
*/
#include "system_def.h"
#include "ioADE7169F16.h"
MODULE acc_energy
PUBLIC Accumulate_Energy
FUNCTION Accumulate_Energy,0203H
EXTERN Active_Energy
RSEG NEAR_CODE:CODE:NOROOT(0)
Accumulate_Energy:
CLR EA ;disable all interrupts
/*
-subtract MC/100 from Active_Energy.B0.
-If Active_Energy.B0 < MC/100, don't do anything
-If Active_Energy.B0 >= MC/100, then subtract MC/100 from it and
accumulate 1 in Active_Energy.B4-B1
-The energy is accumulated in tens of wh, i.e. 0.01 Kwh.
-The display must at least visualize hundreds of wh, i.e. 0.1kwh
-So, if the LCD digits is 7, the maximum number that can be represented
on the display is 999,999.9Kwh. Therefore, the maximum number that may
be accumulated in Active_Energy.B4-B1 is 999 999 99
-If the LCD digits is 6, the maximum number that can be represented
on the display is 99,999.9Kwh. Therefore, the maximum number that may
be accumulated in Active_Energy.B4-B1 is 99 999 99
-So, if Active_Energy.B4-B1>Max_wh_number, then make Active_Energy.B4-B1=0
There are 8 digits accumulated in Active_Energy.B4-B1. This is exactly the
number of digits that are necessary for a 7 segment LCD. So for the LCD
used on the reference design, overflowing goes naturally to 0.
The problem appears when we have LCDs with different segments
*/
MOV A, Active_Energy
CJNE A, #limit_counter, Not_Eq ;if Active_Energy.B0 != MC/100, then jump to Not_Eq
SJMP Inc_energy
Not_Eq:
JC END1 ;if Active_Energy.B0 < MC/100, don't do anything
Inc_energy:
SUBB A,#limit_counter
MOV Active_Energy, A ;store the new value of Active_Energy.B0
MOV R0, #0x01
CLR C
MOV A, Active_Energy+1 ;read Active_Energy.B1
ADD A, R0 ;1+B1
DA A
MOV Active_Energy+1, A
MOV A,Active_Energy+2
ADDC A, #0
DA A
MOV Active_Energy+2, A
MOV A,Active_Energy+3
ADDC A, #0
DA A
MOV Active_Energy+3, A
MOV A,Active_Energy+4
ADDC A, #0
DA A
MOV Active_Energy+4, A
//if the LCD has 6 segments, the energy is accumulated on (6-1)+2=7 digits,
//so the most significant nibble is erased
#if (LCD_digits_number==6)
MOV A, Active_Energy+4
ANL A, #0x0f
MOV Active_Energy+4, A
#endif
//if the LCD has 5 segments, the energy is accumulated on (5-1)+2=6 digits,
//so the most significant byte is erased
#if (LCD_digits_number==5)
CLR A
MOV Active_Energy+4, A
#endif
END1:
SETB EA
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -