📄 实验板time.asm
字号:
;********************************************************************************
;* *
;* File : 实验板time.asm *
;* Function : 实时时钟DS1302应用练习 *
;* Date : 2006-06-22 *
;* Version : 1.0 *
;* *
;* Author : 开关电源 hongtusy@itsn.cn *
;* Company : 电子信息技术咨询网 http://www.itsn.cn *
;* *
;****************************描述与记事******************************************
;实验板的AVR程序,实时时钟DS1302的读写并用138驱动LED显示实验练习。
;接线定义:PA3-CLK时钟(SW5-1) PA4-I/O数据入/出(SW5-2) PA5-RET复位(SW5-3)
;数码管部分,PC为数据端(SW1-1~8),PD是138的输入端(SW2-1,2,3,6),SW3-8为系统复位端。
;记事:本程序旨在对DS1302驱动的理解与演示,程序适合初学者使用。
;提示:第一次使用时需要打通写保护位,就是秒寄存器的最高位。然后可以修改或读取各个计数值。
; 对各个寄存器的操作可以是单字节操作,也可以多(必须是8)字节操作。本示例是多字节操作。
;具体电路可参照使用指南里的说明。
;使用器件:ATMEGA8535,可更换。 使用默认的片内RC振荡器,1MHz。
;注意事项:第一次使用本程序需要首先给1302写时间初始值,即选中
;下面的“rcall wrcr ;写入时钟需要的值”句,以后在运行中就不需要选中了。
;并且主电源断开时时间有电池供电,以后如果不重新烧写数据的程序,读出的将是实时时间。
;********************************************************************************
.include "m8535def.inc" ;定义头文件。
.org 0x0000 ;指定开始地址。
rjmp reset ;转移到“RESET”句。
.org 0x10
reset: ldi r16,0x02 ;设置堆栈指针0x025f
out sph,r16
ldi r16,0x5f
out spl,r16
;---------------------------
ldi r16,0xff ;加载立即数,把立即数0XFF放到定义过的Temp中,作数据方向参数。
out ddrc,r16 ;PC口为输出,数码管的段码端
out ddra,r16 ;PA口为输出,PA5接时钟芯片的复位端,PA3/4是时钟和数据端
out ddrd,r16 ;PD口为输入/出,145的输入控制部分使用末4位
rcall datin ;装入初始数据
rcall wrcr ;写入时钟需要的值
;------------------年月日和时分秒交替显示-----------------------
star: ldi r19,0xf0
star1: rcall rdcr ;读数据
rcall moin1 ;数据分开,装入显存,时,分,秒
rcall display ;动态显示
rcall display
rcall display
dec r19 ;减1
cpi r19,0
brne star1
ldi r19,0x60
star2: rcall rdcr ;读数据
rcall moin2 ;数据分开,装入显存,年,月,日
rcall display ;动态显示
rcall display
rcall display
dec r19 ;减1
cpi r19,0
brne star2
rjmp star
;--------------------多字节模式写入各个寄存器数据程序------------------------
;-----每次上电后,自动处于写保护状态,必须先解除写保护,然后才能进行写操作。
;-----并且每次重新上电后,自动处于暂停状态,必须使秒寄存器的D7位为0,才能开始计时。
;-----方便起见,这里对年月日时分秒的数据写和读都采用了多字节读写的命令。一次操作8个寄存器。
;-----如果只操作一个的话,就先写相应的地址在读或写相应的数据操作即可。
;--这里的操作顺序是:解除写保护-->复位一次-->单字节对涓流充电的操作-->复位一次-->多字节写命令-->连续8个写入的数据。
;--刚上电时,充电器是被禁止的,我们把TCS改为1010后,启动充电。由于电源是5V,电池是3V,我们选择两个二极管和4k电阻。
wrcr: sbi ddra,4 ;PA4(dat)暂时为输出
nop
cbi porta,5 ;ret=0
nop
cbi porta,3 ;clk=0
nop
sbi porta,5 ;ret=1
nop
ldi r18,0x8e ;写保护命令字节的地址,0b10001110
rcall wbyte ;写指令
ldi r18,0x00 ;解除写保护
rcall wbyte
cbi porta,5 ;ret=0
cbi porta,3 ;clk=0
sbi porta,5 ;ret=1
ldi r18,0b10010000 ;涓流充电寄存器地址
rcall wbyte ;写命令
ldi r18,0b10101010 ;充电使能TCS=1010,二极管=10(两个),电阻=10(4kOHM)
rcall wbyte ;写命令
cbi porta,5 ;ret=0
cbi porta,3 ;clk=0
sbi porta,5 ;ret=1
ldi r18,0xbe ;多字节写命令,之后必须连续写8个字节数据,否则无效。
rcall wbyte ;写指令
ldi r18,0x00 ;00秒,这样保证了秒寄存器的D7位是0,从而启动计时了。
rcall wbyte
ldi r18,0x48 ;48分
rcall wbyte
ldi r18,0x13 ;13时,最高位TP为0,表示24小时制。
rcall wbyte
ldi r18,0x01 ;01日
rcall wbyte
ldi r18,0x10 ;10月 ;该位还有问题,月份不能大于等于10,不知道为什么
rcall wbyte
ldi r18,0x01 ;星期一
rcall wbyte
ldi r18,0x06 ;06年
rcall wbyte
ldi r18,0x00 ;写保护内容,允许写操作。
rcall wbyte
cbi porta,5 ;ret=0
ret
;---------------------多字节模式读出各个寄存器数据程序---------------------
rdcr: cbi porta,5 ;ret=0
nop
cbi porta,3 ;clk=0
nop
sbi porta,5 ;ret=1
sbi ddra,4 ;PA4暂时为输出
ldi r18,0xbf ;多字节读命令
rcall wbyte ;写入命令
cbi ddra,4 ;PA4暂时为输入
rcall rbyte ;读数据
mov r0,r18 ;秒
rcall rbyte
mov r1,r18 ;分
rcall rbyte
mov r2,r18 ;时
rcall rbyte
mov r3,r18 ;日
rcall rbyte
mov r4,r18 ;月
rcall rbyte
mov r5,r18 ;星期
rcall rbyte
mov r6,r18 ;年
rcall rbyte
mov r7,r18 ;写保护数据
cbi porta,5 ;ret=0
ret
;----------8位写入指令程序,数据需要事先放在r18中----------------------
wbyte: ldi r16,0x08 ;写入命令
wb0: ror r18 ;带C循环右移,r18放的是数据。
brbc 0,b0 ;若C为0跳转,输出0。
rjmp b1 ;否则肯定为1,输出1。
b0: cbi porta,4 ;I/Oout=0,输出0
rjmp wb1 ;转移
b1: sbi porta,4 ;I/Oout=1,输出1
nop
wb1: sbi porta,3 ;clk=1
nop
nop
cbi porta,3 ;clk=0
dec r16 ;寄存器减1
cpi r16,0 ;与立即数0比较
brne wb0 ;不为0,继续发送下一位。
ret
;----------8位读出数据程序,读出的数据放在r18中----------------------
rbyte: ldi r16,0x08 ;一字节8位。
rb0: in r17,pina ;读取端口PIND的数据
sbrc r17,4 ;指定位为0跳行
rjmp d1 ;否则肯定为1
d0: clc ;c=0
ror r18 ;带C循环右移,r18将放读出的数据
rjmp rb1 ;转移
d1: sec ;c=1
ror r18 ;带C循环右移,r18将放读出的数据
nop
rb1: sbi porta,3 ;clk=1
nop
nop
cbi porta,3 ;clk=0
dec r16 ;寄存器减1
cpi r16,0 ;与立即数0比较
brne rb0 ;不为0,继续发送下一位。
ret
;---------------------------------
;----数据分开,并分别装入相应的显示存储器中,时,分,秒-------------------
moin1: mov r16,r0 ;秒
cbr r16,0xf0
mov r27,r16
swap r0
mov r16,r0
cbr r16,0xf0
mov r26,r16
mov r16,r1 ;分
cbr r16,0xf0
mov r24,r16
swap r1
mov r16,r1
cbr r16,0xf0
mov r23,r16
mov r16,r2 ;时
cbr r16,0xf0
mov r21,r16
swap r2
mov r16,r2
cbr r16,0xf0
mov r20,r16
ldi r22,16 ;-
ldi r25,16 ;-
ret
;----数据分开,并分别装入相应的显示存储器中,年,月,日-------------------
moin2: mov r16,r3 ;日
cbr r16,0xf0
mov r27,r16
swap r3
mov r16,r3
cbr r16,0xf0
mov r26,r16
mov r16,r4 ;月
cbr r16,0xf0
mov r24,r16
swap r5
mov r16,r5
cbr r16,0xf0
mov r23,r16
;r5存的是星期值。
mov r16,r6 ;年
cbr r16,0xf0
mov r21,r16
swap r6
mov r16,r6
cbr r16,0xf0
mov r20,r16
ldi r22,17 ;_
ldi r25,17 ;_
ret
;----------r20-r29单元是显示存储区,只要把数据装入这些寄存器,调动态扫描程序就可以显示了。
datin: ldi r20,0 ;0
ldi r21,0 ;0
ldi r22,16 ;-
ldi r23,0 ;0
ldi r24,0 ;0
ldi r25,16 ;-
ldi r26,0 ;0
ldi r27,0 ;0
ret
;################led动态扫描显示子程序,使用前把显示数据装入显示存储器中###使用145############
;可显示的字符包括:0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、-、_、P、X、
display: ldi r16,0B10000000 ;作共阴的公共脚。
out portd,r16 ;位号,第1位。
mov r16,r20 ;数据1
rcall dxaa ;显示
;----------------------------
ldi r16,0B10010000
out portd,r16 ;位号,第2位。
mov r16,r21 ;数据2
rcall dxaa ;显示
;----------------------------
ldi r16,0B10100000
out portd,r16 ;位号,第3位。
mov r16,r22 ;数据3
rcall dxaa ;显示
;----------------------------
ldi r16,0B10110000
out portd,r16 ;位号,第4位。
mov r16,r23 ;数据4
rcall dxaa ;显示
;----------------------------
ldi r16,0B11000000
out portd,r16 ;位号,第5位。
mov r16,r24 ;数据5
rcall dxaa ;显示
;----------------------------
ldi r16,0B11010000
out portd,r16 ;位号,第6位。
mov r16,r25 ;数据6
rcall dxaa ;显示
;----------------------------
ldi r16,0B11100000
out portd,r16 ;位号,第7位。
mov r16,r26 ;数据7
rcall dxaa ;显示
;----------------------------
ldi r16,0B11110000
out portd,r16 ;位号,第8位。
mov r16,r27 ;数据8
rcall dxaa ;显示
;----------------------------
ret
;------取码/延迟/消隐多功能程序---------
dxaa: ldi zh, high(Table_1<<1); 初始化Z指针
ldi zl, low(Table_1<<1)
clc ;清进位标志
add r30,r16 ;r16放的是要显示的数据,处理低字节数据
clr r16 ;r16清0
adc r31,r16 ;处理高字节数据
lpm r16,z ;从程序存储器中装入Z指针(r31:r30)指向的常量
out portc,r16
rcall londel ;长延时
ser r16 ;消隐
out portc,r16
rcall del
ret
;------------------------
Table_1:
.db 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xBF,0xF7,0x8C,0xFF
;共阳 0 1 2 3 4 5 6 7 8 9 A b C d E F - _ P X
;***************************************************************************************************
;#################短延迟程序##################
del: ldi r16,0x1f ;使用内部1MHzRC震荡器
del1: dec r16
brne del1
nop
ret
;###################钳套的延迟程序################
londel: ldi r17,0x08
del2: rcall del
rcall del
dec r17
brne del2
ret
;##################end###############
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -