⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inne.asm

📁 实现对ADE7759电能芯片的读写和校准,AVR单片机源码与电路图,单相电能表读写程序和初始化程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;==============================================================================
;  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 + -