📄 90clock2.asm
字号:
; Pc.4--cs
; Pc.3--clk
; Pc.2--data
; Pc.1--key
.macro setcs
sbi portc, cs
.endm
.macro datainput
cbi ddrc, data
.endm
.macro dataoutput
sbi ddrc, data
.endm
.include"d:\wu\8515def.inc"
.org 0x0000
rjmp reset
.def temp =r16
.def temp1 =r17
.def temp2 =r18
.def send_buf=r19
.def rec_buf =r20
.def cnt =r21
.def delayr =r22
.def myflag =r23 ;bit0:keyup? bit1:keypress?
.def ledcnt =r24
.def hour =r25
.def minute =r26
.def second =r27
.def timercnt=r28
.equ cs = 4
.equ clk = 3
.equ data= 2
.equ key = 1
.org 0x007
rjmp timer0
timer0:
ldi temp,104
bu: ;因25ms内差40us故补上40/(1/8)即320个CK。
dec temp ;因中断需4CK这样:4+104*(1+2)+1+1+1+1=320
brne bu
ldi temp, 256-195 ;计数(256-195)次才产生1次中断。
out tcnt0, temp ;CK/1024分频,这样一次中断需25ms。
rcall distime ;显示时间
reti
reset:
ldi temp, high(ramend) ;设置堆栈指针。
out sph, temp
ldi temp, low(ramend)
out spl, temp
clr myflag ;清工作寄存器。
clr hour
clr minute
clr second
clr send_buf
clr rec_buf
ldi timercnt,0
ldi ledcnt, 0xcf
ldi temp, $fd
out ddrc, temp
ldi temp, $f7
out portc, temp
main:
ldi send_buf,$a4 ;清屏
rcall send
setcs
ldi temp, 0
ldi temp1, 8
ldi zh, 0
ldi zl, 0x60
mnext:
st z+, temp ;清显存
dec temp1
brne mnext
ldi delayr, 4
ldi send_buf,0xc8 ;显00-00-00
rcall send
ldi send_buf,0
rcall send
setcs
rcall delay
ldi send_buf,0xc9
rcall send
ldi send_buf,0
rcall send
setcs
rcall delay
ldi send_buf,0x92
rcall send
ldi send_buf,0x01
rcall send
setcs
rcall delay
ldi send_buf,0xcb
rcall send
ldi send_buf,0
rcall send
setcs
rcall delay
ldi send_buf,0xcc
rcall send
ldi send_buf,0
rcall send
setcs
rcall delay
ldi send_buf,0x95
rcall send
ldi send_buf,0x01
rcall send
setcs
rcall delay
ldi send_buf,0xce
rcall send
ldi send_buf,0
rcall send
setcs
rcall delay
ldi send_buf,0xcf
rcall send
ldi send_buf,0
rcall send
setcs
ldi zh, 0
ldi zl, 0x60
loop:
rcall display
rcall keyscan
sbrs myflag, 2 ;是否按下执行键?
rjmp loop
excute:
rcall timerinit
sei
in r0,mcucr
ldi temp,$20
OR r0,temp
out mcucr,r0
clr temp1
gosleep:
sleep ;进入休眠状态
rjmp gosleep
send: ;发送子程序
ldi cnt, 8
cbi portc, cs
ldi delayr, 150 ;delay 50us
rcall delay
; cbi portc, clk
ldi delayr, 20 ;delay 10us
send1:
lsl send_buf
brcs sset1
sset0:
cbi portc, data
rjmp snext1
sset1:
sbi portc, data
snext1:
nop
nop
sbi portc, clk
rcall delay
nop
nop
cbi portc, clk
rcall delay
dec cnt
brne send1
cbi portc, data
ret
receive: ;接受子程序
ldi cnt, 8
datainput
ldi delayr, 150 ;delay 50us
rcall delay
ldi delayr, 20 ;delay 10us
receive1:
sbi portc, clk
rcall delay
sbis pinc, data
rjmp rset0
rjmp rset1
rset0:
clc
rjmp rnext
rset1:
sec
rnext:
rol rec_buf
cbi portc, clk
rcall delay
dec cnt
brne receive1
dataoutput
ret
display: ;显示子程序
sbrs myflag, 0
rjmp disexit
cpi ledcnt, 0xcd
breq diswww
cpi ledcnt, 0xca
breq diswww
rjmp diswwww
diswww:
dec ledcnt
diswwww:
mov send_buf,ledcnt
rcall send
mov send_buf,rec_buf
rcall send
setcs
dec ledcnt
cpi ledcnt, 0xc7
brne disww
ldi ledcnt, 0xcf
ldi zh, 0x00
ldi zl, 0x60
disww:
cbr myflag, 0x01
disexit:
ret
keyscan: ;键扫子程序
sbic pinc, key
rjmp keyexit
sbrc myflag, 1
rjmp keyexit1
ldi send_buf,0x15
rcall send
rcall receive
setcs
sbr myflag, 0x02
ret
keyexit:
sbrs myflag, 1
rjmp keygo1
sbr myflag, 0x01
cpi rec_buf,0x17
brne keygo
sbr myflag, 0x04
rjmp keygo1
keygo:
st z+, rec_buf
keygo1:
cbr myflag, 0x02
keyexit1:
ret
timerinit: ;定时初始化
ldi zh, 0x00
ldi zl, 0x66
rcall givetime
rcall judgedata
ldi temp, 256-195
out tcnt0, temp
ldi temp, 2
out timsk, temp
ldi temp, 5
out tccr0, temp
ret
givetime:
rcall bcdtoh
mov second, temp1
rcall bcdtoh
mov minute, temp1
rcall bcdtoh
mov hour, temp1
ret
bcdtoh: ;BCD转换二进制
ld temp1, -z
cpi temp1, 10
brlo bcdnext
rjmp reset
bcdnext:
ld temp, -z
bcd8_0:
subi temp, 1
brcs bcd8_1
subi temp1, -10
rjmp bcd8_0
bcd8_1:
ret
judgedata: ;判断输入是否正确
cpi hour, 24
brsh judreset
cpi minute, 60
brsh judreset
cpi second, 60
brsh judreset
rjmp judok
judreset:
rjmp reset ;不正确,重置
judok:
ret
distime: ;显示时间
inc timercnt ;cnt1计数40次为1秒钟。
cpi timercnt,40
brne distexit
clr timercnt
inc second
cpi second, 60
brne dissecond
clr second
inc minute
cpi minute, 60
brne disminute
clr minute
inc hour
cpi hour, 24
brne dishour
clr hour
dishour: ;显示小时
mov temp1, hour
rcall bintobcd
ldi temp, 0xce
rcall disres
disminute: ;显示分
mov temp1, minute
rcall bintobcd
ldi temp, 0xcb
rcall disres
dissecond: ;显示秒
mov temp1, second ;temp1:bin value
rcall bintobcd
ldi temp, 0xc8
rcall disres
distexit:
ret
bintobcd: ;二进制转BCD子程序
clr temp2 ;清高位
btobcd1:
subi temp1, 10
brcs btobcd2
inc temp2
;------------------------------------------------------------
; subi temp2, -0x10 ;代替上行作为压缩bcd输出
;------------------------------------------------------------
rjmp btobcd1
btobcd2:
subi temp1, -10
;------------------------------------------------------------
; add temp1, temp2 ;作为bcd输出,temp1为输出
;------------------------------------------------------------
ret
disres:
mov send_buf,temp
rcall send
mov send_buf,temp1
rcall send
setcs
ldi delayr, 2
rcall delay
inc temp
mov send_buf,temp
rcall send
mov send_buf,temp2
rcall send
setcs
ret
delay:
dec delayr
brne delay
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -