📄 inne.asm
字号:
;==============================================================================
; Inne procedury
; Projekt: Miernik energii i mocy na ADE7759
;==============================================================================
.cseg
;==============================================================================
INT_WLACZ: ; wlacza przerwanie INT0 i INT2
in temp, GICR
sbr temp, (1<<INT0) | (1<<INT2) ; ustawia bit INT0 i INT2
out GICR, temp
ldi temp, (1<<INTF0) | (1<<INTF2)
out GIFR, temp ; kasuj flage przerwania
ret
;--------------------------------------
TIMER1_ICP: ; timer1 w trybie Input Capture
clr r2
out TCCR1B, r2 ; wylacz taktowanie timera
out TCCR1A, r2 ; tryb normalny (liczenie w gore)
; czyszczenie licznika
out TCNT1H, r2
out TCNT1L, r2
; zerowanie bitow przerwan
in temp, TIMSK
cbr temp, (1<<TICIE1) | (1<<OCIE1A) | (1<<OCIE1B) | (1<<TOIE1)
out TIMSK, temp
; czyszczenie flag
in temp, TIFR
sbr temp, (1<<ICF1) | (1<<OCF1A) | (1<<OCF1B) | (1<<TOV1)
out TIFR, temp
ldi temp, 1<<CS11 ; zbocze opadajace na ICP...
out TCCR1B, temp ; ...i wlacz taktowanie CLK/8
ret
;------------------------------------------------------------------------------
TIMER0_USTAW: ; ustawia timer0 na czas ~32ms
; oraz ustawia zglaszanie przerwan do obslugi klawiatury
clr temp
out TCNT0, temp
ldi temp, 1<<TOIE0
out TIMSK, temp ; generacja przerwania
in temp, TIFR
sbr temp, 1<<TOV0
out TIFR, temp ; czyszczenie flagi
ldi temp, (1<<CS02) | (1<<CS00)
out TCCR0, temp ; Fosc/1024
ret
;==============================================================================
; TIMER0_INT
; Przerwanie czasowe: co 32ms sprawdzanie stanu klawiatury
; dziala zawsze, wiec stan klawiatury jest zawsze aktualny, co wykorzystuje
; sie w MENU i przy edycji zmiennych
; czas obslugi przerwania: (dla wylaczonych przerwan (cli))
; 28c -klawisz niewcisniety
; 18c+10c -klawisz wcisniety
;==============================================================================
TIMER0_INT: ; przerwanie po przepelnieniu Timer0
push temp
in temp, SREG
push temp
; sprawdzenie stany klawiatury i zapisanie stanu do zmiennej "Klawisze"
in temp, KLAW_PIN
com temp ; aby nacisniety klawisz symbolizowal stan "1"
andi temp, KLAW_MASKA
sts Klawisze, temp ; zapis do zmiennej
sbrc flagi, fMENU ; przeskocz, jesli fMENU=0
rjmp T0I_MENU ; fMENU=1
; fMENU=0
brne T0I_NORM ; skacz, jesli temp<>0 (klawisz nacisniety)
KLAWISZ_PUSZCZONY
rjmp T0I_Z ; temp=0 -> brak nacisniecia
; fMENU=1
T0I_MENU: brne T0I_KPZ ; skacz, jesli temp<>0 (klawisz nacisniety)
KLAWISZ_PUSZCZONY ; temp=0
clr temp
sts Klaw_dlugo, temp ; zeruje czas trzymania klawisza
cbr flagi, 1<<fOVER_I ; zeruje flage dlugiego trzymania
; liczenie czasu przerwy miedzy nacisnieciami
push xl
push xh
lds xl, Klaw_pusz
lds xh, Klaw_pusz+1
cpi xh, KLAWISZ_CZAS_NIEAKTYWNY
brne T0I_CZNO
ldi temp, 1<<KLAW_NIE ; ustaw wyjscie z MENU
sts Klawisze, temp
rjmp T0I_CZW
T0I_CZNO: adiw xl, 1
sts Klaw_pusz, xl
sts Klaw_pusz+1, xh
T0I_CZW: pop xh
pop xl
rjmp T0I_Z
T0I_KPZ: clr temp
sts Klaw_pusz, temp ; jesli klawisz nacisniety, to zeruje czas
sts Klaw_pusz+1, temp
; obsluga dlugiego wcisniecia klawisza
lds temp, Klaw_dlugo
cpi temp, KLAWISZ_CZAS_TRZYMANIA
brne T0I_FNO ; skacz, jesli nie rowne
sbr flagi, 1<<fOVER_I ; ustaw flage dlugiego trzymania klawisza (druga funkcja)
rjmp T0I_Z
T0I_FNO: inc temp
sts Klaw_dlugo, temp
rjmp T0I_Z
T0I_NORM: sei ; przerwania musza byc wlaczone, gdyz obsluga menu trwa dlugo
rcall KLAW_NORMAL ; sprawdzenie jaki klawisz nacisnieto i wykonanie akcji
cli
T0I_Z: pop temp
out SREG, temp
pop temp
reti
;==============================================================================
ZBIERANIE_PROBEK_WLACZ:
lds temp, Ade_irqen ; zaladuj zmienna przechowujaca stan rejestru IRQEN
sbr temp, 1<<I_WSMP ; ustaw bit przerwania od probek
sts Ade_irqen, temp ; zapisz zmienna
mov r0, temp
ldi temp, ADE_IRQEN_ADR ; zaladuj adres rejestru
rcall SPI_ADE_WRITE_1B ; wyslij
ret
;--------------------------------------
ZBIERANIE_PROBEK_WYLACZ:
lds temp, Ade_irqen ; zaladuj zmienna przechowujaca stan rejestru IRQEN
cbr temp, 1<<I_WSMP ; czysc bit przerwania od probek
sts Ade_irqen, temp ; zapisz zmienna
mov r0, temp
ldi temp, ADE_IRQEN_ADR ; zaladuj adres rejestru
rcall SPI_ADE_WRITE_1B ; wyslij
ret
;==============================================================================
HEX_1B: ; wyswietlenie bajtu w postaci hexadecymalnej: r0 -liczba
; od aktualnej pozycji kursora, w formacie "??h" ...
; ...jesli temp zawiera 'h' - w innym przypadku tylko liczba
push temp
mov temp, r0
swap temp
andi temp, 0x0F
ori temp, 0b00110000 ; poprawne ustawienie cyfry w tablicy znakow
cpi temp, ':' ; ':' jest po cyfrze 9
brlo H1_1 ; cyfry 0-9
subi temp, -7 ; cyfry A-F -> dodaj 7
H1_1: rcall LCD_CHAR ; wyswietlenie 1-szej cyfry
mov temp, r0
andi temp, 0x0F
ori temp, 0b00110000 ; poprawne ustawienie cyfry w tablicy znakow
cpi temp, ':' ; ':' jest po cyfrze 9
brlo H1_A ; cyfry 0-9
subi temp, -7 ; cyfry A-F -> dodaj 7
H1_A: rcall LCD_CHAR ; wyswietlenie 2-giej cyfry
pop temp
cpi temp, 'h'
brne H1_K
rcall LCD_CHAR
H1_K: ret
;------------------------------------------------------------------------------
HEX_2B: ; wyswietlanie wartosci hex 2B od aktualnej pozycji kursora
; r1:r0 -liczba
clr temp
push r0
mov r0, r1 ; najpierw starszy bajt
rcall HEX_1B
pop r0
ldi temp, 'h'
rcall HEX_1B ; teraz mlodszy
ret
;------------------------------------------------------------------------------
WYSW_HEX_DEC_2B: ; wyswietlenie liczby 2-bajtowej (ze znakiem) na LCD W DRUGIEJ LINII
; r1:r0 -liczba; najpierw hex potem dec
; flaga T informuje o liczbach ze znakiem (w uzupelnieniu do dwoch)
push r6 ; bin0, cyfra0
push r7 ; bin1, cyfra1
push r8 ; bin2, cyfra2
push r9 ; bin3, cyfra3
push r10 ; cyfra4
push r11 ; cyfra5
push r12 ; cyfra6
push r13 ; cyfra7
push r14 ; cyfra8
push r15 ; cyfra9
push r18 ; bcd0
push r19 ; bcd1
push r20 ; bcd2
push r21 ; bcd3
push r22 ; bcd4
push xl
push xh
push yl
push yh
movw bin0, r0 ; kopia liczby dla wysw. dziesietnego
brtc WHD2_P ; jesli T=1 to liczba w kodzie U2
sbrs bin1, 7 ; jesli bit znaku ustawiony -to neguj liczbe
rjmp WHD2_P
com bin0 ; negacja liczby
com bin1 ; .
ldi temp, 1
add bin0, temp ; Add 1
clr temp
adc bin1, temp ; Add carry
WHD2_P: rcall BIN_16_BCD ; na BCD
push r1
rcall ROZPAKUJ_BCD ; cyfry w cyfra4::cyfra0
pop r1
ldi temp, LCD_LINE_2
rcall LCD_COMMAND
rcall HEX_2B ; wyswietlanie wartosci hex 2B
ldi temp, ' '
rcall LCD_CHAR
ldi temp, ' '
rcall LCD_CHAR
ldi temp, ' '
rcall LCD_CHAR
mov temp, cyfra4 ; wyswietlanie wartosci dec
rcall LCD_CHAR
mov temp, cyfra3
rcall LCD_CHAR
mov temp, cyfra2
rcall LCD_CHAR
mov temp, cyfra1
rcall LCD_CHAR
mov temp, cyfra0
rcall LCD_CHAR
ldi temp, 'd'
rcall LCD_CHAR
brtc WHD2_K ; jesli T=1 to liczba w kodzie U2
ldi temp, LCD_LINE_2 | 7
rcall LCD_COMMAND
ldi temp, ' '
sbrs r1, 7 ; jesli bit znaku ustawiony
rjmp WHD2_S
ldi temp, '-' ; wyswietlenie znaku '-'
WHD2_S: rcall LCD_CHAR
WHD2_K:
pop yh
pop yl
pop xh
pop xl
pop r22
pop r21
pop r20
pop r19
pop r18
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
ret
;==============================================================================
EDYCJA: ; edycja wartosci liczby HEX, interaktywnie na LCD
; r1:r0 -liczba, r3:r2 -wartosc min., r5:r4 -wartosc max.
; flaga T informuje o liczbach ze znakiem (w uzupelnieniu do dwoch)
push r24 ; r25:r24 kopia oryginalnej liczby
push r25 ; ...do modyfikacji
push zl
push zh
movw r24, r0 ; kopia oryginalnej liczby do r25:r24
ldi temp, LCD_D1_C0_B1
rcall LCD_COMMAND
ED_ST: rcall WYSW_HEX_DEC_2B ; wyswietlenie liczby
ldi temp, LCD_LINE_2 | 3
rcall LCD_COMMAND
;--------
ED_KL: wdr
; detekcja dlugiego trzymania klawisza
sbrc flagi, fOVER_I
rjmp ED_KL_DL
; detekcja, czy jest to pierwsze wejscie do procedury obslugi klawisza
sbrc flagi, fKLAW_WCIS ; przeskocz, jesli flaga wyzerowana
rjmp ED_KL ; na poczatek petli
lds temp, Klawisze ; laduj zmienna o stanie klawiszy
tst temp
breq ED_KL ; brak nacisniecia
; rozpoznanie wcisnietego klawisza
KLAWISZ_WCISNIETY ; ustaw bit wcisniecia klawisza
sbrc temp, KLAW_TAK ; przeskocz, jesli to nie klawisz TAK
rjmp ED_TAK ; klawisz TAK wcisniety - zatwierdzenie
sbrc temp, KLAW_NIE
rjmp ED_NIE
ED_KL_DL: lds temp, Klawisze
cbr flagi, 1<<fOVER_I ; zeruj flage dlugiego wcisniecia klawisza
sbrc temp, KLAW_G
rjmp ED_GORA
sbrc temp, KLAW_D
rjmp ED_DOL
sbrc temp, KLAW_L
rjmp ED_LEWO
sbrc temp, KLAW_P
rjmp ED_PRAWO
rjmp ED_KL ; na poczatek petli
;--------
ED_NIE: ; anulowanie zmiany (jesli ED_NIE)
movw r0, r24 ; przywrocenie oryginalnej wartosci
ED_TAK: ; zatwierdzenie zmiany
ldi temp, LCD_D1_C0_B0
rcall LCD_COMMAND
pop zh
pop zl
pop r25
pop r24
ret
;--------------------------------------
ED_GORA: ; zwiekszenie wartosci liczby r1:r0 o 1
cp r0, r4
cpc r1, r5
brts EDG_Z ; jesli T=1 -> liczba ze znakiem
brlo EDG_A ; mniejsza --> zwiekszenie
rjmp ED_KL ; na poczatek petli
EDG_Z: brlt EDG_A
rjmp ED_KL
EDG_A: ldi temp, 1
add r0, temp
clr temp
adc r1, temp
rjmp ED_ST ; dane sie zmienily
;--------------------------------------
ED_DOL: ; zmniejszenie wartosci liczby r1:r0 o 1
cp r2, r0
cpc r3, r1
brts EDD_Z ; jesli T=1 -> liczba ze znakiem
brlo EDD_A ; wieksza --> zmniejszenie
rjmp ED_KL
EDD_Z: brlt EDD_A
rjmp ED_KL
EDD_A: ldi temp, 1
sub r0, temp
clr temp
sbc r1, temp
rjmp ED_ST ; dane sie zmienily
;--------------------------------------
ED_LEWO: ; zmniejszenie wartosci liczby r1:r0 o 256 (czyli starszy bajt)
cp r3, r1
brts EDL_Z ; jesli T=1 -> liczba ze znakiem
brlo EDL_A ; wieksza --> zmniejszenie
rjmp ED_KL
EDL_Z: brlt EDL_A
rjmp ED_KL
EDL_A: ldi temp, 1
sub r1, temp
rjmp ED_ST ; dane sie zmienily
;--------------------------------------
ED_PRAWO: ; zwiekszenie wartosci liczby r1:r0 o 256 (czyli starszy bajt)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -