📄 ade7759.asm
字号:
;==============================================================================
; Projekt: Miernik energii i mocy na ADE7759
; Autor: Grzesiek Gajewski (gayos@interia.pl)
; Koniec: 22.04.2003
; Wersja: 1.0
; Kompilacja w AVRStudio 4.04
; wielkosc Tabsize w edytorze: 12
;
; kilka informacji w equ.asm (na koncu pliku)
; licencja GPL w licencja.txt
;
;==============================================================================
; Ustawienie bitow konfiguracyjnych "fuse bits"
; BODLEVEL, BODEN, SUT1, SPIEN - zaprogramowane (programmed) czyli wartosc 0
; reszta niezaprogramowana (1)
; konfiguracja odnosi sie do rezonatora kwarcowego 8MHz
;==============================================================================
.nolist
.include "m16def.inc"
.list
.include "equ.asm" ; prawie wszystkie stale i zmienne
.def temp =r16
.def flagi =r17
.equ fKAL =0 ; =1 -> procedura kalibracji
.equ fINT2 =1 ; informacja o stanie przerwania INT2; =1 -> zezwolenie na zbieranie probek
.equ fOVER_I =2 ; =1 -> przepelnienie probki pradu
.equ fOVER_U =3 ; =1 -> przepelnienie probki napiecia
.equ fKLAW_WCIS =4 ; =1 -> klawisz wcisniety
.equ fTARYFY =5 ; =1 -> licznik dwutaryfowy
.equ fTARYFA2 =6 ; biezaca taryfa (zalezne od pory dnia), =0 -> taryfa 1
.equ fMENU =7 ; =1 -> trwa obsluga MENU
;==============================================================================
;======== S T A R T P R O G R A M U =========================================
;==============================================================================
.cseg
.org 0
jmp RESET ; reset
jmp INT0_INT ; int0
jmp RESET ; int1
jmp RESET ; timer2_comp
jmp RESET ; timer2_ovf
jmp RESET ; timer1_capt
jmp RESET ; timer1_compa
jmp RESET ; timer1_compb
jmp RESET ; timer1_ovf
jmp TIMER0_INT ; timer0_ovf
jmp RESET ; spi_stc
jmp RESET ; usart_rxc
jmp RESET ; usart_udre
jmp RESET ; usart_txc
jmp RESET ; adc
jmp RESET ; ee_rdy
jmp RESET ; ana_comp
jmp RESET ; twi
jmp INT2_INT ; int2 przerwanie z ADE7759
jmp RESET ; timer0_comp
jmp RESET ; spm_rdy
.include "int0.asm"
.include "int2.asm"
.include "spitwi.asm"
.include "init.asm"
.include "klaw.asm"
.include "menu.asm"
.include "math.asm"
.include "inne.asm"
;==============================================================================
;======== P R O G R A M G L O W N Y =========================================
;==============================================================================
.cseg
RESET: cli
clr r30
out EECR, r30
out MCUCR, r30
; ; DISABLE WATCHDOG
; ldi r31, (1<<WDTOE) | (1<<WDE)
; out WDTCR, r31
; ldi r31, 1<<WDTOE
; out WDTCR, r31
; watchdog na 1s
ldi r31, (1<<WDE) | (1<<WDP2) | (1<<WDP1)
out WDTCR, r31
; inicjalizacja stosu
ldi r31, high(RAMEND)
out SPH, r31
ldi r31, low(RAMEND)
out SPL, r31
; sprawdzenie czy EEPROM zawiera wlasciwe dane
rcall INICJUJ_EEPROM
; ustawienie timera0 na czas 15ms (odczekanie 15ms)
ldi temp, 136
out TCNT0, temp
in temp, TIFR
sbr temp, 1<<TOV0
out TIFR, temp ; czyszczenie flagi
ldi temp, (1<<CS02) | (1<<CS00)
out TCCR0, temp ; Fosc/1024
; odczyt zmiennych z EEPROMu, inicjalizacja zmiennych
; ustawienie rejestrow uC
call USTAW_MEGA16
call USTAW_SPI
call USTAW_KLAWISZE
; czekanie na koniec odmierzania czasu T0 (15ms)
RST15ms: in temp, TIFR
sbrs temp, TOV0
rjmp RST15ms
out TIFR, temp ; czyszczenie flagi
clr temp
out TCCR0, temp ; wylacz timer
; rcall USTAW_DS1307_R7 ; ustawienie OUT=1Hz
;test rcall DELAY_5_1ms
rcall RESET_ADE
call USTAW_ADE7759
; inicjalizacja LCD 15ms po starcie uP
rcall LCD_INIT
ldi temp, LCD_D1_C0_B0
rcall LCD_COMMAND
ldi zh, high(2*txt_witaj)
ldi zl, low(2*txt_witaj)
rcall LCD_STR_FLASH ; komunikat powitalny
rcall LCD_CGRAM ; polskie znaczki
; sprawdzenie klawisza OK i Anuluj
sbis KLAW_PIN, KLAW_NIE ; przeskocz jesli stan wysoki (klawisz zwolniony)
rcall KALIBRACJA ; stan niski - procedura kalibracji
; sprawdzenie stanu linii ADE_SAG
sbis ADE_SAG_PIN, ADE_SAG ; przeskocz jesli stan wysoki (poprawne napiecie)
rjmp BZ_SAG ; stan niski SAG
call CZYTAJ_DS1307 ; odczyt czasu
rcall SPRAWDZ_TARYFE
rcall POROWNAJ_CZAS
rcall DELAY_44us
rcall CZYT_EN_DS1307 ; odczyt energii z DS1307 do RAM
; wlaczenie odmierzania czasu ~32ms do obslugi klawiatury
rcall TIMER0_USTAW
rcall TIMER1_ICP
; ustawienie przerwan sprzetowych
; przerwanie INT2 musi byc wlaczone zawsze, gdyz tylko tak nastepuje detekcja SAG
rcall INT_WLACZ
rcall DELAY_1_7ms
wdr
;------------------------------------------------------------------------------
;---------- glowna petla programu ---------------------------------------------
;------------------------------------------------------------------------------
PETLA_START_0: ; tu skacze sie po wyjsciu z MENU
sei
PETLA_START:
; w przerwaniu INT0 (czyli procedurze CZYTAJ_ENERGIE) obliczane sa E i P
; czekanie na zakonczenie odczytu energii i ustawienie flagi fINT2
PS_0: ; oczekiwanie na fINT2 = 1
sbrs flagi, fINT2 ; przeskocz, jesli flaga =1
rjmp PS_0
cli
; przygotowanie rejestrow i zmiennych do zbierania probek
clr r2 ; r2 zawsze =0
ldi zl, low(Prb_0xff)
ldi zh, high(Prb_0xff)
ldi yl, low(Bufor)
ldi yh, high(Bufor)
PS_ZER: st z+, r2
cp zl, yl
cpc zh, yh
brlo PS_ZER
cbr flagi, (1<<fOVER_I) | (1<<fOVER_U)
clr probek0
clr probek1
movw i_suma0, probek0
movw i_suma2, probek0
movw i_suma4, probek0 ; czyszczenie sumy pradu
movw u_suma0, probek0
movw u_suma2, probek0
movw u_suma4, probek0 ; czyszczenie sumy napiecia
movw prb0, probek0
clr okresow
dec okresow ; ustaw licznik okresow na -1
; ustawienie zglaszania przerwania od probek w ADE7759
rcall ZBIERANIE_PROBEK_WLACZ
wdr
sei
PS_1: ; oczekiwanie na fINT2 = 0
sbrc flagi, fINT2 ; przeskocz, jesli flaga =0
rjmp PS_1
wdr
in temp, GIFR
sbrs temp, INTF2
rjmp PS_2
ldi temp, 1<<INTF2
out GIFR, temp ; kasuj flage przerwania
nop
PS_2: sei
;--------------------------------------
; ;test! \/
; cli
; sts Prb, probek0
; sts Prb+1, probek1
; sts Prb_z, prb_znak
; sts Okr, okresow
; sei
; ;test! /\
;--------------------------------------
LICZENIE: rcall OBLICZENIA ; liczenie RMS, S, Q, PF, F
; wyswietlanie wyniku na LCD wybranego parametru (E lub U lub I ...)
lds temp, Flagi4
tst temp
brne PETLA_KAL ; <>0 ==> trwa jakas kalibracja
rcall WYSWIETL_WYNIK
sbrc flagi, fKAL ; przeskocz, jesli tryb zwykly
rjmp PETLA_KAL ; KALIBRACJA ==> specjalny tryb
;------------------------------------------------------------------------------
; sprawdzanie czasu (odczyt z DS1307) co minute
SPR_CZAS: lds temp, Sekundy_bin ; wczytanie zliczonej ilosci sekund
inc temp
sts Sekundy_bin, temp
cpi temp, 60
brne SPR_TARYF_NIE
; sprawdzenie czasu z DS1307 i ustawienie taryfy jesli potrzeba
cli
call CZYTAJ_DS1307
sei
rcall SPRAWDZ_TARYFE
rcall POROWNAJ_CZAS
lds r0, Minuty_bcd
lds r1, Godziny_bcd
clr temp
cp r0, temp
cpc r1, temp ; spr czy godz. =00:00
brne SPR_TARYF_NIE
cli
rcall ZAP_EN_DS1307 ; o godz. 00:00 zapisywany jest stan licznikow energii
rcall ZAPISZ_EN_EE
sei
SPR_TARYF_NIE:
; i cykl od poczatku...
wdr
cbr flagi, 1<<fINT2 ; zeruj bit zezwolenia na zbieranie probek
rjmp PETLA_START
;==============================================================================
PETLA_KAL:
lds temp, Flagi4
tst temp
brne PK_KAL
rjmp PETLA_START
PK_KAL: sbrc temp, f4KAL_ZI
rjmp PK_C_Z ; =1 ==> kalibracja offsetow zera pradu
sbrc temp, f4KAL_DCI ; =1 ==> trwa kalibracja DC pradu
rcall KAL_I
sbrc temp, f4KAL_ZU
rjmp PK_C_Z ; =1 ==> kalibracja offsetow zera napiecia
sbrc temp, f4KAL_DCU ; =1 ==> trwa kalibracja DC napiecia
rcall KAL_U
sbrc temp, f4KAL_E ; =1 ==> trwa kalibracja zera energii
rcall KAL_E
rjmp PETLA_START
PK_C_Z: clr temp
sts Flagi4, temp
ldi zl, low(2*txt_zro) ; komunikat "Zrobione"
ldi zh, high(2*txt_zro)
rcall LCD_STR_FLASH ; wyswietl linie
rjmp PETLA_START
;==============================================================================
.include "lcd8.asm"
.include "kalibr.asm"
.include "obliczenia.asm"
.include "bufor.asm"
;==============================================================================
;======== K O N I E C =========================================================
;==============================================================================
;==============================================================================
txt_witaj: .db 1,"LICZNIK ENERGII", 2," i WATOMIERZ", 0
txt_kalibr: .db " KALIBRACJA", 2," wejd",15," w MENU", 0
txt_czek: .db "Czekaj...", 0
txt_bns: .db 1,"brak napi",10,"cia", 2,"sieciowego", 0
txt_u_rms: .db "Napi",10,"cie RMS ", 0
txt_u_mav: .db "Nap. ",14,"rednie ", 0
txt_u_ap: .db "Nap. ampl.+++ ", 0
txt_u_am: .db "Nap. ampl.--- ", 0
txt_i_rms: .db "Pr",8,"d RMS ", 0
txt_i_mav: .db "Pr",8,"d ",14,"redni ", 0
txt_i_ap: .db "Pr",8,"d ampl.+++ ", 0
txt_i_am: .db "Pr",8,"d ampl.--- ", 0
txt_moc_p: .db "Moc czynna ", 0
txt_moc_q: .db "Moc bierna ", 0
txt_moc_s: .db "Moc pozorna ", 0
txt_wsp_m: .db "Wsp. mocy P/S ", 0
txt_czest: .db "Cz",10,"stotliwo",14,9," ", 0
txt_en_sum: .db "En ca",11,"kowita ", 0
txt_en_od: .db "En od DD.MM.RR", 0
txt_en_oddo: .db "En DD.MM-DD.MM", 0
txt_en_ses: .db "En tymczasowa ", 0
txt_en_poz: .db "En pozorna ", 0
txt_en_sek: .db "Energ. SEKUND.", 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -