Você está na página 1de 64

;************************************************************

; Author: Dave Smith


; Company: Analog Devices Inc.
; Revision: 1.1
; Date: 4-9-2001
;************************************************************
; This program controls and reads data from The Analog Devices ADE7756
; Single Phase Bi-Directional Power/Energy IC to measure Active Energy, Voltage
RMS and Current RMS.
; This program should be used in conjunction with the AN-578 Application note
; The Energy Dump routine describes in the AN-564 and AN-578
; is not implemented in this version of the program
; This code is for the PIC16F873 but can easily been changed to work with PIC16C
63

list p=16f873 ; list directive to define processor


#include <p16f873.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENA
BLE_ON & _LVP_OFF & _CPD_OFF
; Declare variables ; valid addresses are Bank 0 20 to 7F Hex and ba
nk1 A0 to FF Hex

spi equ H'20' ; spi reg data =0c hex


swap_w equ H'21' ; used in interrupt routine
swap_status equ H'22' ; used in interrupt routine
swap_wordlen equ H'23' ; used in interrupt routine
outd1 equ H'24' ; out to 7756 1st byte (msb 1st) of word
outd2 equ H'25' ; out to 7756 2st byte (msb 1st) of word
mem equ H'26' ; used to check eeprom mem
carry equ H'27' ; used in carrychk routine
wordlen equ H'28' ; word length for rotate
sar1 equ H'29' ; approximation register 1
sar2 equ H'2A' ; approximation register 2
sar3 equ H'2B' ; approximation register 3
wait equ H'2C' ; wait loop data
wait2 equ H'2D' ; wait2 loop data
bcd0 equ H'2E' ; lsb of bcd word
bcd1 equ H'2F' ; bcd word
bcd2 equ H'30' ; bcd word
bcd3 equ H'31' ; bcd word
bcd4 equ H'32' ; msb of bcd word
bin0 equ H'33' ; lsb of bin word
bin1 equ H'34' ; bin word
bin2 equ H'35' ; bin word
bin3 equ H'36' ; bin word
bin4 equ H'37' ; msb of bin word
addend1 equ H'38' ; result of addition
addend2 equ H'39' ; result of addition
addend3 equ H'3A' ; result of addition
addend4 equ H'3B' ; result of addition
addend5 equ H'3C' ; result of addition
addend6 equ H'3D' ; result of addition
y1 equ H'3E' ; binary acumulated power
y2 equ H'3F' ; binary acumulated power
y3 equ H'40' ; binary acumulated power
y4 equ H'41' ; binary acumulated power
y5 equ H'42' ; binary acumulated power
y6 equ H'43' ; period to freq
mode0 equ H'44' ; lsb mode register data
mode1 equ H'45' ; msb mode register data
sample_low equ H'46' ; lsb cf divide data
sample_middle equ H'47' ; msb cf divide data
sample_high equ H'48' ; period to freq
contint equ H'49' ; loop for energy dump
dave1 equ H'4A' ;
dave2 equ H'4B' ;
x1 equ H'4C' ; output of iir filter
x2 equ H'4D' ; output of iir filter
x3 equ H'4E' ; output of iir filter
x4 equ H'4F' ; output of iir filter
x5 equ H'50' ; output of iir filter
x6 equ H'51' ; output of iir filter
eep1 equ H'52' ;
eep2 equ H'53' ;
timerh equ H'54' ; timer working reg
timerl equ H'55' ; timer working reg
sinwait equ H'56' ; serial in wait between bit check
bcdtemp equ H'57' ; energy conversion constant .xxxxxxxx
lcdout equ H'58' ; lcd output data
lcdup equ H'59' ; lcd acsii data upper 4 bits
lcdlow equ H'5A' ; lcd ascii data lower 4 bits
wait3 equ H'5B' ; wait for lcd
insd1 equ H'5C' ; in from 7756 1st byte (msb 1st) of word
insd2 equ H'5D' ; in from 7756 2st byte (msb 1st) of word
insd3 equ H'5E' ; in from 7756 3st byte (msb 1st) of word
insd4 equ H'5F' ; in from 7756 4st byte (msb 1st) of word
insd5 equ H'60' ; in from 7756 5st byte (msb 1st) of word
insd6 equ H'61' ; sign extension
insd7 equ H'62' ; sign extension
insd8 equ H'63' ; sign extension
insd9 equ H'64' ; sign extension
insd10 equ H'65' ; sign extension
insd11 equ H'66' ; sign extension
econstant0 equ H'67'
econstant1 equ H'68'
econstant2 equ H'69'
tempof equ H'6A'
econstant equ H'6B'
mem2 equ H'6C'
msdbcd equ H'6D' ; used in bcd conversion
lsdbcd equ H'6E' ; used in bcd conversion
point equ H'6F' ; decimal point flag
mem3 equ H'70' ; energy conversion constant .xxxxxxxx
sampcnt equ H'71' ; loop for energy dump
square1 equ H'72' ; used in rms routine lsb
square2 equ H'73' ; used in rms routine
square3 equ H'74' ; used in rms routine
square4 equ H'75' ; used in rms routine
square5 equ H'76' ; used in rms routine
square6 equ H'77' ; used in rms routine msb
add1 equ H'78' ; results of square and sum lsb
add2 equ H'79' ; results of square and sum
add3 equ H'7A' ; results of square and sum
add4 equ H'7B' ; results of square and sum
add5 equ H'7C' ; results of square and sum
add6 equ H'7D' ; results of square and sum
div equ H'7E' ; results of square and sum msb
wavsamp equ H'7F' ; number of wav samples
; A0 to FF page1 address**************************************************
icof1 equ H'A0' ; lsw current coef
icof2 equ H'A1' ; msw current coef
vcof1 equ H'A2' ; lsw volts coef
vcof2 equ H'A3' ; msw volts coef
coffdiv equ H'A4' ; coeff divisor
rmsch equ H'A5' ; channel memory
ioffset1 equ H'A6' ; current channel offset correction
ioffset2 equ H'A7' ; current channel offset correction
voffset1 equ H'A8' ; voltage channel offset correction
voffset2 equ H'A9' ; voltage channel offset correction
aenergy0 equ H'AA' ; binary acumulated power
aenergy1 equ H'AB' ; binary acumulated power
aenergy2 equ H'AC' ; binary acumulated power
aenergy3 equ H'AD' ; binary acumulated power
aenergy4 equ H'AE' ; binary acumulated power
aenergy5 equ H'AF' ; binary acumulated power after conversion to kw
h
aenergy6 equ H'B0' ; binary acumulated power
aenergy7 equ H'B1' ; binary acumulated power
aenergy8 equ H'B2' ; binary acumulated power
aenergy9 equ H'B3' ; binary acumulated power
aenergy10 equ H'B4' ; binary acumulated power
e0 equ H'B5' ; temp storage for energy before display
e1 equ H'B6' ; temp storage for energy before display
e2 equ H'B7' ; temp storage for energy before display
e3 equ H'B8' ; temp storage for energy before display
e4 equ H'B9' ; temp storage for energy before display
e5 equ H'BA' ; temp storage for energy before display

;setup ports

org 0 ; start at address 0


clrf PCLATH ; ensure page bits are cleared
GOTO INITIALIZE
org 0x0004 ; interrupt vector
LGOTO INTERRUPT
;---------LCD control setup I/O--------------------------
#DEFINE lcd7 PORTA,5
#DEFINE lcd4 PORTC,0
#DEFINE lcd5 PORTC,1
#DEFINE lcd6 PORTC,2
#DEFINE lcde PORTA,3
#DEFINE lcdrs PORTC,6
#DEFINE lcdrw PORTC,7
;--------rs232 port setup I/O----------------------------
#DEFINE rsout PORTA,0
#DEFINE rsin PORTA,4
;--------7756 control setup I/O--------------------------
#DEFINE irqb PORTB,0
#DEFINE rstb PORTB,3
#DEFINE csb PORTB,4
#DEFINE sagb PORTB,6
#DEFINE rms PORTB,1
;end port setup

;----------------freq setup--------------------
#DEFINE timer PORTA,1 ; timer,0 stop timer,1 start
#DEFINE mcsb PORTB,5 ; cs for spi rom

INITIALIZE:

TRISTATE:
;=====================check for cal cable set all pins to input=================
===========
; if cable present display cal mode on display and tristate all spi buss pins to
allow pc to take over

bcf STATUS,6
bsf STATUS,5 ; set to bank 1
movlw H'06' ; set port a to digital same as 16C62B
movwf ADCON1
clrf PIE1 ; clr register in bank 1
clrf PIE2 ; clr register in bank 1
bcf STATUS,5 ; set to bank 0
movlw B'11010111' ; w := 11111010 binary
tris PORTA ; port A ctrl register := w
movlw B'11111111' ; w := 11111010 binary
tris PORTB ; port B ctrl register := w
movlw B'00111000' ; w := 11111010 binary outputs
are on for lcd only!!!
tris PORTC ; port c ctrl register := w
nop
nop
btfss PORTB,7 ; test for cable if there loop
GOTO CABLE
GOTO NORMAL ; normal operation
CABLE:
CALL INITLCD ; initialize lcd for 4 bit mode

movlw A' ' ; ascii " "


CALL LCDCHAR
movlw A' ' ; ascii " "
CALL LCDCHAR
movlw A' ' ; ascii " "
CALL LCDCHAR
movlw A' ' ; ascii " "
CALL LCDCHAR
movlw A'C' ; ascii "C"
CALL LCDCHAR
movlw A'A' ; ascii "A"
CALL LCDCHAR
movlw A'L' ; ascii "L"
CALL LCDCHAR
movlw A' ' ; ascii " "
CALL LCDCHAR
movlw A'M' ; ascii "M"
CALL LCDCHAR
movlw A'O' ; ascii "O"
CALL LCDCHAR
movlw A'D' ; ascii "D"
CALL LCDCHAR
movlw A'E' ; ascii "E"
CALL LCDCHAR
CABLE3: GOTO CABLE3
;=====================if no cable normal operation then norma operation=========
===============
NORMAL:
; port A is for rs232 serial comunications bit 5 is for LCD data4
; port B is for 7756 comunication and control
; port C is for LCD data, LCD control and serial epprom
bcf STATUS,6
bsf STATUS,5 ; set to bank 1
movlw H'06' ; set port a to digital same as 16C62B
movwf ADCON1
clrf PIE1 ; clr register in bank 1
clrf PIE2 ; clr register in bank 1
bcf STATUS,5 ; set to bank 0
movlw B'11010110' ; w := 11111010 binary
tris PORTA ; port A ctrl register := w
; port A is 4 bits wide
;
; ra0 and ra1 will be used for serial com
; ra0 as xmit rs232
; ra1 as rcv rs232
; ra2 will be used for lcd enable
; ra3 lcd enable
; ra4 will serve as interrupt in
; ra5 LCD databit 4
; setting a bit to '1' = an input
movlw B'010000111' ; w := 11000011 binary
tris PORTB ; port B ctrl register := w
; sets rb0 and rb1 as in
; set rb1,2,3,4,5,6 as out for com with 7756
; rb0 in from /IRQ on 7756 input
; rb1 input from rms select input
; rb2 not used output
; rb3 out to /reset in on 7756 output
; rb4 out to /chip select on 7756 output
; rb5 out to serial clock on 7756 output
;
movlw B'00010000'
tris PORTC ; port C ctrl register := w

movlw B'10111100' ; w := 00111100 binary


movwf PORTB ; port B itself := w sets all output of PORTB hi
gh
bsf PORTA,0 ; set PORTA bit 0 to "1" rs232 inactive state
bcf PORTB,7 ; set clk to low
bcf PORTB,3 ; set /reset to 7756 low
bsf PORTB,3 ; set /reset to 7756 high
bsf PORTB,4 ; set /cs to 7756 high
;--------------- this will set timer 0 to ff and no prescale increment on fallin
g
; edge. This will generate and interrupt and service serial in rou
tine
;
; ; 1 enable 0 disable
clrf INTCON ; set intcon to 00000000
bcf INTCON,7 ; disable all interrupts CLR DISA
BLE
bcf INTCON,6 ; enable disable peripheral int bits CLR DISA
BLE
bcf INTCON,5 ; enable tmr0 overflow interrupt CLR DISA
BLE
bsf INTCON,4 ; enable rb0/int CLR DISA
BLE
bcf INTCON,3 ; PORT B INTERRUPT ON CHANGE CLR DISA
BLE
bcf INTCON,2 ; clear tmr0 overflow interrupt bit
bcf INTCON,1 ;
bcf INTCON,0 ;
bcf INTCON,7 ; disable all interrupts
bsf STATUS,5 ; set to bank 1
bcf OPTION_REG,7 ; enable pullups on port b
bcf OPTION_REG,6 ; int in falling edg of rb0/int
; bsf OPTION_REG,5 ; select ra4/tocki as source input to tmr0
; bsf OPTION_REG,4 ; inc tmr0 on (set for rising clr for falling) e
dge
; bsf OPTION_REG,3 ; set prescale to wdt
; bcf OPTION_REG,2 ; set prescale to 0
; bcf OPTION_REG,1 ; set prescale to 0
; bcf OPTION_REG,0 ; set prescale to 0
bcf PIE1,7 ; always clear
bcf PIE1,6 ; A/D converter interrupt enable
bcf PIE1,5 ; always clear
bcf PIE1,4 ; always clear
bcf PIE1,3 ; ssp port interrupt enable
bcf PIE1,2 ; ccp1 int enable
bcf PIE1,1 ; tmr2 int enable
bcf PIE1,0 ; tmr1 int enable for energy measure
clrf TMR1L ; clear timer 1 low byte
clrf TMR1H ; clear timer 1 high byte
bcf STATUS,5 ; set to bank 0
; movlw H'FF'
movwf TMR0 ; set timer 0 to FF prep for overflow

;------------------------------ setup timer 1 for energy dump-------------------


-------------
movlw B'00110000'
movwf T1CON ; sets up timer 1 prescale/8 increment on intern
al xtal/4
; start and stop is bit 0
;------------------------------ setup spi port for 7756 communication SCLK = 20M
hz/16--------
;
; movlw B'00110000'
; movwf T1CON ; sets up timer 1 prescale/8 increment on intern
al xtal/4
; ; start and stop is bit 0
;

;------------------------------setup spi port for 7756 communication------------


------------------------------------------
; movlw B'00000010' ;set up spi as master fos/64 idle state high
movlw B'00000001' ;set up spi as master fos/16 idle state high
; movlw B'00000000' ;set up spi as master fos/4 idle state high
movwf SSPCON ; mov w to spi control register
movlw B'00000000'
bsf STATUS,5 ; set to bank 1
movwf SSPSTAT ; set up clk edges
bcf STATUS,5 ; set to bank 0
; movlw B'00100000' ; set up spi as master fos/4 idle state
high
; movlw B'00100001' ; set up spi as master fos/16 idle state
high
; movwf SSPCON ; mov w to spi control register
bsf SSPCON,5
;------------------------------end port setup-----------------------------------
-------------------
;------------------------------clear all registers------------------------------
-------------------
clrf spi
clrf outd1
clrf outd2
clrf mem
clrf carry
clrf wordlen
clrf wait
clrf wait2
clrf bcd0
clrf bcd1
clrf bcd2
clrf bcd3
clrf bcd4
clrf bin0
clrf bin1
clrf bin2
clrf bin3
clrf bin4
clrf mode0
clrf mode1
clrf swap_w
clrf swap_status
clrf sinwait
clrf bcdtemp
clrf lcdout
clrf lcdup
clrf lcdlow
clrf wait3
clrf insd1
clrf insd2
clrf insd3
clrf insd4
clrf insd5
clrf insd6
clrf insd7
clrf insd8
clrf insd9
clrf insd10
clrf insd11
clrf sample_high
clrf sample_middle
clrf sample_low
bsf STATUS,5 ; set to bank 1
clrf icof1
clrf icof2
clrf vcof1
clrf vcof2
clrf coffdiv
clrf rmsch
bcf STATUS,5 ; set to bank 0
CALL INITLCD ; initialize lcd for 4 bit mode
CALL ENERGYSET ; recall saved energy from eeprom
CALL KWH ; recall calibration values from eeprom and writ
e to ADE7756 registers

;****--------------Start of read power routine normal operation ----------------


--------
clrf dave1 ; zero sample counter
clrf dave2
clrf contint ; clear int count for next interrupt
bsf INTCON,7 ; enable all unmasked interrupts
bsf point,6
GOTO START1
ENGREAD1:
movlw B'00000011' ; mov 03 into w register
movwf spi ; output to spi read active energy and reset
movlw b'00010000' ; number of bytes to download B'000(5)(4)(3)(2)(
1)'
movwf wordlen ; wordlen is 40 bits. reg is actually 40 bits
CALL SPIRX ; CALL SPI read 40 bit word data will be in
; insd1,2,3,4,5. 5 being msb 1 being lsb
;---------------test polarity before add and sign extend if necessary-----------
------------------------------------
movlw B'00000000' ; this sign extends the 40 bit energy register p
ositive
movwf insd6 ; to be added to the 80 bit accum. energy regist
er
movwf insd7
movwf insd8
movwf insd9
movwf insd10
movwf insd11
btfss insd5,7
GOTO POSITIVEE
movlw B'11111111' ; this sign extends the 40 bit energy register n
egative
movwf insd6 ; to be added to the 80 bit accum. energy regist
er
movwf insd7
movwf insd8
movwf insd9
movwf insd10
movwf insd11
POSITIVEE:
btfss insd5,7 ; test polarity of acc energy
GOTO POSPOL
movlw B'00001000' ; upper 4 bits of next command
CALL LCD ; output command to lcd
movlw B'00001111' ; lower 4 bits of last command display shift to
location 40
CALL LCD ; output command to lcd
movlw A'*' ; ascii "*" = Negative Energy accumulated di
splay updated each energy rear
CALL LCDCHAR ; output character to LCD
GOTO POLDONE
POSPOL:
movlw B'00001000' ; upper 4 bits of next command
CALL LCD ; output command to lcd
movlw B'00001111' ; lower 4 bits of last command display shift to
location 40
CALL LCD ; output command to lcd
movlw A' ' ; ascii " " = Positive Energy accumulated
CALL LCDCHAR ; output character to LCD
POLDONE:
CALL MULTBYCOEF ; multiply by energy coeff then add to 88 bit en
ergy accumulator
CALL PLUSORMINUS ; divide energy accu by 2^40 and make positive
CALL DISPLAYKWH ; mov energy to bin0-4 then output kwh( )or(-)
CALL BIN2BCD ; convert bin0-4 to bcd
CALL LCDUPDATE ; convert bcd to ascII and output to lcd add dec
imal and remove if indicated
; unwanted resolution
RETURN

;---------------Multiply the 40-bit read by the econstant register to convert re


gister in WattHour---------------
MULTBYCOEF:

movf econstant0,w ; mov econstant0 to mem


movwf mem ; mem will be cleared during multiply
CALL MULT10
movf econstant1,w ; mov econstant1 to mem
movwf mem ; mem will be cleared during multiply
CALL MULT10
movf econstant2,w ; mov econstant2 to mem
movwf mem ; mem will be cleared during multiply
CALL MULT10
RETURN

MULT10:
movlw D'8' ; number of bits to multiply
movwf wordlen ; mov 40 into wordlen
MULTLOOP0: ;
;
btfsc mem,0 ; if bit is 1 add insd1-9 to aenergy0-10
CALL ADDEGY ; add insd1-11 to energy accu.
bcf STATUS,0 ;
rrf mem,1 ; rotate constant for next bit to multiply
bcf STATUS,0
rlf insd1,1 ; rotate for next add
rlf insd2,1 ; rotate for next add
rlf insd3,1 ; rotate for next add
rlf insd4,1 ; rotate for next add
rlf insd5,1 ; rotate for next add
rlf insd6,1 ; rotate for next add
rlf insd7,1 ; rotate for next add
rlf insd8,1 ; rotate for next add
rlf insd9,1 ; rotate for next add
rlf insd10,1 ; rotate for next add
rlf insd11,1 ; rotate for next add Register is long enought b
y mult 32 bits
bcf STATUS,0
decfsz wordlen,1
GOTO MULTLOOP0 ; repeat
RETURN
ADDEGY:
;-----------------------40 bit add routine results in 88 bit aenergy0-10 10msb
movf insd1,w
bsf STATUS,5 ; page 1
addwf aenergy0,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy1,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy2,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy3,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy4,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy5,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy6,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy7,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy8,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy9,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy10,1
bcf STATUS,5 ; page 1

movf insd2,w
bsf STATUS,5 ; page 1
addwf aenergy1,1
bcf STATUS,5 ; page 1
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy2,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy3,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy4,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy5,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy6,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy7,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy8,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy9,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy10,1
bcf STATUS,5 ; page 0

movf insd3,w
bsf STATUS,5 ; page 1
addwf aenergy2,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy3,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy4,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy5,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy6,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy7,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy8,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy9,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy10,1
bcf STATUS,5 ; page 0

movf insd4,w
bsf STATUS,5 ; page 1
addwf aenergy3,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy4,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy5,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy6,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy7,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy8,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy9,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy10,1
bcf STATUS,5 ; page 0
movf insd5,w
bsf STATUS,5 ; page 1
addwf aenergy4,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy5,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy6,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy7,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy8,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy9,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy10,1
bcf STATUS,5 ; page 0

movf insd6,w
bsf STATUS,5 ; page 1
addwf aenergy5,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy6,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy7,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy8,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy9,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy10,1
bcf STATUS,5 ; page 0

movf insd7,w
bsf STATUS,5 ; page 1
addwf aenergy6,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy7,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy8,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy9,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy10,1
bcf STATUS,5 ; page 0

movf insd8,w
bsf STATUS,5 ; page 1
addwf aenergy7,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy8,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy9,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy10,1
bcf STATUS,5 ; page 0
movf insd9,w
bsf STATUS,5 ; page 1
addwf aenergy8,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy9,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy10,1
bcf STATUS,5 ; page 0
movf insd10,w
bsf STATUS,5 ; page 1
addwf aenergy9,1
bcf STATUS,5 ; page 0
CALL CARRYCHK
movf carry,w
bsf STATUS,5 ; page 1
addwf aenergy10,1
bcf STATUS,5 ; page 0
movf insd11,w
bsf STATUS,5 ; page 1
addwf aenergy10,1
bcf STATUS,5 ; page 0
RETURN

CARRYCHK:
clrf carry ; clear carry register
btfsc STATUS,0 ; test status reg carry bit. skip if clr
incf carry,1 ; increment carry
RETURN
;-----------------------------end 40 bit add routine------------------------
PLUSORMINUS:
;-------------divide by 2^40 the result of Aenergyxeconstant
; mov aenergy5-10 to e0-e5 for temporary manipulation before conversion to ascII
bsf STATUS,5 ; page 1
movf aenergy5,w
movwf e0
movf aenergy6,w
movwf e1
movf aenergy7,w
movwf e2
movf aenergy8,w
movwf e3
movf aenergy9,w
movwf e4
movf aenergy10,w
movwf e5
btfss aenergy10,7 ;test for sign extension
GOTO PLORMIEND
comf e0,1 ; complement and add 1
comf e1,1
comf e2,1
comf e3,1
comf e4,1
comf e5,1
bcf STATUS,0 ; clear carry
movlw B'00000001'
addwf e0,1 ; add 1 and ripple if carry jump when no carry t
o PLORMIEND
btfss STATUS,0
GOTO PLORMIEND
bcf STATUS,0 ; clear carry
movlw B'00000001'
addwf e1,1
btfss STATUS,0
GOTO PLORMIEND
bcf STATUS,0 ; clear carry
movlw B'00000001'
addwf e2,1
btfss STATUS,0
GOTO PLORMIEND
bcf STATUS,0 ; clear carry
movlw B'00000001'
addwf e3,1
btfss STATUS,0
GOTO PLORMIEND
bcf STATUS,0 ; clear carry
movlw B'00000001'
addwf e4,1
bcf STATUS,0 ; clear carry
GOTO PLORMIEND
bcf STATUS,0 ; clear carry
movlw B'00000001'
addwf e5,1
bcf STATUS,0 ; clear carry

PLORMIEND:
bcf STATUS,5 ; page 0
RETURN

;----------------Display the result kWhour on the LCD---------------------------


; moves the selected range of the energy accumulator (aenergy0:10) for bin2bcd c
onversion
DISPLAYKWH:
bsf STATUS,5 ; page 1
movf e0,w
bcf STATUS,5 ; page 0
movwf bin0 ; mov energy5-9 to bin 0-4 for bcd conversion
bsf STATUS,5 ; page 1
movf e1,w
bcf STATUS,5 ; page 0
movwf bin1
bsf STATUS,5 ; page 1
movf e2,w
bcf STATUS,5 ; page 0
movwf bin2
bsf STATUS,5 ; page 1
movf e3,w
bcf STATUS,5 ; page 0
movwf bin3
bsf STATUS,5 ; page 1
movf e4,w
bcf STATUS,5 ; page 0
movwf bin4

movlw B'00001000' ; upper 4 bits of next command


CALL LCD ; output command to lcd
movlw B'00000000' ; lower 4 bits of last command display shift to
location 40
CALL LCD ; output command to lcd

CALL DELCD ; wait for last LCD command to complete


CALL DELCD
CALL DELCD
CALL DELCD

movlw A'K' ; ascii "K"


CALL LCDCHAR ; output char to lcd
movlw A'w' ; ascii "w"
CALL LCDCHAR ; output char to lcd
movlw A'h' ; ascii "h"
CALL LCDCHAR ; output char to lcd
bsf STATUS,5 ; page1
btfss aenergy10,7 ; test for sign extension
GOTO PSIGN0 ; displays "-" sign if neg energy
bcf STATUS,5 ; page 0
movlw A'-' ; ascii "-"
CALL LCDCHAR ; output char to lcd
GOTO PSIGN1
PSIGN0:
bcf STATUS,5 ; page 0
movlw A' ' ; ascii " " if positive
CALL LCDCHAR
PSIGN1:
RETURN
;-------------------------------------------------------------------------------
---------
; CALL EEPWAIT
EEPWAIT: ; wait for spi buffer to empty
bsf STATUS,5 ; set to bank 1
MXLOOP1:
btfss SSPSTAT,0 ; wait for completion
GOTO MXLOOP1
bcf STATUS,5
RETURN
ENERGYSET:
;-----------------------------Save the Active Energy in the EEPROM--------------
----------
; first two writes set up start address for block read. each word is shifted out
after 8 clock pulses.
; keep clocking and each work is sent out in order until eeprom cs is set high.
will roll over to the
; address after 16 words.
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; write instruction
bcf mcsb ; clear chip select for eeprom
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000000' ; start at address 00
bcf mcsb ; clear chip select for eeprom
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT

CALL MEMDATAIN ; read 8 bit of data from eeprom starting at 00


inc address each memdatain until
; mcsb goes hi
bsf STATUS,5 ; page1
movwf aenergy0
bcf STATUS,5 ; page0
CALL MEMDATAIN
bsf STATUS,5 ; page1
movwf aenergy1
bcf STATUS,5 ; page0
CALL MEMDATAIN
bsf STATUS,5 ; page1
movwf aenergy2
bcf STATUS,5 ; page0

CALL MEMDATAIN
bsf STATUS,5 ; page1
movwf aenergy3
bcf STATUS,5 ; page0
CALL MEMDATAIN
bsf STATUS,5 ; page1
movwf aenergy4
bcf STATUS,5 ; page0

CALL MEMDATAIN
bsf STATUS,5 ; page1
movwf aenergy5
bcf STATUS,5 ; page0

CALL MEMDATAIN
bsf STATUS,5 ; page1
movwf aenergy6
bcf STATUS,5 ; page0

CALL MEMDATAIN
bsf STATUS,5 ; page1
movwf aenergy7
bcf STATUS,5 ; page0

CALL MEMDATAIN
bsf STATUS,5 ; page1
movwf aenergy8
bcf STATUS,5 ; page0

CALL MEMDATAIN
bsf STATUS,5 ; page1
movwf aenergy9
bcf STATUS,5 ; page0

CALL MEMDATAIN
bsf STATUS,5 ; page1
movwf aenergy10
bcf STATUS,5 ; page0
bsf mcsb ; write enable eeprom
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
RETURN
ENERGYDUMP:
; dump energy to eeprom starting at address 00 when called by inte
rrupt routine
: after sag is detected
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
;===============================================================================
=====
bsf csb ; set 7756 csb to high if not already
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000110' ; WREN instruction
bcf mcsb ; clear chip select for eeprom
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT ; wait for spi buff to be empty
bsf mcsb ; write enable eeprom
;===============================================================================
======

bsf STATUS,5 ; set to bank 1


bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000010' ; write instruction
bcf mcsb ; clear chip select for eeprom
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000000' ; start at address 00
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
bsf STATUS,5 ; page 1
movf aenergy0,w
bcf STATUS,5 ; page 0
CALL MEMDATAOUT ; start at address 00 and increment for each mem
dataout
bsf STATUS,5 ; page 1
movf aenergy1,w
bcf STATUS,5 ; page 0
CALL MEMDATAOUT
bsf STATUS,5 ; page 1
movf aenergy2,w
bcf STATUS,5 ; page 0
CALL MEMDATAOUT
bsf STATUS,5 ; page 1
movf aenergy3,w
bcf STATUS,5 ; page 0
CALL MEMDATAOUT
bsf STATUS,5 ; page 1
movf aenergy4,w
bcf STATUS,5 ; page 0
CALL MEMDATAOUT
bsf STATUS,5 ; page 1
movf aenergy5,w
bcf STATUS,5 ; page 0
CALL MEMDATAOUT
bsf STATUS,5 ; page 1
movf aenergy6,w
bcf STATUS,5 ; page 0
CALL MEMDATAOUT
bsf STATUS,5 ; page 1
movf aenergy7,w
bcf STATUS,5 ; page 0
CALL MEMDATAOUT
bsf STATUS,5 ; page 1
movf aenergy8,w
bcf STATUS,5 ; page 0
CALL MEMDATAOUT
bsf STATUS,5 ; page 1
movf aenergy9,w
bcf STATUS,5 ; page 0
CALL MEMDATAOUT
bsf STATUS,5 ; page 1
movf aenergy10,w
bcf STATUS,5 ; page 0
CALL MEMDATAOUT
bsf mcsb ; setting memory /cs starts block write in eepro
m
CALL CHECKWRITE ; is write complete???
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
RETURN
MEMDATAOUT:
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
RETURN
CHECKWRITE:
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000101' ;read status register
bcf mcsb ; clear chip select for eeprom
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
CALL MEMDATAIN
bsf mcsb ; set chip select for eeprom
btfsc SSPBUF,0 ; check to see if wpi bit is set if so repeat un
til clear
GOTO CHECKWRITE
RETURN
SPIEEPROM:
; CALL SPIEEPROM
;------------------------------setup spi port---------------------------
---------------------------
bsf csb ; clear enable for csb 7756
bcf SSPCON,5 ; disable port for reconfiguring
movlw B'01000000'
bsf STATUS,5 ; set to bank 1
movwf SSPSTAT ; set up clk edges
bcf STATUS,5 ; set to bank 0
bsf SSPCON,5 ; enable spi port after changes
RETURN
MEMDATAIN:
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movf H'0',w ; lower eight bits
movwf SSPBUF ; output starts after mov command
bsf STATUS,5 ; set to bank 1
CALL EEPWAIT
movf SSPBUF,w
RETURN

SPI7756:
;------------------------------ setup spi port CALL SPI7756 ------------------
------------------------------------

bcf SSPCON,5 ; disable port for reconfiguring


movlw B'00000000'
bsf STATUS,5 ; set to bank 1
movwf SSPSTAT ; set up clk edges
bcf STATUS,5 ; set to bank 0
bsf SSPCON,5 ; enable spi port after changes
RETURN
;---------------------------------------------------------
;
;start read of spi port of X bit reg defined by spicnt
;
;----------------------------------------------------------

SPIRX:
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movf spi,w ; spi control word (first 8 bits)
bcf csb ; set to 0 /cs pin
movwf SSPBUF ; output 8 bit word msb first
bsf STATUS,5 ; set to bank 1
LOOPSPI:
btfss SSPSTAT,0 ; wait for completion
GOTO LOOPSPI ; wait for output buffer empty
bcf STATUS,5 ; set to bank 0
clrf insd1 ; clear input data registers
clrf insd2
clrf insd3
clrf insd4
clrf insd5
btfsc wordlen,4 ; input 40 bits if set 5 bytes
GOTO bit40
btfsc wordlen,3 ; input 32 bits if set 4 bytes
GOTO bit32
btfsc wordlen,2 ; input 24 bits if set 3 bytes
GOTO bit24
btfsc wordlen,1 ; input 16 bits if set 2 bytes
GOTO bit16
btfsc wordlen,0 ; input 8 bits if set 1 bytes
GOTO bit8

bit40:
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movf H'0',w ; lower eight bits
movwf SSPBUF
bsf STATUS,5 ; set to bank 1
LOOP40:
btfss SSPSTAT ; wait for completion
GOTO LOOP40
bcf STATUS,5 ; set to bank 0
movf SSPBUF,w
movwf insd5

bit32:
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movf H'0',w ; lower eight bits
movwf SSPBUF
bsf STATUS,5 ; set to bank 1
LOOP32:
btfss SSPSTAT,0 ; wait for completion
GOTO LOOP32
bcf STATUS,5 ; set to bank 0
movf SSPBUF,w
movwf insd4

bit24:
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movf H'0',w ; lower eight bits
movwf SSPBUF
bsf STATUS,5 ; set to bank 1
LOOP24:
btfss SSPSTAT,0 ; wait for completion
GOTO LOOP24
bcf STATUS,5 ; set to bank 0
movf SSPBUF,w
movwf insd3

bit16:
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movf H'0',w ; lower eight bits
movwf SSPBUF
bsf STATUS,5 ; set to bank 1
LOOP16:
btfss SSPSTAT,0 ; wait for completion
GOTO LOOP16
bcf STATUS,5 ; set to bank 0
movf SSPBUF,w
movwf insd2

bit8:
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movf H'0',w ; lower eight bits
movwf SSPBUF
bsf STATUS,5 ; set to bank 1
LOOP8:
btfss SSPSTAT,0 ; wait for completion
GOTO LOOP8
bcf STATUS,5 ; set to bank 0
movf SSPBUF,w
movwf insd1
bsf csb ; set /cs to 1
RETURN

;------------------------end spi control write----------------------


;-----------------------------------------------------------
;
; This routine writes to the 7756 spi control
; control data (first 8 bits before data read or write)
;
; OUTPUT 8 BIT SPI CONTROL AND 8 OR 16 BIT DATA
; 34us FOR 8+16 BIT AND 26us FOR 8+8 BIT
;-------------------------------------------------------------------

SPIDX:
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movf spi,w
bcf csb ; set to 0 /cs pin
movwf SSPBUF ; output 8 bit word msb first
bsf STATUS,5 ; set to bank 1
TXLOOP1:
btfss SSPSTAT,0 ; wait for completion
GOTO TXLOOP1
;------------------------end spi control write----------------------
;------------------------start of data------------------------------
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
btfsc wordlen,3 ; test for 8 or 16 bits
GOTO eight
movf outd2,w ; upper eight bits
movwf SSPBUF ; move word to buffer
bsf STATUS,5 ; set to bank 1
TXLOOP2:
btfss SSPSTAT,0 ; wait for completion
GOTO TXLOOP2
eight:
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 01
movf outd1,w ; lower eight bits
movwf SSPBUF
bsf STATUS,5 ; set to bank 1
TXLOOP3:
btfss SSPSTAT,0 ; wait for completion
GOTO TXLOOP3
bcf STATUS,5

bsf csb ; set /cs to 1


RETURN

;-----------------end spi control and data (x) out--------------------


;----------------------------ASCII 8 bit to 2 4bit words for lcd------

LCDCHAR:
movwf lcdup ;
movwf lcdlow ;
movlw B'11110000' ; for masking lower bits
andwf lcdup,1 ; lcdupper= xxxx0000
swapf lcdup,1 ; lcdupper= 0000xxxx
movlw B'00010000' ; add data command to lcd output
addwf lcdup,0 ; " " "
CALL LCD ; output upper 4 bits to lcd
movlw B'00001111' ; for masking upper bits
andwf lcdlow,1 ; lcdlower= 0000xxxx
movlw B'00010000' ; add data command to lcd output
addwf lcdlow,0 ; " " "
CALL LCD ; output lower 4 bits
RETURN
;------------------end ascii convert for lcd--------------------------

KWH:

;-------------------------------------------------------------------------------
----------------------------
;-----------------This initializes the part as a power meter--------------------
----------------------------
; 156us for 8bit control and 16 bit data, 112us for 8bit control and 8 bit out

; RECALL 7756 SETTINGS FROM EEPROM

; first two writes set up start address for block read. each word is shifted out
after 8 clock pulses.
; keep clocking and each work is sent out in order until eeprom cs is set high.
will roll over to the
; address after 16 words.

;------------------------------cf read------------------------------------------
----------------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom rising edge
transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'16' ; start at address 16 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 16
movwf outd1
CALL MEMDATAIN ; get address 17
movwf outd2
movlw B'10000111' ; command to write to cfdiv register
movwf spi ; call spi control write to cfdiv reg
movlw D'16' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 and outd2 to 7756
;-------------------------------------------------------------------------------
------------------------------

;------------------------------apgain read--------------------------------------
------------------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'18' ; start at address 18 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 18
movwf outd1
CALL MEMDATAIN ; get address 19
movwf outd2
movlw B'10001011' ; command to write to apgain register
movwf spi ; call spi control write to apgain reg
movlw D'16' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 and outd2 to 7756
;-------------------------------------------------------------------------------
------------------------------
;------------------------------apos read----------------------------------------
------------------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'37' ; start at address 37 PAGE 3
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 37
movwf outd1
CALL MEMDATAIN ; get address 38
movwf outd2
movlw B'10001101' ; command to write to apos register
movwf spi ; call spi control write to apos reg
movlw D'16' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 and outd2 to 7756
;-------------------------------------------------------------------------------
------------------------------
;------------------------------icoef--------------------------------------------
-------------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'21' ; start at address 21 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 21
movwf outd1
movlw B'10001000' ; command to write to ch1os register
movwf spi ; call spi control write to ch1os reg
movlw D'8' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 to 7756
;-------------------------------------------------------------------------------
------------------------------
;------------------------------ch2os read---------------------------------------
----------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'22' ; start at address 22 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 22
movwf outd1
movlw B'10001001' ; command to write to ch2os register
movwf spi ; call spi control write to ch2os reg
movlw D'8' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 to 7756
;-------------------------------------------------------------------------------
------------------------------
;------------------------------gain read----------------------------------------
---------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'23' ; start at address 23 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 23
movwf outd1
movlw B'10001010' ; command to write to gain register
movwf spi ; call spi control write to gain reg
movlw D'8' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 to 7756
;-------------------------------------------------------------------------------
------------------------------
;------------------------------phcal read--------------------------------------
-----------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'24' ; start at address 24 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 24
movwf outd1
movlw B'10001100' ; command to write to phcal register
movwf spi ; call spi control write to phcal reg
movlw D'8' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 to 7756
;-------------------------------------------------------------------------------
------------------------------
;------------------------------sagcyc read-------------------------------------
------------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'25' ; start at address 25 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 25
movwf outd1
movlw B'10001111' ; command to write to sagcyc register
movwf spi ; call spi control write to sagcyc reg
movlw D'8' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 to 7756
;-------------------------------------------------------------------------------
------------------------------
;------------------------------saglvl read-------------------------------------
------------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'26' ; start at address 26 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 26
movwf outd1
movlw B'10010001' ; command to write to saglvl register
movwf spi ; call spi control write to saglvl reg
movlw D'8' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 and outd2 to 7756
;-------------------------------------------------------------------------------
------------------------------
;------------------------------mask read---------------------------------------
----------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'27' ; start at address 27 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 27
movlw b'00000010'
movwf outd1
movlw B'10010000' ; command to write to mask register
movwf spi ; call spi control write to mask reg
movlw D'8' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 to 7756
;-------------------------------------------------------------------------------
------------------------------
;------------------------------mode read----------------------------------------
---------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'28' ; start at address 28 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 28
movwf outd1
movwf mode0
CALL MEMDATAIN ; get address 29
movwf outd2
movwf mode1
movlw B'10000110' ; command to write to mode register
movwf spi ; call spi control write to mode reg
movlw D'16' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 and outd2 to 7756
;-------------------------------------------------------------------------------
------------------------------
;------------------------------zxout read---------------------------------------
----------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'30' ; start at address 30 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 30
movwf outd1
CALL MEMDATAIN ; get address 31
movwf outd2
movlw B'10001110' ; command to write to zxout register
movwf spi ; call spi control write to zxout reg
movlw D'16' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ; output outd1 and outd2 to 7756
;-------------------------------------------------------------------------------
------------------------------
;------------------------------constant1 read----------------------------------
---------------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'32' ; start at address 32 PAGE 3
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 32
movwf econstant0
CALL MEMDATAIN ; get address 33
movwf econstant1
CALL MEMDATAIN ; get address 34
movwf econstant2
CALL MEMDATAIN ; get address 35 set bit 7 to show watts clr to
show tenths of watts
movwf point
CALL MEMDATAIN ; get address 36 temp offset
movwf tempof
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.

;-------------------------------------------------------------------------------
------------------------------
;------------------------------Current Offset and voltage offset for rms--------
----------------------------
CALL SPIEEPROM ; call routine to setup spi port for eeprom risi
ng edge transfer
bcf mcsb ; clear chip select for eeprom
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw B'00000011' ; read instruction
movwf SSPBUF ; output 8 bit word msb first (mode and A8 bit)
CALL EEPWAIT
bsf STATUS,5 ; set to bank 1
bcf SSPSTAT,0 ; clear buffer full flag
bcf STATUS,5 ; set to bank 0
movlw D'48' ; start at address 48 PAGE 2
movwf SSPBUF ; output 8 bit word msb first
CALL EEPWAIT
CALL MEMDATAIN ; get address 48
bsf STATUS,5
movwf icof1
bcf STATUS,5
CALL MEMDATAIN ; get address 49
bsf STATUS,5
movwf icof2
bcf STATUS,5
CALL MEMDATAIN ; get address 50
bsf STATUS,5
movwf vcof1
bcf STATUS,5
CALL MEMDATAIN ; get address 51
bsf STATUS,5
movwf vcof2
bcf STATUS,5
CALL MEMDATAIN ; get address 48
bsf STATUS,5
movwf ioffset1
bcf STATUS,5
CALL MEMDATAIN ; get address 49
bsf STATUS,5
movwf ioffset2
bcf STATUS,5
CALL MEMDATAIN ; get address 50
bsf STATUS,5
movwf voffset1
bcf STATUS,5
CALL MEMDATAIN ; get address 51
bsf STATUS,5
movwf voffset2
bcf STATUS,5
bsf mcsb ; clear chip select for eeprom
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ;
RETURN
;-------------------------------------------------------------------------------
------------------------------
LCD:
movwf lcdout ; mov lcd data+ins/char into lcdout
LCDL:
bcf lcde ; set lcde low
bcf lcdrw ; set lcd to write
bcf lcdrs ; set rs bit low
bcf lcd4 ; clears lcd databit 4-7
bcf lcd5
bcf lcd6
bcf lcd7
btfsc lcdout,0 ; test lcd data bit 0 if set set lcd4
bsf lcd4
btfsc lcdout,1 ; test lcd data bit 1 if set set lcd5
bsf lcd5
btfsc lcdout,2 ; test lcd data bit 2 if set set lcd6
bsf lcd6
btfsc lcdout,3 ; test lcd data bit 3 if set set lcd7
bsf lcd7
btfsc lcdout,4 ; test lcd data bit 4 if set set lcdrs instructi
on or character
bsf lcdrs
CALL DELAY ; wait for data to stablize before enable
CALL DELAY2 ;removed 45 CALL DELAY2's incase of problem 20 mhz
bsf lcde ; set lcde high for enable
CALL DELAY ; sets enable pulse width
CALL DELAY ; sets enable pulse width
CALL DELAY2 ;removed 45 CALL DELAY2's incase of problem 20 mhz
bcf lcde ; set lcde low to latch data
RETURN
;------------------------------------------------------------------------------
DELCD: ; called in initLCD routine
movlw D'100'
movwf wait3 ; mov 100 into wait3 loop
WAIT3:
decfsz wait3,1 ; dec wait if zero return
GOTO WAIT3
RETURN ; return to lcd routine

;-----------------end of ram to ad7756 register transfer----------------


RETURN
;-----------------------------------------------------------
; This is a delay loop USED EVERYWHERE for the LCD routine
;-----------------------------------------------------------

DELAY: ; called in rs232 routine


movlw D'27'
movwf wait ; mov 20 into wait loop
WAIT:
decfsz wait,1 ; dec wait if zero return
GOTO WAIT
RETURN ; return to rs232 routine

DELAY2: ; called in initLCD routine


movlw D'255'
movwf wait2 ; mov 255 into wait2 loop
WAIT2:
decfsz wait2,1 ; dec wait if zero return
GOTO WAIT2
RETURN ; return to initlcd routine
;---------------------------end serial output routine---------------------------
--
INITLCD:
; sets lcd up for 4bit mode. setup from lcd datasheet
bCf STATUS,5 ; GOTO PAGE 0
movlw D'150'
movwf wait
LCDLOOP:
CALL DELAY2 ;wait loop1
decfsz wait,1
GOTO LCDLOOP
movlw B'00000011' ; send 3 to lcd for the 1st time
CALL LCD
movlw D'60'
movwf wait
LCDLOOP1:
CALL DELAY2 ;wait loop 2
decfsz wait,1
goto LCDLOOP1
movlw B'00000011' ; send 3 to lcd for the 2nd time
CALL LCD ; call lcd output routine
CALL DELAY2 ;removed 45 CALL DELAY2's incase of problem 20 m
hz
CALL DELAY2 ;removed 45 CALL DELAY2's incase of problem 20 m
hz
CALL DELAY2 ;removed 45 CALL DELAY2's incase of problem 20 m
hz
CALL DELAY2 ;removed 45 CALL DELAY2's incase of problem 20 m
hz
movlw B'00000011' ; send 3 to lcd for the 3rd and last time
CALL LCD ; call lcd output routine
movlw B'00000010' ; set display to 4 bit mode
CALL LCD ; output command
movlw B'00000010' ; upper 4 bits of next command
CALL LCD ; output command
movlw B'00001000' ; lower 4 bits of last command Disp line and
font
CALL LCD ; output command
movlw B'00000000' ; upper 4 bits of next command
CALL LCD ; output command
movlw B'00001000' ; lower 4 bits of last command Display off
CALL LCD ; output command
movlw B'00000000' ; upper 4 bits of next command
CALL LCD ; output command
movlw B'00000001' ; lower 4 bits of last command Clear displa
y
CALL LCD ; output command
movlw D'30'
movwf wait
LCDLOOP2:
CALL DELCD
decfsz wait,1
GOTO LCDLOOP2

movlw B'00000000' ; upper 4 bits of next command


CALL LCD ; output command
movlw B'00000110' ; lower 4 bits of last command Entry mode
CALL LCD ; output command
movlw B'00000000' ; upper 4 bits of next command
CALL LCD ; output command
movlw B'00001100' ; lower 4 bits of last command Display on,cu
rsor off
CALL LCD ; output command blink off

RETURN
;----------------------------end initialization-----------------------------

;-------------------------------------------------------------------------------
; 24-bit binary to BCD conversion.
;
; Binary input data is taken from bin0-bin4 which is destroyed.
; The result is stored in bcd0..bcd3, bcd0 holds the two LS Digits.
;
;
;-------------------------------------------------------------------------------
BIN2BCD:

do_b2b:
movlw D'32' ;
movwf wordlen ;
clrf bcd0 ; clear bcd0
clrf bcd1 ; clear bcd1
clrf bcd2 ; clear bcd2
clrf bcd3 ; clear bcd3
clrf bcd4 ; clear bcd4
BCDLOOP:
bcf STATUS,0
rlf bin0,f ; rotate bin to left through carry
rlf bin1,f
rlf bin2,f
rlf bin3,f
btfsc STATUS,0
bsf 0x0C,0
rlf bcd0,f ; ...into bcd
rlf bcd1,f
rlf bcd2,f
rlf bcd3,f
rlf bcd4,f
decfsz wordlen,f
GOTO ADJUST
RETURN
ADJUST:
movlw H'2E' ; make magic adjustment to each BCD digit
movwf FSR ; mov address of bcd0 to indirect pointer
CALL ADJBCD
incf FSR,f ; increment pointer to bcd1
CALL ADJBCD
incf FSR,f ; increment pointer to bcd2
CALL ADJBCD
incf FSR,f ; increment pointer ro bcd3
CALL ADJBCD
incf FSR,f ; increment pointer ro bcd4
CALL ADJBCD
GOTO BCDLOOP
ADJBCD:
movf INDF,w ;
movwf bcdtemp ;
movlw 0x33 ;
addwf bcdtemp,f ;
clrw ;
btfss bcdtemp,3 ;
iorlw 0x03 ;
btfss bcdtemp,7 ;
iorlw 0x30 ;
subwf bcdtemp,f ;
movf bcdtemp,w ;
movwf INDF ;
RETURN
;-------------------end bcd convert-----------------------------------

LCDUPDATE:
btfss point,6
GOTO KWHDIGIT ;
bsf STATUS,5
btfsc rmsch,0
GOTO RMSSPACE
bcf STATUS,5

; movlw B'00000000' ; upper 4 bits of next command


; CALL LCD ; output command
; movlw B'00000010' ; lower 4 bits of last command Clear displa
y
; CALL LCD ; output command
movlw B'00001010' ; upper 4 bits of next command
CALL LCD ; output command
movlw B'00001000' ; lower 4 bits of last command display shift to
location 40
CALL LCD ; output command
movlw A'R' ; ascii "R"
LCALL LCDCHAR ; output rms to display
movlw A'M' ; ascii "M"
LCALL LCDCHAR
movlw A'S' ; ascii "S"
LCALL LCDCHAR
movlw A' ' ; ascii " "
LCALL LCDCHAR
GOTO RMSDIGIT
RMSSPACE:
GOTO RMSDIGIT
KWHDIGIT:
;--------------outputs aenergy to LCD-------------------------------------------
-------
bcf point,1 ; clr decimal pointers
bcf point,2
bcf point,3
movf bcd4,w ; mov aenergy to w
CALL BCD2ASCII ; output aenergy to serial or lcd 2 character pe
r call
movf bcd3,w ; mov aenergy to w
CALL BCD2ASCII ; output aenergy to serial or lcd 2 character pe
r call

; need to move 38 characters for 16 character display


; movlw B'00001010' ; upper 4 bits of next command
; CALL LCD ; output command
; movlw B'00001000' ; lower 4 bits of last command display shift to
location 40
; CALL LCD ; output command
movf bcd2,w ; mov aenergy to w
CALL BCD2ASCII ; output aenergy to serial or lcd 2 character pe
r call

;--------------------displays tenths of kwh .x

bcf STATUS,5
bsf point,1 ; set bit 2 to display 0.0000 1 for 0.000 or
0 for 0.00
movf bcd1,w ; mov aenergy to w
CALL BCD2ASCII ; output aenergy to serial or lcd 2 character pe
r call
bcf point,1

;-----------------remove rem to show watts .xxx


btfss point,7 ; if this bit is clear don't display last 2 digits from
eeprom
GOTO NOWATT
movf bcd0,w ; mov aenergy to w
CALL BCD2ASCII ; output aenergy to serial or lcd 2 character pe
r call

NOWATT:
RETURN
;--------------------displays tenths of kwh .x
RMSDIGIT:
bcf STATUS,5 ; Page 0
bcf point,0 ; set bit 2 to display 0.0000 1 for 0.000 or 0 for 0.
00
bcf point,1
btfss point,5 ; this bit is used to select .0 or .00 for rms output al
low the same
;routine to be used for Irms and Vrms
bsf point,0 ; set bit 2 to display 0.0000 1 for 0.000 or 0 for 0.
00
movf bcd1,w ; mov aenergy to w
CALL BCD2ASCII ; output aenergy to serial or lcd 2 character pe
r call
bcf point,0 ; clear decimal pointers
bcf point,1
btfsc point,5 ; test for I rms or vrms see above
bsf point,1 ; set bit 2 to display 0.0000 1 for 0.000 or 0 for 0.
00
btfss point,7
GOTO NOWATT
movf bcd0,w ; mov aenergy to w
CALL BCD2ASCII ; output aenergy to serial or lcd 2 character pe
r call
btfsc point,6
GOTO RMSDIGGAP
RETURN

RMSDIGGAP:
movlw A' ' ; ascii " " to put space between Irms and vrms
CALL LCDCHAR
movlw A' ' ; ascii " "
CALL LCDCHAR
RETURN
;-------------end output to lcd--------------------------------------------

;****------------------end of read power routine--------------------------------


---------
;*******************************************************************************
**********

BCD2ASCII:
;--------------------------------bcd0-4 to ascii convert------------------------
----------
; btfsc point,3
; mov aenergy value into w before calling routin
e
movwf msdbcd ; msdbcd
movwf lsdbcd ; lsdbcd
movlw B'11110000' ; for masking lower bits
andwf msdbcd,1 ; msdbcd = xxxx0000
swapf msdbcd,1 ; msdbcd = 0000xxxx
movlw B'00110000' ; add 48 to change bcd to ascii character of bcd
value
addwf msdbcd,0 ; "0011xxxx"
btfsc point,2
GOTO NODIGIT
CALL LCDCHAR ; output upper 4 bits to lcd
NODIGIT:
btfsc point,1 ; test for point
CALL POINT ;
movlw B'00001111' ; for masking upper bits
andwf lsdbcd ,1 ; lcdlower= 0000xxxx
movlw B'00110000' ; add 48 to change bcd to ascii character of bcd
value
addwf lsdbcd ,0 ; " " "er
CALL LCDCHAR ; output lower 4 bits to lcd
btfsc point,0 ; test for point
CALL POINT
RETURN
POINT:
movlw A'.' ; ascii "."
CALL LCDCHAR
RETURN
;--------------------------------end bcd to ascii to lcd character output-------
------------

START1:
; CALL GETDATA;------------------------------------------------LOOP----
---------------------------------------------------
; CALL ENGREAD1 ; Initial read before loop
GOTO START1 ; loop until interrupt

;------------------- interrupt routine--------------------------------


INTERRUPT:
CALL GETDATA ; dump waveform data
RETFIE ; return from interrupt

;-----------------LCD write routine--------------------------


;
; Data can be entered by movlw then CALL LCD
;------------------------------------------------------------

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rms routine %%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%

MODEMASK:
movf mode0,w
movwf outd1
movlw B'01011000' ; set mode register for waveform sampling
iorwf mode1,w
movwf outd2
movlw B'10000110' ; command to write to mode register
movwf spi ; call spi control write to mode reg
movlw D'16' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
LCALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
LCALL SPIDX ; mov lsb of word to output to outd2

movlw B'00001000' ; set disable sag


movwf outd1
movlw B'10010000' ; command to write to mask register
movwf spi ; call spi control write to mask reg
movlw D'8' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
CALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
CALL SPIDX ;
RETURN
;------------------- Read Waveform register--------------------------------
GETDATA:
incf contint,1 ; get every other sample
bcf INTCON,1 ; clear int
btfsc contint,0 ; if second interrupt then skip next
RETURN ; return to interrupt routine

clrf contint ; clear int count for next interrupt


movlw B'00000001' ; mov 01 into w register get wav sample
movwf spi ; output to spi read active energy and reset
movlw b'00000100' ; number of bytes to download B'000(5)(4)(3)(2)(
1)'
movwf wordlen ; wordlen is 24 bits. reg is actually 24 bits
CALL SPIRX ; CALL SPI read 24 bit word data will be in
; insd1,2,3. 3 being msb 1 being lsb
movf insd3,w ; mov in serial data (insd1-3) to sample low to high
movwf sample_high
movf insd2,w
movwf sample_middle
movf insd1,w
movwf sample_low
LCALL START ; preform abs value then sqr samples
CALL SAMPMINY ; pass sqr samples through iir filter 4096 times
befor sqr root
bcf STATUS,0 ; clear carry
movlw D'1' ;
addwf dave1,1 ; +1 until overflow then skip
btfsc STATUS,0
incf dave2,1
btfss dave2,4 ; filter 4096 samples then skip next
RETURN
CALL SQROOT ; sqroot after filtering all samples
LCALL CORRECTION ;Take y1,y2,y3 results of squareroot multiply by
16 bit coeff the shift right by 16
LCALL DISPLAYRMS ;display rms to lcd v or I depending on the cond
ition of rmsch
LCALL BIN2BCD ;convert sqroot to bcd for conversion to ascII
LCALL LCDUPDATE ;then dislay
DEBUG:
bsf STATUS,5 ; page 1
incf rmsch ; inc to change wav sample ch
; if rmsch=00000000 then display ch1 rms
; if rmsch=00000001 then display ch2 rms
btfss rmsch,1 ; if rmsch=00000010 then read eng , display energy , cle
ar rms chanel then repeat
GOTO NOENG
bcf STATUS,5
bcf INTCON,7
bcf point,6
LCALL ENGREAD1 ; get energy from 7756 mult by coef then display
bsf point,6
bsf STATUS,5
clrf rmsch ; clr rmsch for repeat ch1 then ch2 then energy
then repeat

NOENG:
bcf STATUS,5
clrf y1 ; clear all register for rms calculation
clrf y2
clrf y3
clrf y4
clrf y5
clrf y6
clrf x1
clrf x2
clrf x3
clrf x4
clrf x5
clrf x6
clrf dave1
clrf dave2
LCALL CHANNEL
bsf INTCON,7 ; enable interrupts
GOTO START1 ; return to start loop and wait for wav sample interrupt

; this is to compensate for above 2047 jump in program mem space


NOCARRY11:
LGOTO NOCARY11
NOCARRY12:
LGOTO NOCARY12
NOCARRY13:
LGOTO NOCARY13
NOCARRY14:
LGOTO NOCARY14
NOCARRY15:
LGOTO NOCARY15
ADD: ; addend to be added to
bcf STATUS,0 ; add number to be added
movf add1,w
addwf addend1,1
CALL CARRYCHK1 ; add routine used through out rms calculation.
add each 8 bit word
btfss carry,0 ; ripple any carry through
GOTO NOCARRY11
movf carry,w
addwf addend2,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY11
movf carry,w
addwf addend3,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY11
movf carry,w
addwf addend4,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY11
movf carry,w
addwf addend5,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY11
movf carry,w
addwf addend6,1
bcf STATUS,0
NOCARY11:
movf add2,w
addwf addend2,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY12
movf carry,w
addwf addend3,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY12
movf carry,w
addwf addend4,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY12
movf carry,w
addwf addend5,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY12
movf carry,w
addwf addend6,1
bcf STATUS,0
NOCARY12:
movf add3,w
addwf addend3,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY13
movf carry,w
addwf addend4,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY13
movf carry,w
addwf addend5,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY13
movf carry,w
addwf addend6,1
bcf STATUS,0
NOCARY13:
movf add4,w
addwf addend4,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY14
movf carry,w
addwf addend5,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY14
movf carry,w
addwf addend6,1
bcf STATUS,0
NOCARY14:
movf add5,w
addwf addend5,1
CALL CARRYCHK1
btfss carry,0
GOTO NOCARRY15
movf carry,w
addwf addend6,1
bcf STATUS,0
NOCARRY15:
bcf STATUS,0
movf add6,w
addwf addend6,1
RETURN
CARRYCHK1:
clrf carry ; clear carry register
btfsc STATUS,0 ; test status reg carry bit. skip if clr
incf carry,1 ; increment carry
RETURN
; this multiplication by shift and add if the current multiplier bit is 1 shift
only if zero
MULT1:
movlw D'8' ; number of bits to multiply
movwf wordlen ; mov 8 into wordlen
MULTLOOP: ;
;
btfsc mem,0 ; if bit is 1 add word
CALL ADD ;
bcf STATUS,0 ;
rrf mem,1 ; rotate constant for next bit to multiply
bcf STATUS,0
rlf add1,1 ; rotate for next add
rlf add2,1 ; rotate for next add
rlf add3,1 ; rotate for next add
rlf add4,1 ; rotate for next add
rlf add5,1 ; rotate for next add
rlf add6,1 ; rotate for next add
bcf STATUS,0
decfsz wordlen,1
GOTO MULTLOOP ; repeat

RETURN
;------------------- Square routine--------------------------------
SQR:
;------------------- clear register--------------------------------
clrf square1 ; multiply 24 bit word by itself (shift and add)
clrf square2
clrf square3
clrf square4
clrf square5
clrf square6
clrf add1
clrf add2
clrf add3
clrf add4
clrf add5
clrf add6
clrf addend1
clrf addend2
clrf addend3
clrf addend4
clrf addend5
clrf addend6
;------------------- Load the register--------------------------------
movf sample_low,w ;load adder with sample data
movwf add1
movf sample_middle,w
movwf add2
movf sample_high,w
movwf add3
;------------ Square the register results in square registers-----------
--------------
movf sample_low,w ; test sample work shift and add as indicated
movwf mem
CALL MULT1
movf sample_middle,w
movwf mem
CALL MULT1
movf sample_high,w
movwf mem
CALL MULT1
RETURN

; this is the add one routine used after compliment to make positive or negative
PLUSONE:
bcf STATUS,0 ; clear carry
movlw D'1'
addwf sample_low,1
btfss STATUS,0
RETURN
bcf STATUS,0 ; clear carry
movlw D'1'
addwf sample_middle,1
btfss STATUS,0
RETURN
bcf STATUS,0 ; clear carry
movlw D'1'
addwf sample_high,1
btfss STATUS,0
RETURN
; necessary for lcall's
ADDJUMP:
CALL ADD
RETURN

;------------------- IIR filter--------------------------------


; y(n)=(x(n)^2 x 2^9 - y(n)) x 2^(-9) + y(n-1)
SAMPMINY:
; x1 output of filter before sqr root
; x2
; x3
; x4
; x5
; x6
;------------------- process (-y(n)) ------------------------
comf x1,1 ; change to negative then add
comf x2,1
comf x3,1
comf x4,1
comf x5,1
comf x6,1
; add one
bcf STATUS,0 ; clear carry
movlw D'1'
addwf x1,1
btfss STATUS,0
GOTO SKIP
bcf STATUS,0 ; clear carry
movlw D'1'
addwf x2,1
btfss STATUS,0
GOTO SKIP
bcf STATUS,0 ; clear carry
movlw D'1'
addwf x3,1
btfss STATUS,0
GOTO SKIP
bcf STATUS,0 ; clear carry
movlw D'1'
addwf x4,1
btfss STATUS,0
GOTO SKIP
bcf STATUS,0 ; clear carry
movlw D'1'
addwf x5,1
btfss STATUS,0
GOTO SKIP
bcf STATUS,0 ; clear carry
movlw D'1'
addwf x6,1
bcf STATUS,0
;--------mov -x values adder then multiply samples by 2^9 load 2nd adde
r variable then add(subtract) ------
SKIP:
movf x1,w
movwf add1
movf x2,w
movwf add2
movf x3,w
movwf add3
movf x4,w
movwf add4
movf x5,w
movwf add5
movf x6,w
movwf add6
movlw D'9'
movwf div
;--------Multiply x(n)^2 by 2^9 ------
DIVBYN1:
bcf STATUS,0
rlf square1,1
rlf square2,1
rlf square3,1
rlf square4,1
rlf square5,1
rlf square6,1
bcf STATUS,0
decfsz div,1
GOTO DIVBYN1

movf square1,w ; load 2nd variable into adder


movwf addend1
movf square2,w
movwf addend2
movf square3,w
movwf addend3
movf square4,w
movwf addend4
movf square5,w
movwf addend5
movf square6,w
movwf addend6
;--------ADD 2^9 x square with (-x) results in Addend registers------
CALL ADD
movlw D'9' ; this is the IIR filter coefficent
movwf div
;--------Multiply (2^9 x square - y) by 2^-9 ------
DIVBYN:
bcf STATUS,0 ; rotate right and keep
sign extension
btfsc addend6,7
bsf STATUS,0
rrf addend6,1
rrf addend5,1
rrf addend4,1
rrf addend3,1
rrf addend2,1
rrf addend1,1
BCF STATUS,0
decfsz div,1
GOTO DIVBYN
;test for neg 1 ; if result = -1 then make resul
t = to 0
bcf STATUS,Z ; with smaller neg numbe
rs it is posible to rotate in ffffffffffff
incfsz addend1,w ; causing -1 this is why
this is done, each increment is done in the
GOTO NOTM1 ; w reg leaving data int
act for adding later
bcf STATUS,Z
incfsz addend2,w
GOTO NOTM1
bcf STATUS,Z
incfsz addend3,w
GOTO NOTM1
bcf STATUS,Z
incfsz addend4,w
GOTO NOTM1
bcf STATUS,Z
incfsz addend5,w
GOTO NOTM1
bcf STATUS,Z
incfsz addend6,w
GOTO NOTM1
bcf STATUS,Z
clrf addend1 ; make 0 if -1
clrf addend2
clrf addend3
clrf addend4
clrf addend5
clrf addend6
;-------Add y(n-1) to the previous calculation -------------------------
;------the result is the output of the IIR filter (Addend registers)-----------
NOTM1:
comf x1,1 ; change -x back to positive x for add output of
times coef routine
comf x2,1
comf x3,1
comf x4,1
comf x5,1
comf x6,1
; add one
bcf STATUS,0 ; clear carry ; skip if no carry to save time.
movlw D'1'
addwf x1,1
btfss STATUS,0
GOTO SKIP1
bcf STATUS,0 ; clear carry
movlw D'1'
addwf x2,1
btfss STATUS,0
GOTO SKIP1
bcf STATUS,0 ; clear carry
movlw D'1'
addwf x3,1
btfss STATUS,0
GOTO SKIP1
bcf STATUS,0 ; clear carry
movlw D'1'
addwf x4,1
btfss STATUS,0
GOTO SKIP1
bcf STATUS,0 ; clear carry
movlw D'1'
addwf x5,1
btfss STATUS,0
GOTO SKIP1
bcf STATUS,0 ; clear carry
movlw D'1'
addwf x6,1
bcf STATUS,0
SKIP1: ; mov x to adder
movf x1,w
movwf add1
movf x2,w
movwf add2
movf x3,w
movwf add3
movf x4,w
movwf add4
movf x5,w
movwf add5
movf x6,w
movwf add6
CALL ADD ; add (((samp^2 * 2^9)-x) * 2^-9) to x(z-1)
movf addend1,w ; mov results of adder to new value of x (output
of iir filter)
movwf x1
movf addend2,w
movwf x2
movf addend3,w
movwf x3
movf addend4,w
movwf x4
movf addend5,w
movwf x5
movf addend6,w
movwf x6
RETURN ; return to repeat 4096 times
; more lcall correction
NRESULT:
LGOTO NRESULT1
SQFILT1:
LGOTO SQFILT

;--------Successive Approximation square root routine------


SQROOT:

; x1-6 is the output of the iir filter or the square root of the input
; divide output of iir filter by 2^9 to negate the multiply sample by 2^9 this w
as done so
; no lsb's would be lost in the filter
movlw D'9'
movwf div
DIVBYN5: ; div by 2^9
bcf STATUS,0
rrf x6,1
rrf x5,1
rrf x4,1
rrf x3,1
rrf x2,1
rrf x1,1
BCF STATUS,0
decfsz div,1
GOTO DIVBYN5

;run till sar^2 = x


;
; x=4 time=16.6ms 14849 cycles clock=4 mhz
; x=fefe0001 time=26.97ms 24126 cycles clock=4 mhz
;
; x=4 time=2.97ms 14848 cycles clock=20 mhz
; x=fefe0001 time=4.83ms 24126 cycles clock=20 mhz
;
;x=6bytes incomming
;y=3bytes outging
;sar=3bytes
clrf y1 ; clr output of the sqrt routine.
clrf y2
clrf y3
clrf sar1 ;initialize sar reg
clrf sar2
clrf sar3
bsf sar3,7
bsf y3,7 ; set msb of y reg
; if sar reg^2 - x1-x6>0 keep bit yn shift sar ior sar w
ith yn results in sar then repeat
; IF sar reg^2 - x1-x6<=0 clr bit do not ior with yn sh
ift sar and repeat
;--------process the square of the square root approximation register------
SQFILT:

movf y1,w ; prepare to sqr y1


