📄 ade7759.lst
字号:
.include "int0.asm"
;==============================================================================
; Przerwanie INT0 zglaszane co 1sek. z DS1307
; Projekt: Miernik energii i mocy na ADE7759
;==============================================================================
;.listmac
; r0, r1, r2 -rejestry operacyjne, r2=0
.def wyn0 =r4
.def wyn1 =r5
.def wyn2 =r6
.def wyn3 =r7 ; wynik mnozenia
.def wsp_en0 =r8
.def wsp_en1 =r9 ; wspolczynnik korekcji probki energii
.def wsp_en2 =r3 ; uwaga! r3
.def aden0 =r10
.def aden1 =r11
.def aden2 =r12
.def aden3 =r13
.def aden4 =r14
.def aden5 =r15 ; probka energii z ADE7759 (po korekcji)
.def en0 =r18
.def en1 =r19
.def en2 =r20
.def en3 =r21
.def en4 =r22 ; en4::en0 probka energii z ADE7759
.def en5 =r23
.def en6 =r24 ; en6::en0 akumulator energii (ladowanej z RAM)
;;;;;;.def akum_en =r25
;.def spi_bufor =r28 ; deklaracja juz jest w int2.asm
; rejestr X wolny
; rejestru Y nie wolno uzyc
; rejestr Z trzyma wskaznik do energii (RAM)
;======== M A K R A ===========================================================
.macro SPI_ADE_ON ; uaktywnij SPI w ADE7759
cbi ADE_CS_PORT, ADE_CS
.endm
.macro SPI_ADE_OFF ; wylacz SPI w ADE7759
sbi ADE_CS_PORT, ADE_CS
.endm
;--------------------------------------
.macro MUL16x16 ; @0:@1 -mnozna, @2:@3 -mnoznik; wynik w rejestrach wynx
; oraz musi byc: r2=0
mul @0, @2
movw wyn2, r0
mul @1, @3
movw wyn0, r0
mul @0, @3
add wyn1, r0
adc wyn2, r1
adc wyn3, r2
mul @1, @2
add wyn1, r0
adc wyn2, r1
adc wyn3, r2
.endm
;--------------------------------------
.macro MUL16x8 ; @0:@1 -mnozna, @2 -mnoznik; wynik w rejestrach wyn2:wyn1:wyn0
clr wyn2
mul @1, @2
movw wyn0, r0
mul @0, @2
add wyn1, r0
adc wyn2, r1
.endm
;------------------------------------------------------------------------------
.cseg
;======== P R O G R A M =======================================================
INT0_INT: ; gdy przerwanie
; gdy przerwanie trzeba zapewnic ochrone rejestrow
; ...gdyz bedac w MENU przerwanie od INT0 rozwali rejestry
00002a 930f push temp
00002b b70f in temp, SREG ; zachowaj rejestr SREG
00002c 930f push temp
00002d 920f push r0
00002e 921f push r1
00002f 922f push r2
000030 923f push r3
000031 924f push r4
000032 925f push r5
000033 926f push r6
000034 927f push r7
000035 928f push r8
000036 929f push r9
000037 92af push r10
000038 92bf push r11
000039 92cf push r12
00003a 92df push r13
00003b 92ef push r14
00003c 92ff push r15
;push r16 temp na poczatku
;push r17 flagi nie
00003d 932f push r18
00003e 933f push r19
00003f 934f push r20
000040 935f push r21
000041 936f push r22
000042 937f push r23
000043 938f push r24
000044 939f push r25
000045 93af push r26
000046 93bf push r27
000047 93cf push r28
000048 93df push r29
000049 93ef push r30
00004a 93ff push r31
00004b + SPI_ADE_ON
00004c e003 ldi temp, ADE_RSTENERGY_ADR ; komenda odczytu energii
00004d d2ca rcall SPI_TRX ; wyslij bajt z temp
;--1----- ; czytanie pierwszego bajtu
00004e d2c9 rcall SPI_TRX ; odczyt pierwszego bajtu energii (MSB) do temp
00004f 2f60 mov en4, temp ; ...i potem do wlasciwego rejestru
;--2-----
000050 d2c7 rcall SPI_TRX
000051 2f50 mov en3, temp ; odczyt energii do en4::en0 - tymczasowo
; ...potem nastepuje zaladowanie energii
;--3----- ; ...do tych rejestrow
000052 d2c5 rcall SPI_TRX
000053 2f40 mov en2, temp
;--4-----
000054 d2c3 rcall SPI_TRX
000055 2f30 mov en1, temp
;--5-----
000056 d2c1 rcall SPI_TRX
000057 2f20 mov en0, temp
000058 + SPI_ADE_OFF
;------------------------------------------------------------------------------
000059 9100 015a lds temp, Flagi3
00005b ff00 sbrs temp, f3EN_RST ; flaga pierwszej probki po resecie
00005c c008 rjmp LE_OK
00005d 7f0e cbr temp, 1<<f3EN_RST ; zeruj
00005e 9300 015a sts Flagi3, temp
000060 2766 clr en4 ; zerowanie probki energii
000061 2755 clr en3
000062 2744 clr en2
000063 2733 clr en1
000064 2722 clr en0
000065 9100 0090 LE_OK: lds temp, Flagi2
000067 7e0f cbr temp, 1<<f2EN_MI ; zeruj flagi
000068 9300 0090 sts Flagi2, temp
; [2]
00006a ff67 sbrs en4, 7 ; spr bitu znaku probki energii
00006b c008 rjmp LE_PLUS ; bit_znaku=0 --> dalej
; probka ujemna -ustawienie flagi...
00006c 6100 sbr temp, 1<<f2EN_MI
00006d 9300 0090 sts Flagi2, temp
; ...i negacja probki (wystarczy negacja bitow)
00006f 9520 com en0
000070 9530 com en1
000071 9540 com en2
000072 9550 com en3
000073 9560 com en4
LE_PLUS:
000074 24aa clr aden0
000075 24bb clr aden1
000076 24cc clr aden2
000077 24dd clr aden3
000078 24ee clr aden4
000079 24ff clr aden5
00007a 9080 0081 lds wsp_en0, Wsp_E
00007c 9090 0082 lds wsp_en1, Wsp_E+1
00007e 9030 0083 lds wsp_en2, Wsp_E+2 ; zaladuj wspolczynnik korekcji
000080 2422 clr r2
; [3] ; mnozenie probki (5B) przez wspolczynnik (3B), wynik (8B)
; ale poniewaz dwa najmlodsze bajty sa odrzucane to wynik miesci sie w (6B)
000081 + MUL16x16 wsp_en1, wsp_en0, en1, en0 ; mnozenie mlodszego slowa przez wsp.
00008d 0153 movw aden0, wyn2 ; obciecie 2 najmlodszych bajtow [3a]
00008e + MUL16x16 wsp_en1, wsp_en0, en3, en2 ; mnozenie kolejnego slowa
00009a 0ca4 add aden0, wyn0
00009b 1cb5 adc aden1, wyn1
00009c 1cc6 adc aden2, wyn2
00009d 1cd7 adc aden3, wyn3 ; dodanie wyniku posredniego do rejestru probki energii
00009e + MUL16x8 wsp_en1, wsp_en0, en4 ; ostatnie mnozenie
0000a4 0cc4 add aden2, wyn0
0000a5 1cd5 adc aden3, wyn1
0000a6 1ce6 adc aden4, wyn2
; teraz mnozenie najstarszego bajtu wsp_en2 wraz z przesunieciem o 2 bajty
0000a7 + MUL16x8 en1, en0, wsp_en2
0000ad 0ca4 add aden0, wyn0
0000ae 1cb5 adc aden1, wyn1
0000af 1cc6 adc aden2, wyn2
0000b0 1cd2 adc aden3, r2
0000b1 1ce2 adc aden4, r2
0000b2 1cf2 adc aden5, r2
0000b3 + MUL16x8 en3, en2, wsp_en2
0000b9 0cc4 add aden2, wyn0
0000ba 1cd5 adc aden3, wyn1
0000bb 1ce6 adc aden4, wyn2
0000bc 1cf2 adc aden5, r2
0000bd 9d63 mul en4, wsp_en2 ; ostatnie mnozenie (najstarsze bajty)
0000be 0ce0 add aden4, r0
0000bf 1cf1 adc aden5, r1
; [4] dwa najmlodsze bajty sa odrzucane - nie nalezy ich akumulowac
; aden5::aden0 => probka energii po korekcji (6B)
0000c0 0156 movw aden0, aden2
0000c1 0167 movw aden2, aden4 ; dzielenie przez 2^16
; wynik (4B): aden3::aden0
; zapis energii sekundowej (wymagane przy kalibracji)
0000c2 9100 0090 lds temp, Flagi2
0000c4 fd02 sbrc temp, f2EN_S ; jesli EN_S=0 to zapisz energie sek.
0000c5 c008 rjmp LE_NOS
0000c6 92a0 010a sts Energia_sek, aden0
0000c8 92b0 010b sts Energia_sek+1, aden1
0000ca 92c0 010c sts Energia_sek+2, aden2
0000cc 92d0 010d sts Energia_sek+3, aden3
; prog akumulacji energii
0000ce ef24 LE_NOS: ldi en0, low(PROG_AKUMULACJI)
0000cf e031 ldi en1, byte2(PROG_AKUMULACJI)
0000d0 e040 ldi en2, byte3(PROG_AKUMULACJI)
0000d1 e050 ldi en3, byte4(PROG_AKUMULACJI)
0000d2 16a2 cp aden0, en0
0000d3 06b3 cpc aden1, en1
0000d4 06c4 cpc aden2, en2
0000d5 06d5 cpc aden3, en3
0000d6 f008 brlo LE_PRMN ; skacz, jesli en_sek mniejsza od progu
0000d7 c006 rjmp LE_TARYF ; probka wieksza od progu
0000d8 fd10 LE_PRMN: sbrc flagi, fKAL ; =1 ==> tryb kalibracji...
0000d9 c004 rjmp LE_TARYF ; ...wiec nie ograniczaj akumulacji progiem
0000da 7e0f cbr temp, 1<<f2EN_MI ; kasuj flage energii ujemnej, aby nie migala
0000db 9300 0090 sts Flagi2, temp ; ...gwiazdka na LCD
0000dd c03c rjmp LE_MOC_P ; i nie akumuluj energii
;--------------------------------------
; test biezacej taryfy
0000de ff16 LE_TARYF: sbrs flagi, fTARYFA2 ; przeskocz, jesli jest taryfa 2
0000df c00f rjmp LE_T1 ; skocz bo taryfa 1
; taryfa 2 - ladowanie wskaznikow
0000e0 e2e9 ldi zl, low(Energia2_od)
0000e1 e0f1 ldi zh, high(Energia2_od) ; zaladuj wskaznik do zmiennej Energia2_od
0000e2 012f movw wyn0, zl ; zapamietaj wskaznik w wyn1:wyn0
0000e3 e3e7 ldi zl, low(Energia2_oddo)
0000e4 e0f1 ldi zh, high(Energia2_oddo) ; zaladuj wskaznik do zmiennej Energia2_oddo
0000e5 013f movw wyn2, zl ; zapamietaj wskaznik w wyn3:wyn2
0000e6 e5e3 ldi zl, low(Energia2_ses)
0000e7 e0f1 ldi zh, high(Energia2_ses) ; zaladuj wskaznik do zmiennej Energia2_ses
0000e8 014f movw wsp_en0, zl ; zapamietaj wskaznik w wsp_en1:wsp_en0
0000e9 e4e5 ldi zl, low(Energia2_poz)
0000ea e0f1 ldi zh, high(Energia2_poz) ; zaladuj wskaznik do zmiennej Energia2_poz
0000eb 017f movw aden4, zl ; zapamietaj wskaznik w aden5:aden4
0000ec e1eb ldi zl, low(Energia2)
0000ed e0f1 ldi zh, high(Energia2) ; zaladuj wskaznik do zmiennej Energia2
0000ee c00e rjmp LE_TD
LE_T1: ; taryfa 1 - ladowanie wskaznikow
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -