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

📄 menu.asm

📁 实现对ADE7759电能芯片的读写和校准,AVR单片机源码与电路图,单相电能表读写程序和初始化程序
💻 ASM
📖 第 1 页 / 共 3 页
字号:

	sbrc	r7, 1		; jesli r7(1)=1 to zmienna 2-bajtowa
	rjmp	MAZR_2B1
	; 1bajt
	ld	r0, z		; wczytaj wartosc zmiennej
	clr	r1
	brtc	MAZR_PL		; jesli liczba w kodzie U2 to powiel bity znaku
	sbrs	r0, 7		; jesli r0(7)=1 to liczba ujemna
	rjmp	MAZR_PL
	ser	temp
	mov	r1, temp		; bity znaku
MAZR_PL:	rcall	EDYCJA
	ld	temp, z
	cp	r0, temp
	breq	MAZR_W		; identyczne --> brak zmiany
	st	z, r0
	rjmp	MAZR_ADE
	; 2bajty
MAZR_2B1:	ld	r0, z		; wczytaj wartosc zmiennej
	ldd	r1, z+1
	rcall	EDYCJA
	ld	temp, z
	cp	r0, temp
	ldd	temp, z+1
	cpc	r1, temp		; porownianie nowej wartosci z ta z RAM
	breq	MAZR_W		; identyczne --> brak zmiany
	st	z, r0
	std	z+1, r1		; zapisanie nowej wartosci

MAZR_ADE:	tst	r6
	breq	MAZR_W		; jesli r6=0, to nie wysylac do ADE

	sbrc	r7, 1		; jesli r7(1)=1 to zmienna 2-bajtowa
	rjmp	MAZR_2B2		; rejestr dwubajtowy
	mov	temp, r6
	cli
	rcall	SPI_ADE_WRITE_1B	; temp -komenda; r0 -1 bajt danych
	sei
	rjmp	MAZR_W
MAZR_2B2:	mov	temp, r6
	cli
	rcall	SPI_ADE_WRITE_2B	; temp -komenda; r1:r0 -2 bajty danych
	sei

MAZR_W:	;rcall	OIP	; obliczenie ilosci Probek_ile (przydatne tylko przy zmianie ilosci okresow)
	rcall	US_HIST_ZERA

	pop	r0
	out	SREG, r0
	pop	r7
	pop	r6	;wyn2
	pop	r5	;wyn1
	pop	r4	;wyn0
	pop	r3
	pop	r2
	rjmp	M_AZR_W


;--------------------------------------
PUST2:	; czyszczenie 2-go wiersza LCD
	ldi	temp, LCD_LINE_2
	rcall	LCD_COMMAND
	ldi	zl,  low(2*txt_pust)
	ldi	zh, high(2*txt_pust)	; czyszczenie 2-go wiersza
	rcall	LCD_STR_FLASH
	ret


MADE_W:	ldi	zl,  low(2*txt_zro)	; komunikat "Zrobione"
	ldi	zh, high(2*txt_zro)
	rjmp	MX_WYSW


;==============================================================================
M_ZR_W:	; podglad zmiennych z RAM (nie tylko zwiazanych z ADE7759)
	; par0 -adres zmiennej (low); par1 -ilu bajtowa
	in	r0, SREG
	push	r0
	; sprawdzenie czy liczba w kodzie U2
	clt			; czysc flage liczby ze znakiem
	sbrc	par1, 7		; jesli bit7=1 to zmienna U2
	set			; ustaw flage liczby ze znakiem

	sbrc	par1, 1		; jesli bit1=1 to zmienna 2-bajtowa
	rjmp	MZRW_2B
	; 1bajt
	mov	zl, par0
	clr	zh
	ld	r0, z		; wczytaj wartosc zmiennej
	clr	r1
	brtc	MZRW_PL		; jesli liczba w kodzie U2 to powiel bity znaku
	sbrs	par1, 7		; bit 7 informuje o liczbie ze znakiem
	rjmp	MZRW_PL
	ser	temp
	mov	r1, temp		; bity znaku

MZRW_2B:	mov	zl, par0
	clr	zh
	ld	r0, z+		; czytaj zmienna
	ld	r1, z
MZRW_PL:	rcall	WYSW_HEX_DEC_2B
	pop	r0
	out	SREG, r0
	ret


;------------------------------------------------------------------------------
M_OPC_W:	; rozne ustawienia -wyswietlanie
	; par1:par0 -adres parametrow
	push	r2
	push	r3
	push	r4
	push	r5
	rcall	PUST2

	movw	zl, par0		; adres danych
	lpm	r0, z+		; adres zmiennej
	lpm	r1, z+		; maska
	lpm	r2, z+
	lpm	r3, z+		; r3:r2 -adres komunikatu gdy bit=0
	lpm	r4, z+
	lpm	r5, z+		; r5:r4 -adres komunikatu gdy bit=1

	mov	zl, r0
	clr	zh
	ld	r0, z		; pobierz zmienna
	and	r0, r1		; maska na bit
	movw	zl, r2
	breq	MOPCW_ZE		; bit wyzerowany
	; bit ustawiony
	movw	zl, r4
MOPCW_ZE:	ldi	temp, LCD_LINE_2
	rcall	LCD_COMMAND
	rcall	LCD_STR_FLASH	; wyswietl linie

	pop	r5
	pop	r4
	pop	r3
	pop	r2
	ret


;--------------------------------------
M_OPC:	; Rozne ustawienia bitowe
	; par1:par0 -adres parametrow

	movw	zl, par0		; adres danych
	lpm	r0, z+		; adres zmiennej
	lpm	r1, z+		; maska

	mov	zl, r0
	clr	zh
	ld	r0, z		; pobierz zmienna
	mov	temp, r0		; kopia
	and	temp, r1		; maska na bit
	breq	MOPC_US		; bit wyzerowany -> ustaw
	; bit ustawiony -> zeruj
	com	r1		; odwroc maske
	and	r0, r1		; zeruje bit
	rjmp	MOPC_D
MOPC_US:	or	r0, r1		; ustawia bit
MOPC_D:	st	z, r0		; zapisz zmienna

	cli
	cbr	flagi, (1<<fTARYFY) | (1<<fTARYFA2)	; ustaw licznik jednotaryfowy i taryfe1
	lds	temp, Flagi2
	lsr	temp		; bit TARYFY do C
	brcc	MT0
	sbr	flagi, 1<<fTARYFY	; ustaw licznik dwutaryfowy
MT0:	rcall	SPRAWDZ_TARYFE

	push	ee_adr
	push	ee_dane
	lds	ee_dane, Flagi2
	ldi	ee_adr, (low(Flagi2) -RAM) +EEPROM
	rcall	EE_ZAPIS
MOPC_1:	sbic	EECR, EEWE		; czekaj koniec zapisu
	rjmp	MOPC_1
	pop	ee_dane
	pop	ee_adr

	sei
	rjmp	M_OPC_W		; odswiezenie LCD


;==============================================================================
DATACZAS:	; wyswietla date i czas na LCD (w jednej linii)
	; w rejestrze Z adres Bufora wypelnionego data i czasem
	ldi	temp, '2'
	rcall	LCD_CHAR
	ldi	temp, '0'
	rcall	LCD_CHAR
	ld	r0, z		; pobierz rok
	rcall	HEX_1B
	ldi	temp, '-'
	rcall	LCD_CHAR
	ldd	r0, z+1		; pobierz miesiac
	rcall	HEX_1B
	ldi	temp, '-'
	rcall	LCD_CHAR
	ldd	r0, z+2		; pobierz dzien
	rcall	HEX_1B

	ldi	temp, ' '
	rcall	LCD_CHAR
	ldd	r0, z+3		; pobierz godziny
	rcall	HEX_1B
	ldi	temp, ':'
	rcall	LCD_CHAR
	ldd	r0, z+4		; pobierz minuty
	rcall	HEX_1B
	ret

;------------------------------------------------------------------------------
M_CZAS:	; odczyt DS1307, wyswietlenie czasu i daty
	cli
	push	yl
	push	yh
	rcall	CZYTAJ_DS1307
	pop	yh
	pop	yl
	sei

	ldi	zl,  low(Bufor)
	ldi	zh, high(Bufor)
	lds	r0, Rok_bcd
	st	z, r0
	lds	r0, Miesiac_bcd
	std	z+1, r0
	lds	r0, Dzien_bcd
	std	z+2, r0
	lds	r0, Godziny_bcd
	std	z+3, r0
	lds	r0, Minuty_bcd
	std	z+4, r0

	rcall	LCD_CLEAR
	rcall	DATACZAS

	ldi	temp, LCD_LINE_2
	rcall	LCD_COMMAND
	lds	temp, Dzien_tyg
MC_DNI:	push	r0
	push	r1
	push	zl
	push	zh
	ldi	zl,  low(da_dni)	; adres (word-1) do tabeli adresow dni tygodnia
	ldi	zh, high(da_dni)
	add	zl, temp		; dodanie dnia tygodnia: 1-Pn., 7-Nd
	clr	temp
	adc	zh, temp
	lsl	zl
	rol	zh		; adres*2 aby wczytywac bajty
	lpm	r0, z+
	lpm	r1, z+		; pobranie adresu (word) do wybranego dnia tyg.
	movw	zl, r0		; adres do Z
	rcall	LCD_STR_FLASH	; wyswietl linie
	pop	zh
	pop	zl
	pop	r1
	pop	r0
	ret


;------------------------------------------------------------------------------
M_CZAS_ED:	; edycja zmiennych daty lub czasu w formacie BCD
	; par1:par0 -poczatek serii danych do edycji
	push	r2
	push	r6	;bin0
	push	r18	;bcd0
	push	r19	;bcd1
	push	yl
	push	yh

	ldi	temp, LCD_D1_C0_B1
	rcall	LCD_COMMAND
	movw	zl, par0		; adres pierwszej danej do z

MCE_ZN:	lpm	yl, z+		; adres zmiennej w Y
	clr	yh
	ld	bcd0, y		; wartosc zmiennej...
	rcall	BCD_8_BIN		; ...w bin0
	lpm	r0, z+		; min
	lpm	r1, z+		; max
	lpm	r2, z+		; numer znaku na LCD
	rcall	MCE_KUR		; umiesc kursor we wlasciwym miejscu
	sbiw	zl, 4

	rjmp	MCE_LCD

;--------
MCE_KL:	wdr
	; detekcja dlugiego trzymania klawisza
	sbrc	flagi, fOVER_I
	rjmp	MCE_KL_DL

	; detekcja, czy jest to pierwsze wejscie do procedury obslugi klawisza
	sbrc	flagi, fKLAW_WCIS	; przeskocz, jesli flaga wyzerowana
	rjmp	MCE_KL		; na poczatek petli

	lds	temp, Klawisze	; laduj zmienna o stanie klawiszy
	tst	temp
	breq	MCE_KL		; brak nacisniecia

	; rozpoznanie wcisnietego klawisza
	KLAWISZ_WCISNIETY		; ustaw bit wcisniecia klawisza
	sbrc	temp, KLAW_TAK	; przeskocz, jesli to nie klawisz TAK
	rjmp	MCE_TAK		; klawisz TAK wcisniety - zatwierdzenie
	sbrc	temp, KLAW_NIE
	rjmp	MCE_NIE
	sbrc	temp, KLAW_L
	rjmp	MCE_LEWO
	sbrc	temp, KLAW_P
	rjmp	MCE_PRAWO
MCE_KL_DL:	lds	temp, Klawisze
	cbr	flagi, 1<<fOVER_I	; zeruj flage dlugiego wcisniecia klawisza
	sbrc	temp, KLAW_G
	rjmp	MCE_GORA
	sbrc	temp, KLAW_D
	rjmp	MCE_DOL
	rjmp	MCE_KL		; na poczatek petli

;--------
MCE_TAK:	; zatwierdzenie zmiany: z=0xFFFF
	ldi	zl, 0xFF
	mov	zh, zl
	rjmp	MCE_K
MCE_NIE:	; anulowanie zmiany z=0
	ldi	zl, 0
	mov	zh, zl
MCE_K:	ldi	temp, LCD_D1_C0_B0
	rcall	LCD_COMMAND
	pop	yh
	pop	yl
	pop	r19
	pop	r18
	pop	r6
	pop	r2
	ret


	; edycja zmiennej w bin0
MCE_GORA:	; zwiekszenie liczby o 1 jesli mozliwe
	cp	bin0, r1
	brlo	MCEG_A		; mniejsza  --> zwiekszenie
	rjmp	MCE_KL		; na poczatek petli
MCEG_A:	ldi	temp, 1		; +1
	tst	bin0
	brne	MCEG_B
	sbr	flagi, 1<<fOVER_U
MCEG_B:	add	bin0, temp
	rjmp	MCE_LCD		; dane sie zmienily

MCE_DOL:	; zmniejszenie liczby o 1 jesli mozliwe
	cp	r0, bin0
	brlo	MCED_A		; mniejsza  --> zwiekszenie
	rjmp	MCE_KL		; na poczatek petli
MCED_A:	ldi	temp, 1		; -1
	sub	bin0, temp
	rjmp	MCE_LCD		; dane sie zmienily

MCE_LEWO:	; zmiana zmiennej do edycji
	cp	par0, zl
	cpc	par1, zh		; czy mozna wybrac wczesniejsza zmienna?
	brlo	MCEL_A
	rjmp	MCE_KL		; na poczatek petli
MCEL_A:	sbiw	zl, 4		; poprzednia zmienna
	rjmp	MCE_ZN		; zmien wskaznik na LCD

MCE_PRAWO:	; zmiana zmiennej do edycji
	sbrc	r2, 7		; bit7 numeru_znaku_lcd oznacza koniec danych
	rjmp	MCE_KL		; na poczatek petli
MCEP_A:	adiw	zl, 4		; nastepna zmienna
	rjmp	MCE_ZN		; zmien wskaznik na LCD

;--------------------------------------
MCE_LCD:	mov	temp, r1
	cpi	temp, 7		; spr. czy wyswietlic dzien tygodnia (max.=7)
	brne	MCELCD_1		; <>7 --> liczba
	st	y, bin0		; zapis Dzien_tyg
	movw	bcd0, zl		; ochrona Z
	sbrs	flagi, fOVER_U
	rjmp	MCELDNI
	ldi	zl,  low(2*txt_pust)	; czyszczenie spacjami
	ldi	zh, high(2*txt_pust)
	rcall	LCD_STR_FLASH
	rcall	MCE_KUR
	cbr	flagi, 1<<fOVER_U
MCELDNI:	mov	temp, bin0
	rcall	MC_DNI		; wyswietl nazwe dnia tyg.
	rcall	MCE_KUR		; kursor na miejsce edycji
	movw	zl, bcd0
	rjmp	MCE_KL		; na poczatek petli

MCELCD_1:	mov	bcd0, bin0
	rcall	BIN_7_BCD
	mov	temp, bcd1
	swap	temp
	or	temp, bcd0		; pakowanie liczby BCD
	st	y, temp		; zapis zmiennej w RAM
	ori	bcd0, 0b00110000	; poprawne ustawienie cyfry w tablicy znakow
	ori	bcd1, 0b00110000
	ldi	temp, LCD_CURSOR_LEFT
	rcall	LCD_COMMAND
	mov	temp, bcd1
	rcall	LCD_CHAR
	mov	temp, bcd0
	rcall	LCD_CHAR
	ldi	temp, LCD_CURSOR_LEFT
	rcall	LCD_COMMAND
	rjmp	MCE_KL		; na poczatek petli

;--------------------------------------
MCE_KUR:	mov	temp, r2
	andi	temp, 0b01111111	; maskuj bit konca serii
	ori	temp, LCD_LINE_1
	rcall	LCD_COMMAND		; kursor na miejsce edycji
	ret


;------------------------------------------------------------------------------
M_DACZ:	; edycja daty i czasu
	rcall	M_CZAS_ED		; par1:par0 -dane
	; rejestr Z zawiera status wykonania:
	cpi	zh, 0xFF
	brne	MDC_NIE
	; zatwierdzenie zmiany
	cli
	push	yl
	push	yh
	rcall	USTAW_DS1307_ALL
	pop	yh
	pop	yl
	sei
	;rcall	SPRAWDZ_TARYFE	; w USTAW_DS1307_ALL
	rcall	DELAY_44us
MDC_NIE:	; anulowanie zmiany
	rcall	M_CZAS		; wyswietlenie (starego, jesli _NIE) czasu

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -