📄 battery_check.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 + -