movwf add1
movf y2,w
movwf add2
movf y3,w
movwf add3
clrf add4 ; clr upper 3 bytes for shift and add
clrf add5
clrf add6
clrf addend1 ; clr output of adder
clrf addend2
clrf addend3
clrf addend4
clrf addend5
clrf addend6
movf y1,w ; multiply y by y
movwf mem
CALL MULT1
movf y2,w
movwf mem
CALL MULT1
movf y3,w
movwf mem
CALL MULT1

movf addend1,w ; mov y^2 to add1-6


movwf add1
movf addend2,w
movwf add2
movf addend3,w
movwf add3
movf addend4,w
movwf add4
movf addend5,w
movwf add5
movf addend6,w
movwf add6
comf add1,1 ; make y(guess) negative to subtract from x1-6(output of
filter)
comf add2,1
comf add3,1
comf add4,1
comf add5,1
comf add6,1
;--------process (-)add------
LCALL Y1 ; add1 to -y ( compliment and add1 )

movf x1,w ; mov x to addend to -y (add1-6)


movwf addend1
movf x2,w
movwf addend2
movf x3,w
movwf addend3
movf x4,w
movwf addend4
movf x5,w
movwf addend5
movf x6,w
movwf addend6
;--------Add input + (-square (square root approximation))------
LCALL ADDJUMP ; long call to add routine
nop
nop
nop
nop ; keep these long call problem do not remove
nop
nop
nop
nop
;--------if difference is > or = 0 add 2^i to the approximation register--------
-
;--------otherwise substract 2^(i+1) to the approximation register------
btfss STATUS,0 ; test results of add routine for negative
GOTO NRESULT
movf sar1,w ; if positive ior sar with y
iorwf y1,1
movf sar2,w
iorwf y2,1
movf sar3,w
iorwf y3,1
bcf STATUS,0 ; rotate sar fro next guess
rrf sar3,1
rrf sar2,1
rrf sar1,1
movf sar1,w ; or new guess with old guess
iorwf y1,1
movf sar2,w
iorwf y2,1
movf sar3,w
iorwf y3,1
btfss STATUS,0 ; sar register rotated right to carry job done.
GOTO SQFILT1 ; complete
RETURN ; not complete process new guess
NRESULT1:
comf sar1,w ; remove previous guess from new guess results were to b
ig.
andwf y1,1
comf sar2,w
andwf y2,1
comf sar3,w
andwf y3,1
bcf STATUS,0 ; shit sar and ior with old guess to make new gu
ess
rrf sar3,1
rrf sar2,1
rrf sar1,1
movf sar1,w
iorwf y1,1
movf sar2,w
iorwf y2,1
movf sar3,w
iorwf y3,1
btfss STATUS,0 ; sar reg shifted into carry job done
GOTO SQFILT2 ; complete
RETURN ; not complete process new guess
SQFILT2: ; more long call stuff
LGOTO SQFILT
SKIP2:
LGOTO SKIPNC

Y1:
; add one
bcf STATUS,0 ; clear carry
movlw D'1'
addwf add1,1
btfss STATUS,0
GOTO SKIP2
bcf STATUS,0 ; clear carry
movlw D'1'
addwf add2,1
btfss STATUS,0
GOTO SKIP2
bcf STATUS,0 ; clear carry
movlw D'1'
addwf add3,1
btfss STATUS,0
GOTO SKIP2
bcf STATUS,0
movlw D'1'
addwf add4,1
btfss STATUS,0
GOTO SKIP2
bcf STATUS,0 ; clear carry
movlw D'1'
addwf add5,1
btfss STATUS,0
GOTO SKIP2
bcf STATUS,0 ; clear carry
movlw D'1'
addwf add6,1
bcf STATUS,0 ; clear carry
SKIPNC:
RETURN

;---After calculation of the square root put the result


;----in bins for display
DISPLAYRMS:
movf addend1,w
movwf bin0 ; mov energy 2-6 to bin 0-5 for bcd conversion
movf addend2,w
movwf bin1
movf addend3,w
movwf bin2
movf addend4,w
movwf bin3
movf addend5,w
movwf bin4

RETURN

ADDVOFF:
GOTO ADDVOFF1 : long call stuff
COEFDIV: ; last part of coeficient
movlw D'16'
movwf div
DIVBY16: ; div by 2^16
bcf STATUS,0
rrf addend6,1
rrf addend5,1
rrf addend4,1
rrf addend3,1
rrf addend2,1
rrf addend1,1
BCF STATUS,0
decfsz div,1
GOTO DIVBY16
RETURN
;---Configure the Mode register for Current or Voltage RMS
;----calculation
;set mode register depending rmsch 0 or 1 this is incremented in getdata routine
CHANNEL:
bsf STATUS,5 ; set to bank 1
btfsc rmsch,0
GOTO CH2
bcf STATUS,5 ; set to bank 1
bcf point,5 ; point5 aux channel indicator
movlw B'00001000' ; sets mode reg for ch1 wav samp at 3.5k
ps
movwf outd1
movwf mode0
movlw B'01011000'
movwf outd2
movwf mode1
CH2:
bsf STATUS,5 ; set to bank 1
btfss rmsch,0
GOTO SETCH
bcf STATUS,5 ; set to bank 1
bsf point,5 ; point5 aux channel indicator
movlw B'00001000' ; sets mode reg for ch2 wav samp at 3.5k
ps
movwf outd1
movwf mode0
movlw B'01111000'
movwf outd2
movwf mode1
SETCH:
bcf STATUS,5
movlw B'10000110' ; command to write to mode register
movwf spi ; call spi control write to mode reg
movlw D'16' ; number of bits
movwf wordlen
bsf mcsb ; chip select high
LCALL SPI7756 ; sets spi port to talk to 7756 data latch on the fallin
g edge.
LCALL SPIDX ; mov lsb of word to output to outd2
RETURN

START:

btfss sample_high,7 ; test sign bit if neg compliment and add 1 to g


et absolute value
GOTO POSITIVE ; in not negative skip to truncate to 16 bit
comf sample_high,1 ; compliment
comf sample_middle,1
comf sample_low,1
; add one
bcf STATUS,0 ; clear carry
movlw D'1'
addwf sample_low,1
btfss STATUS,0
GOTO POSITIVE
bcf STATUS,0 ; clear carry
movlw D'1'
addwf sample_middle,1
btfss STATUS,0
GOTO POSITIVE
bcf STATUS,0 ; clear carry
movlw D'1'
addwf sample_high,1
btfss STATUS,0
POSITIVE:
bcf STATUS,0 ; truncate to 16 bit
rrf sample_high,1
rrf sample_middle,1
rrf sample_low,1
bcf STATUS,0
rrf sample_high,1
rrf sample_middle,1
rrf sample_low,1
bcf STATUS,0
rrf sample_high,1
rrf sample_middle,1
rrf sample_low,1
bcf STATUS,0
LCALL SQR ; square sample
movf addend1,w ; mov results of sqr routine into square1-6
movwf square1
movf addend2,w
movwf square2
movf addend3,w
movwf square3
movf addend4,w
movwf square4
movf addend5,w
movwf square5
movf addend6,w
movwf square6
RETURN
COFFCOMP1: ; more long call stuff
LGOTO COFFCOMP

;------------------------------- end of lcd out routine-------------------------


-----
CORRECTION:
; Gain correction
; Take y1,y2,y3 results of squareroot multiply by 16 bit coeff the shift r
ight by 16
clrf add1 ; clr adder
clrf add2
clrf add3
clrf add4
clrf add5
clrf add6
clrf addend1 ;clr adder
clrf addend2
clrf addend3
clrf addend4
clrf addend5
clrf addend6
movf y1,w ; results of sqrt into adder for coef adjustment
movwf add1
movf y2,w
movwf add2
movf y3,w
movwf add3
bsf STATUS,5 ; set to bank 1
btfsc rmsch,0 ; depending on rmsch use I or v coef and i or v
offset
GOTO CH2COFF
movf icof1,w ; muli by i coef
bcf STATUS,5 ; set to bank 0
movwf mem
LCALL MULT1
bsf STATUS,5 ; set to bank 1
movf icof2,w
bcf STATUS,5 ; set to bank 0
movwf mem
LCALL MULT1
LCALL COEFDIV
;------Offset correction-------add i offset
bsf STATUS,5 ; set to bank 1
movf ioffset1,w
bcf STATUS,5 ; set to bank 0
movwf add1
bsf STATUS,5 ; set to bank 1
movf ioffset2,w
bcf STATUS,5 ; set to bank 0
movwf add2
clrf add3 ; clr add3-6
clrf add4
clrf add5
clrf add6
btfss add2,7 ; SKIP IF NEGATIVE
GOTO ADDIOFF
comf add3,1 ; SIGN EXTEND NEGATIVE
comf add4,1
comf add5,1
comf add6,1
ADDIOFF:
LCALL ADD ; add ioffset

CH2COFF:
bsf STATUS,5 ; set to bank 1
btfsc rmsch,0
GOTO WHY
LGOTO COFFCOMP
WHY:
movf vcof1,w ; multiply by vcoef
bcf STATUS,5 ; set to bank 0
movwf mem
LCALL MULT1
bsf STATUS,5 ; set to bank 1
movf vcof2,w
bcf STATUS,5 ; set to bank 0
movwf mem
LCALL MULT1
LCALL COEFDIV
; add v offset
bsf STATUS,5 ; set to bank 1
movf voffset1,w
bcf STATUS,5 ; set to bank 0
movwf add1
bsf STATUS,5 ; set to bank 1
movf voffset2,w
bcf STATUS,5 ; set to bank 0
movwf add2
clrf add3
clrf add4
clrf add5
clrf add6
btfss add2,7 ; SKIP IF NEGATIVE
GOTO ADDVOFF
comf add3,1 ; SIGN EXTEND NEGATIVE
comf add4,1
comf add5,1
comf add6,1
ADDVOFF1: ; more long call stuff
LCALL ADD
COFFCOMP:
bcf STATUS,5 ; set to bank 0
RETURN

END

Você também pode gostar