📄 init.asm
字号:
;==============================================================================
; Procedury inicjalizacyjne
; Projekt: Miernik energii i mocy na ADE7759
;==============================================================================
.cseg
;------------------------------------------------------------------------------
USTAW_MEGA16:
.def ee_adr =r18
.def ee_dane =r19
; konfig portow (tylko niektorych - reszta gdzie indziej)
clr temp
out DDRA, temp ; na wszelki wypadek (porty jako wejscie)
out DDRB, temp
out DDRC, temp
out DDRD, temp
; portA -> ustawiany w lcd8.asm
; portB -> pb7-pb4 : SPI
ldi temp, (1<<PB3) | (1<<PB2) ; pull-up
out PORTB, temp
; portC -> pc1, pc0 : TWI; reszta to klawisze
; portD -> pd7, pd5, pd4 : lcd8.asm; pd3 : klawisze; pd1, pd0 : UART
clr temp
out PORTD, temp
; ustawienie niektorych rejestrow
; wylaczenie JTAG:
ldi temp, 1<<JTD
out MCUCSR, temp
out MCUCSR, temp
; wylaczenie komparatora:
ldi temp, 1<<ACD
out ACSR, temp
; inne:
clr temp
out SFIOR, temp
out ADCSRA, temp
; przerwanie INT0
in temp, MCUCR
sbr temp, (1<<ISC01) | (1<<ISC00) ; narastajace zbocze
out MCUCR, temp
; przepisuje konfiguracje z EEPROM:(EEPROM) do RAM:(RAM)
; wykorzystuje rejestr Y
clr yh
out EEARH, yh
ldi yl, RAM ; zmiennych nie moze byc wiecej niz 0xFF-0x68 (0xFF-RAM)
ldi ee_adr, EEPROM
ee_nastb: out EEARL, ee_adr ; wpisz adres do odczytu bajtu
sbi EECR, EERE ; ustaw znacznik odczytu (procesor czeka 4 cykle na bajt z EE)
in ee_dane, EEDR
st y+, ee_dane ; przepisz bajt z EE do RAM, oraz zwieksz adres (offset) do RAM
inc ee_adr ; zwieksz adres odczytu
cpi yl, low(Ds_adr) ; czy koniec danych? (zmienna Ds_adr wskazuje adres zmiennych ulotnych)
brne ee_nastb ; nastepny bajt
; inicjalizacja zmiennych ulotnych
ldi zl, low(Energia1_ses)
ldi zh, high(Energia1_ses)
rcall CZYSC_ENERG ; czysci od razu energie taryfy2
clr temp
sts Hist_zera, temp
sts Hist_przepel_I, temp
sts Hist_przepel_U, temp
sts Klaw_dlugo, temp
sts Klaw_pusz, temp
ldi temp, 1<<ST_M
sts Status, temp ; Status wskazuje na moc
ldi temp, 1
sts Status_M, temp ; moc P
sts Status_U, temp ; ...RMS
sts Status_I, temp
sts Status_E2, temp ; ...energie sesji
sts Status_E1, temp ; ...energie sesji
clr flagi
sts Flagi3, flagi
sts Flagi4, flagi
lds temp, Flagi2
lsr temp ; bit TARYFY do C
brcc UM_T0
sbr flagi, 1<<fTARYFY ; ustaw licznik dwutaryfowy
UM_T0: lds temp, Flagi3
sbr temp, 1<<f3EN_RST ; pierwsza probka energii po resecie
sts Flagi3, temp
;------------------
; obliczenie ilosci probek (maks. probek do zebrania -potrzebne dla sygnalow nieokresowych)
; rejestry: n0, n1, mn0, mn1, kwd3::kwd0
OIP: push n0
push n1
push mn0
push mn1
push kwd0
push kwd1
push kwd2
push kwd3
lds n1, Ade_mode+1
com n1 ; odwrocenie bitow
ldi mn0, 0b00011000 ; maska na bity DTRT
and n1, mn0
lsr n1
lsr n1
lsr n1 ; przesuniecie bitow do LSB
ldi mn0, 70 ; 3,5kSps /50Hz = 70
clr mn1
tst n1
breq OIP_Z ; n1=0
OIP_J: lsl mn0
rol mn1 ; *2
dec n1
brne OIP_J
OIP_Z: lds n0, Okresy_ile
inc n0 ; "o dwa okresy wiecej" dla sygnalow nieokresowych
inc n0
clr n1
rcall MUL_16_16 ; n1:n0 * mn1:mn0
sts Probek_ile, kwd0
sts Probek_ile+1, kwd1 ; zapis wyniku do RAM
lsl mn0
rol mn1
sts Prb_na_okr_x2, mn0
sts Prb_na_okr_x2+1, mn1
pop kwd3
pop kwd2
pop kwd1
pop kwd0
pop mn1
pop mn0
pop n1
pop n0
ret
;--------------------------------------
CZYSC_ENERG: ; czysci energie taryfu 1 i 2 --> adres w Z
push r18
clr temp
ldi r18, 14
CE_ZEN: st z+, temp
dec r18
brne CE_ZEN
pop r18
ret
;------------------------------------------------------------------------------
USTAW_KLAWISZE: ; ustawienie klawiszy na dzialanie normalne (pooling T0)
in temp, KLAW_PORT-1
cbr temp, KLAW_MASKA ; rejestr DDRx wyzerowany - port jako wejscie
out KLAW_PORT-1, temp
in temp, KLAW_PORT
sbr temp, KLAW_MASKA ; rejestr PORTx ustawiony - pull-up na klawiszach
out KLAW_PORT, temp
ret
;------------------------------------------------------------------------------
USTAW_ADE7759: ; przesylanie danych do rejestrow ADE7759
; korzysta z Y, temp, r0, r1
clr yh
ldi yl, RAM ; wskaznik do zmiennych Ade_
ldi temp, ADE_CH1OS_ADR ; zaladuj adres rejestru w ADE
ld r0, y+ ; Ade_ch1os
rcall SPI_ADE_WRITE_1B
ldi temp, ADE_CH2OS_ADR
ld r0, y+ ; Ade_ch2os
rcall SPI_ADE_WRITE_1B
ldi temp, ADE_GAIN_ADR
ld r0, y+ ; Ade_gain
rcall SPI_ADE_WRITE_1B
ldi temp, ADE_APGAIN_ADR
ld r0, y+ ; Ade_apgain
ld r1, y+
rcall SPI_ADE_WRITE_2B
ldi temp, ADE_PHCAL_ADR
ld r0, y+ ; Ade_phcal
rcall SPI_ADE_WRITE_1B
ldi temp, ADE_APOS_ADR
ld r0, y+ ; Ade_apos
ld r1, y+
rcall SPI_ADE_WRITE_2B
ldi temp, ADE_ZXTOUT_ADR
ld r0, y+ ; Ade_zxtout
ld r1, y+
rcall SPI_ADE_WRITE_2B
ldi temp, ADE_SAGCYC_ADR
ld r0, y+ ; Ade_sagcyc
rcall SPI_ADE_WRITE_1B
ldi temp, ADE_SAGLVL_ADR
ld r0, y+ ; Ade_saglvl
rcall SPI_ADE_WRITE_1B
ldi temp, ADE_IRQEN_ADR
ld r0, y+ ; Ade_irqen
rcall SPI_ADE_WRITE_1B
ldi temp, ADE_MODE_ADR
ld r0, y+ ; Ade_mode
ld r1, y+
rcall SPI_ADE_WRITE_2B
call DELAY_44us
ret
;==============================================================================
USTAW_DS1307_ALL: ; ustawia wszystko - dane ze zmiennych *_bcd
; wykorzystuje: Z, Y, temp, r0
ldi yl, low(Bufor)
ldi yh, high(Bufor) ; adres bufora w Y
ldi temp, DS1307_ADRES | TWI_WRITE
st Y+, temp ; zapisz adres DS1307 w buforze
ldi temp, 1 ; adres rejestru w DS1307
st y+, temp
; zawartosc rejestrow...
ldi zl, low(Minuty_bcd)
ldi zh, high(Minuty_bcd)
ld temp, z+ ; minuty
st y+, temp
ld temp, z+ ; godziny
st y+, temp
ld temp, z+ ; dzien tyg.
st y+, temp
ld temp, z+ ; dni
st y+, temp
ld temp, z+ ; miesiace
st y+, temp
ld temp, z+ ; lata
st y+, temp
ldi temp, 0b10010000 ; zawartosc rejestru 7
st y+, temp
ldi temp, 8
mov r0, temp ; licznik ilosci danych do wyslania
ldi yl, low(Bufor)
ldi yh, high(Bufor) ; adres bufora w Y
rcall TWI_MASTER_WRITE
call DELAY_44us ; MUSI byc opoznienie, bo TWI pracuje duzo
; ...wolniej niz CPU
; wyslanie sekund i uaktywnienie zegara
ldi yl, low(Bufor)
ldi yh, high(Bufor) ; adres bufora w Y
ldi temp, DS1307_ADRES | TWI_WRITE
st Y, temp ; zapisz adres DS1307 w buforze
ldi temp, 0 ; adres rejestru w DS1307
std y+1, temp
ldi temp, 0 ; sekundy
std y+2, temp
ldi temp, 2
mov r0, temp ; licznik ilosci danych do wyslania
rcall TWI_MASTER_WRITE
rcall SPRAWDZ_TARYFE
ret
;--------------------------------------
;USTAW_DS1307_R7: ; ustawia tylko rejestr 7 (przy starcie, tak na wszelki wypadek)
; ; inne rejestry ustawia sie z menu
; ldi yl, low(Bufor)
; ldi yh, high(Bufor) ; adres bufora w Y
; ldi temp, DS1307_ADRES | TWI_WRITE
; st Y, temp ; zapisz adres DS1307 w buforze
; ldi temp, 7 ; adres rejestru w DS1307
; std y+1, temp
; ldi temp, 0b10010000 ; zawartosc rejestru
; std y+2, temp
; ldi temp, 2
; mov r0, temp ; licznik ilosci danych do wyslania
; rcall TWI_MASTER_WRITE
; ret
;------------------------------------------------------------------------------
CZYTAJ_DS1307: ; czyta rejestry czasowe z DS1307
; najpierw ustawienie rejestru 0 w DS1307
ldi yl, low(Bufor)
ldi yh, high(Bufor) ; adres bufora w Y
ldi temp, DS1307_ADRES | TWI_WRITE
st Y, temp ; zapisz adres DS1307 w buforze
ldi temp, 0 ; adres rejestru w DS1307
std y+1, temp
ldi temp, 1
mov r0, temp ; licznik ilosci danych do wyslania
rcall TWI_MASTER_WRITE
call DELAY_44us ; na wszelki wypadek troche opoznienia
; r0 -ilosc bajtow do odczytu
; Y -wskaznik do zmiennych w RAM i [Y] -> adres DS1307
ldi yl, low(Ds_adr)
ldi yh, high(Ds_adr) ; adres poczatku zmiennych w Y
ldi temp, DS1307_ADRES | TWI_READ
st Y, temp ; zapisz adres DS1307 w buforze
ldi temp, 7
mov r0, temp ; licznik ilosci danych do odczytu
rcall TWI_MASTER_READ
; konwersja sekund_bcd na sekundy_bin
push bcd0 ; ochrona rejestrow
push bin0
lds bcd0, Sekundy_bcd
rcall BCD_8_BIN
sts Sekundy_bin, bin0
pop bin0
pop bcd0
ret
;------------------------------------------------------------------------------
CZYT_EN_DS1307: ; czyta rejestry energii z DS1307
; najpierw ustawienie rejestru 0 w DS1307
ldi yl, low(Bufor)
ldi yh, high(Bufor) ; adres bufora w Y
ldi temp, DS1307_ADRES | TWI_WRITE
st Y, temp ; zapisz adres DS1307 w buforze
ldi temp, 8 ; adres rejestru w DS1307
std y+1, temp
ldi temp, 1
mov r0, temp ; licznik ilosci danych do wyslania
rcall TWI_MASTER_WRITE
call DELAY_44us ; na wszelki wypadek troche opoznienia
; r0 -ilosc bajtow do odczytu
; Y -wskaznik do zmiennych w RAM i [Y] -> adres DS1307
ldi yl, low(Energia1-1)
ldi yh, high(Energia1-1)
ld temp, y
push temp ; ochrona zmiennej w RAM przed Energia1
ldi temp, DS1307_ADRES | TWI_READ
st Y, temp ; zapisz adres DS1307 w buforze
ldi temp, ILE_BAJT_EN
mov r0, temp ; licznik ilosci danych do odczytu
rcall TWI_MASTER_READ
ldi yl, low(Energia1-1)
ldi yh, high(Energia1-1)
pop r0
st y, r0
CEDS_OK: ret
;==============================================================================
INICJUJ_EEPROM: ; sprawdza czy EEPROM nie jest pusty (po programowaniu)
; a jesli jest, to programuje go wartosciami domyslnymi
; wykorzystuje rejestr Y (EE) i Z (Flash), ee_dane, ee_adr, temp, r0, r1
cbr flagi, 1<<fINT2
clr yh
out EEARH, yh
ldi yl, 4 ; testowana komorka pamieci
out EEARL, yl
sbi EECR, EERE ; ustaw znacznik odczytu
in ee_dane, EEDR
cpi ee_dane, 74 ; testowana wartosc: <>74 -brak EE
breq IEE_RET ; =74 --> EEPROM poprawny
IEE_IEE: ldi zl, low(2*EE_ADE_ini)
ldi zh, high(2*EE_ADE_ini) ; adres danych do zapisania
ldi temp, low(2*EE_KON)
mov r0, temp
ldi temp, high(2*EE_KON)
mov r1, temp ; adres koncowy danych
clr yh
out EEARH, yh
ldi ee_adr, EEPROM ; adres poczatkowy w EEPROM
IEE_1: lpm ee_dane, z+ ; pobierz bajt z Flash
rcall EE_ZAPIS ; i zapisz w EE
inc ee_adr
cp zl, r0
cpc zh, r1 ; porownanie czy koniec danych
brlo IEE_1 ; jesli < to nastepny bajt
IEE_GOT: ldi ee_adr, 4 ; testowana komorka pamieci
ldi ee_dane, 74 ; testowana wartosc (EEPROM poprawny)
rcall EE_ZAPIS
IEE_RET: ret
;--------------------------------------
EE_ZAPIS: ; tylko pierwsze 256 bajtow! (nie obsluguje EEADRH)
sbic EECR, EEWE ; czekaj na ewentualny koniec zapisu lub odczytu EE
rjmp EE_ZAPIS
out EEARL, ee_adr ; wpisz adres komorki EE
out EEDR, ee_dane ; wpisz dane do zapisu
sbi EECR, EEMWE ; ustaw pierwszy znacznik zapisu
sbi EECR, EEWE ; ustaw drugi znacznik zapisu
ret ; po dwoch cyklach oczekiwania praca procesora jest kontynuowana
; a "w tle" jest wykonywany zapis bajtu w EEPROM
.exit
;------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -