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

📄 battery_check.asm

📁 ht46r47,电源管理源码
💻 ASM
字号:
;************************************ 
include HT46R47.inc 
;*************************************
;*************************************************
data .section 'data' 
	on_01			db ?
	main_01		db ?
	on_off_bit	db ?
	sl_idle		db ?
	idle_01		db ?
	pac_bak		db ?
	pa_bak    	db ?
	pbc_bak		db ?
	pb_bak		db ?
	intc_bak 	db ?
	spb_bak		db ?
	spbc_bak		db ?
	sintc_bak	db ?
	temp 			db ? 
	intc_out		db ?
	delay_in  	db ?
	delay_4s  	db ?
	check_4s  	db ?
	check_01		db ?
	check_times db ?
	adbuf_h 		db ? 
	adbuf_hc 	db ? 
	adbuf_l		db ?
	adcnt			db ?
	check_end	db ?
	times1_bit	db ?
	timer_in		db ?
	time5min		db ?
	time_a 		db ?
	time30min 	db ?
	time60min 	db ? 
;*************************************** 
code .section at 0 'code' 
	org 000h 
	jmp main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	org 004h 		;external interrupt
	jmp exitint
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	org 008h 		;intial timer interrupt 
	jmp timint 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	org 00ch			;intial	a/d converter interrupt 
	nop
	reti 
;***************************************

	mmov macro a1,b1
	mov 	a,		b1
	mov 	a1,	a 
	endm
;***************************************

; external interrupt
exitint:
	mmov	idle_01,			01h				;idle mode check bit
	clr	timer_in		
	mmov 	time5min, 		0ffh
	mmov 	time_a, 			0ffh
	mmov 	time30min, 		0ffh
	mmov 	time60min, 		0ffh
	mmov 	intc_out,		01h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;timing interrupt
timint: 							;timer interrupt ISR	
	dec 	timer_in 			;timer interrupt 1 times is 8ms 
	dec 	delay_in				;check power delay
reti
;***************************************  
;initial process section
initial:
	clr 	intc 
	clr 	tmrc 
	clr	adcr 
	clr 	on_off_bit			;control open & shut_down 
	clr 	on_01					;
	clr 	status
	
; I/O setup
	mmov 	pac,		089h		;pa1 pa2 pa5 pa6 output,pa4 timer enabled 
	mmov 	pa,		0h 		;pa0 pa3 pa7 input
	mmov 	pbc,		08h		;pb3 input ,pb0 is a/d
	mmov 	pb,		0h			;pb1,	pb2 is output
	set 	pdc 					;pd0 input
	clr 	pd
	
; check batter power setup
	mmov 	adcnt, 		0fch 	;set consecutive times 
	mmov 	times1_bit, 02h	;on power check battery
	clr 	adbuf_h
	clr 	adbuf_hc
	clr 	adbuf_l
	clr 	check_times
	clr  	check_01
	mmov 	delay_in,    	07dh	;check power  time set
	mmov 	check_4s,  	05h	;check power delay 14s
	
; clear ram
	mov 	a,			40h 		;general purpose data memory
	mov 	mp,		a 			
clrram:							;clear data memory 
	clr 	r0 
	inc 	mp 
	inc 	temp 
	mov 	a,			temp 
	xor 	a,			07fh		;data memory end address 
	sz 	z 
	jmp 	clrram

;timer setup
	mmov 	tmrc,			097h 	;time clock is fsys/128  
	mmov 	tmr,			06h	;timer is 8ms
	mmov 	timer_in, 	0fah	;1time interrupt is 2s(8msX250=2000ms)
	mmov 	time5min, 	06ah
	mmov 	time_a, 		09ch	;200s loop
	mmov 	time30min, 	0f7h	;200X9=1800s , 10min
	mmov 	time60min, 	0eeh	;200X18=3600s, 1h
;interrupt set	
	mmov 	intc,			055h	;enable only timer interrupt. 
	clr  	intc_out
	mmov 	delay_4s,    02h	;interrupt inform to main_cpu
;idle mode
	mmov 	idle_01,		01h	;
ret
;***************************************

sleep_bak:
	set  	pa.6
wait_pa7:
	snz   pa.7					;如果pa7=1 进入“睡眠模式”
	jmp  	wait_pa7
	clr  	pa.6
	mmov 	adcr, 		0h
	mmov 	spbc_bak, 	pbc
	mmov 	spb_bak, 	pb
	mmov 	sintc_bak, 	intc
	clr 	pac.0
	clr 	pa.1
	clr  	pb.0
	clr  	pb.1
	clr  	pb.2
	clr 	intc.0 
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

sleep_wake_up:
	set 	pa.1
	mmov 	intc, 		sintc_bak
	mmov	pbc,			spbc_bak
	mmov 	pb, 			spb_bak
	set		pac.0
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; before sleep_mode, backup all I/O status, backup all register's 
sleep_mode:
	sz   	main_01				;if main_01 = 1, indicate from mian_loop enter sleep
	call 	sleep_bak			
	clr  	tmrc.4				;if main_01 = 0, indicate from timing enter sleep
	clr  	intc.0
loop_sleep:
	snz  	pb.3
	jmp 	loop_sleep
	set 	tmrc.4
	set 	intc.0
	sz 	main_01
	call 	sleep_wake_up
ret
;***************************************

idle_wake_up:
	set	pa.1
	clr	intc
	mmov 	intc, 		intc_bak
	clr		pa.7
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; before enter idle_mode, backup all I/O status, backup all register's 
idle_mode:
	clr 	idle_01					;before enter idle mode, clear idle_01
	mmov 	adcr, 		0h
	mmov 	intc_bak, 	intc
	mmov 	pb_bak, 		pb
	clr 	pa.1
	clr  	pb.0
	clr  	pb.1
	clr  	pb.2
	clr	intc
	mmov 	intc, 		047h 		;external and timer interrupt
loop_idle1:
	nop
	sz		pa.0
	clr	on_01
	call 	long_push				; long_time push_key run pvi
	sz		idle_01					;if idle_01=0 , in idle_01
	jmp 	loop_idle3				;if idle_01=1, indiate return from ISR
	sz  	pb.3
	jmp 	loop_idle1
	clr 	intc.0
loop_idle2:
	snz  	pb.3
	jmp 	loop_idle2
loop_idle3:
	call 	idle_wake_up
ret

;***************************************
adpro: 						;A/D conversion 
	dec  	times1_bit
	mmov 	adcr,	08h 		;pb0 is a/d pin
	mmov 	acsr,	02h		;a/d clock is fsys/32
	clr  	adcr.7
	nop
	nop
	nop
	set  	adcr.7 			; reset A/D
	nop
	nop
	nop
	clr  	adcr.7 			; start A/D	
lpask: 
	nop
	sz  	adcr.6 			; poll the ADCR register EOCB bit to detect end of A/D conversion
jmp lpask 
	sz   	times1_bit
	jmp  	adpro

	mmov 	times1_bit, 01h
	mov  	a, 	adrh 		;read A/D conversion result 
	addm 	a,		adbuf_h 	;to add 
	sz   	status.0
	inc  	adbuf_hc 
	mmov  temp, 	adrl
	mov  	a, 		080h
	and  	a, 		temp
	snz  	status.2
	inc  	adbuf_l
	siz  	adcnt 			
	jmp  	adpro				;4 times convert if end? no, return 

	mmov 	check_4s,  05h
	clr  	check_01
	mmov 	adcnt,	0fch 	;update times of continue conversion  
	clr 	status.0 
	rrc 	adbuf_hc 
	rrc 	adbuf_h 			;AD result/2 
	rr		adbuf_l
;	clr 	status.0 
	rrc 	adbuf_h 			;AD result/2, get average of 4_times and save average to adbuf_h 
	rrc 	adbuf_hc 
	rr		adbuf_l

	rl		adbuf_h
	mov 	a, 		01h
	and 	a,			adbuf_l
	addm 	a, 		adbuf_h
	call 	voltage_check 	;battery voltage check
ret 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
voltage_check: 			;b5-3.5v c4-3.8v cf-4.0v d9-4.2v;;;;vdd is 3.27v 
	mov 	a,		0b5h 	
	sub 	a,		adbuf_h 	;c=0 if result is negative
	sz 	status.0
	call 	voltage_35 		;voltage>=3.5V 
	sz		check_end
	ret
	mov 	a,		0c4h		
	sub 	a,		adbuf_h 
	sz 	status.0
	call 	voltage_38 		;voltage>=3.8v 
	sz		check_end
	ret
	mov 	a,		0cfh	 	
	sub 	a,		adbuf_h 
	sz 	status.0
	call 	voltage_40 		;voltage>=4.0v
	sz		check_end
	ret
	mov 	a,		0d9h	 	
	sub 	a,		adbuf_h 
	sz 	status.0
	call 	voltage_42 		;voltage>=4.2v
ret 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
voltage_42:
	clr 	adbuf_h
	clr 	adbuf_hc
	clr 	adbuf_l
	clr 	pb.1
	clr 	pb.2
	clr 	check_times
	mmov	check_end,	01h
ret
voltage_40:
	clr 	adbuf_h
	clr 	adbuf_hc
	clr 	adbuf_l
	clr 	pb.1
	set 	pb.2
	clr 	check_times
	mmov	check_end,	01h
ret
voltage_38:
	clr 	adbuf_h
	clr 	adbuf_hc
	clr 	adbuf_l
	set 	pb.1
	clr 	pb.2
	clr 	check_times
	mmov	check_end,	01h
ret
voltage_35:
	clr 	adbuf_h
	clr 	adbuf_hc
	clr 	adbuf_l
	set 	pb.1
	set 	pb.2	
	inc 	check_times
	mmov	check_end,	01h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; check power one times on 14s
check_delay:
	clr 	status.2
	mov 	a, 		07dh
	and 	a, 		delay_in	;if timer_in=0 so result is 0
	snz 	status.2				;if result=0 so status.2=1
ret								;1 times loop is 2s
	mmov 	delay_in, 07dh	
	dec 	check_4s				;delays is 4
	sz 	status.2				;2X2=4s 
	inc 	check_01
ret
;***************************************
; enter timing mode , backup register
timer_bak:		
	clr 	tmrc.4
	mmov 	tmr,			06h	;timer is 8ms
	set 	tmrc.4
	mmov 	adcr, 		0h
	mmov 	pbc_bak, 	pbc
	mmov 	pb_bak, 		pb
	mmov 	intc_bak, 	intc
	clr  	pa.1
	clr  	pb.0
	clr  	pb.1
	clr  	pb.2
	mmov 	intc, 		047h 		;only disable a/d interrupt
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; timing end , comeback register and reset timer paramiter
timer_back_write:
	mmov 	intc, 	intc_bak
	set		pa.1
	mmov 	pbc, 		pbc_bak
	mmov 	pb, 		pb_bak
	clr  	pd
	mmov 	timer_in, 	0fah		;2s
	mmov 	time5min, 	06ah		;2X150=300s
	mmov 	time_a,		09ch		;2X100=200s loop
	mmov 	time30min, 	0f7h		;200X9=30min loop
	mmov 	time60min, 	0eeh		;200X18=60min loop
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 1min timing
time_5min:
	call 	timer_bak				;do timer_bak IO status, all IO set output 0 
loop1:
	call 	ptled_sleep
	sz		pa.0
	clr	on_01
	call 	long_push
	clr 	status.2
	mov 	a, 		0fah
	and 	a, 		timer_in		;if timer_in=0 so result is 0
	snz 	status.2					;if result=0 so status.2=1
	jmp loop1						;1 times loop is 2s
	mmov 	timer_in, 0fah	
	clr 	status.2
	inc 	time5min					;time5min is 150
	snz 	status.2					;2X150=300s is 5 minutes
	jmp loop1
	mmov 	time5min, 06ah			;reset time5min=106
	call 	timer_back_write		; back write IO status
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 30min timing
time_30min:
	call 	timer_bak
loop2:
	call 	ptled_sleep
	sz		pa.0
	clr	on_01
	call 	long_push
	clr 	status.2
	mov 	a, 		0fah
	and 	a, 		timer_in
	snz 	status.2
	jmp loop2						;2s timer reached
	mmov 	timer_in, 0fah
	clr 	status.2
	inc 	time_a					;time_a=156
	snz 	status.2					;100X2=200s status.2=1
	jmp loop2
	mmov 	time_a, 09ch			;reset time_a
	clr 	status.2
	inc 	time30min				;time30min=247
	snz 	status.2					;200X9=1800s status.2=1
	jmp loop2
	mmov 	time30min, 0f7h		;reset time30min
	call 	timer_back_write
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; 60min timing
time_60min:
	call 	timer_bak
loop3:
	call 	ptled_sleep
	sz		pa.0
	clr	on_01
	call 	long_push
	clr 	status.2
	mov 	a, 		0fah
	and 	a, 		timer_in
	snz 	status.2
	jmp loop3						;2s reached
	mmov 	timer_in, 0fah
	clr 	status.2
	inc 	time_a					;time_a=156
	snz 	status.2					;100X2=200s status.2=1
	jmp loop3
	mmov 	time_a,	09ch			;reset time_a
	clr 	status.2
	inc 	time60min				;time60min=18
	snz 	status.2					;200X18=3600s
	jmp loop3						
	mmov 	time60min, 0eeh		;reset time60min=237
	call 	timer_back_write
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

check_mode1:
	snz  	pd.0						; default mode, timer is no seting  enter idle mode   			
	call 	idle_mode
	sz  	pd.0
	call 	time_5min				;if pd=1, enter 5min set
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

check_mode2:
	snz 	pd.0						;if pd=0 enter time_30min setup, otherwise enter time_60min setup
	call 	time_30min
	sz  	pd.0				
	call 	time_60min
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
time_set:
	clr 	sl_idle
	clr	main_01
	clr   tmrc.4
	mmov	tmr,			06h
	set	tmrc.4
	set  	pac.5
	snz  	pa.3						;if pa.3=0 enter check_mode1, 
	call 	check_mode1
	sz   	pa.3						;if pa.3=1 enter check_mode2
	call 	check_mode2
ret
;***************************************

intc_inform:
	clr 	tmrc.4
	mmov 	tmr,			06h		;timer is 8ms
	set 	tmrc.4
	mmov	timer_in,	0fah
	nop
	nop
	clr 	pac.5
	set 	pa.5
delay1:
	clr 	status.2
	mov 	a, 			0fah
	and 	a, 			timer_in		;if timer_in=0 so result is 0
	snz 	status.2					;if result=0 so status.2=1
	jmp 	delay1					;1 times loop is 2s
	mmov 	timer_in, 	0fah	
	clr 	status.2
	dec 	delay_4s					;delays is 2
	snz 	status.2					;2X2=4s 
	mmov 	delay_4s,  	02h
	set 	pac.5
	clr 	pa.5 
	clr	intc_out
ret
;***************************************
;photosensitive diode
ptled_sleep:
	sz		pa.0
	clr	on_01
	snz	pb.3
	call 	sleep_mode				;if pb3=0 enter sleep_mode
ret
;***************************************
; open pvi
open:	
	sz 	on_off_bit				;if on_off_bit = 0, so open pvi
	jmp 	over						;if on_off_bit = 1, so do nothing
	set 	pa.2
	set 	pa.1
	mmov 	on_off_bit, 	01h	;open after set on_off_bit
	mmov 	on_01, 			01h	;if first on power, so on_01=1
over:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; infom main_cpu will shut down
inform:
	set  	pa.6						;inform to mian_cpu save register
shut_loop:
	snz   pa.7						;if pa7=1	shut_down 
	jmp  	shut_loop
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; shutdown pvi
shut_down:
	sz		sl_idle
	call 	inform					;before shut_down, inform main_cpu to save status
	clr 	pa.1
	clr 	pa.2
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; if POWERCK is pushed, and holding_timer > 200ms, to justify
long_push:
	sz  	pa.0						;pa.0 = 0, indicat switch_key did pushed
ret
	clr	tmrc.4
	mmov	tmr,			06h
	set	tmrc.4
	mmov 	timer_in,	046h
loop:									; 560ms timer_delay
	sz		timer_in
	jmp 	loop
	snz  	pa.0						;powerck push_holding >256ms						
	sz 	on_01						;if on_01 = 1, indicate key don't undo on last times, so not check open_down function
	jmp 	next1						;if on_01 = 0, call open_down function
	sz 	on_off_bit				;if on_off_bit = 1, call shut_down
	call 	shut_down
	call 	open
next1:
ret
;***************************************
main: 
	call 	initial
main_loop:
	mmov	sl_idle,		01h
	mmov 	main_01, 	01h
	call 	long_push				; long_time push_key run pvi
	snz  	pa.0						;pa.0 = 0 , not undo key
	jmp 	next2
	clr	on_01
next2:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;enter sleep_mode mode check
	call 	ptled_sleep
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; power check
	clr	check_end
	sz	 	on_off_bit				;only run status, check battery's power
	call 	check_delay				;5s check 1 time
	sz   	check_01					;if check_01 = 1, check power of battery
	call 	adpro						
	clr	status.2
	mov 	a, 			03h		;if three times low power , so shut down
	sub 	a, 			check_times
	sz 	status.2
	call 	shut_down
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; timing check
	mmov 	timer_in, 0fah
	sz   	pa.7						;if pa7=1 check time_mode
	call 	time_set
;;;;;;;;;;;;;;;;
	sz  	intc_out
	call 	Intc_Inform
jmp main_loop
;*************************************************
;*************************************************
end

⌨️ 快捷键说明

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