📄 time_m8.asm
字号:
;********************************************************************************
;* *
;* File : time_m8.asm *
;* Function : 实时时钟DS1302应用练习 *
;* Date : 2006-06-22 *
;* Version : 1.0 *
;* *
;* Author : 开关电源 hongtusy@163.com *
;* Company : 电子信息技术咨询网 http://www.itsn.cn *
;* *
;****************************描述与记事******************************************
;实验板的AVR程序,实时时钟DS1302的读写并用138驱动LED显示实验练习。
;接线定义:PC0-CLK时钟(SW5-1) PC1-I/O数据入/出(SW5-2) PC2-RET复位(SW5-3)
;PD是138的输入端(SW2-1~3)。使用口资源:PB/PC/PD口
;记事:本程序旨在对实验板杜邦线的使用介绍以及DS1302驱动的理解与演示,程序适合初学者使用。
;提示:第一次使用时需要打通写保护位,就是秒寄存器的最高位。然后可以修改或读取各个计数值。
; 对各个寄存器的操作可以是单字节操作,也可以多(必须是8)字节操作。
;具体电路可参照使用指南里的说明。
;使用器件:ATmega8 使用默认的片内RC振荡器,1MHz。
;开关位置:SW2-1~4,6合上为138的输入和数码管的电源。SW3-7,8为系统复位端。
;杜邦线:需要8+3=11根杜邦线。数码管数据端PB口,用8根杜邦线将PB口和SW1次端的插针连接(注意PB口的次序)
; 1302引脚端,用杜邦线将PC0,1,2口和SW5-0,1,2分别相连。
;功能:使用8数码管交替显示当前的时间-时,分,秒和日期-年,月,日。
;注意事项:第一次使用本程序需要首先给1302写时间初始值,即选中
;下面的“rcall wrcr ;写入时钟需要的值”句,以后在运行中就不需要选中了。
;并且主电源断开时时间有电池供电,以后如果不重新烧写数据的程序,读出的将是实时时间。
;********************************************************************************
.include "m8def.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 ddrb,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 ddrc,1 ;PC1暂时为输出
nop
cbi portc,2 ;ret=0
nop
cbi portc,0 ;clk=0
nop
sbi portc,2 ;ret=1
nop
ldi r18,0x8e ;写保护命令字节的地址,0b10001110
rcall wbyte ;写指令
ldi r18,0x00 ;解除写保护
rcall wbyte
cbi portc,2 ;ret=0
cbi portc,0 ;clk=0
sbi portc,2 ;ret=1
ldi r18,0b10010000 ;涓流充电寄存器地址
rcall wbyte ;写命令
ldi r18,0b10101010 ;充电使能TCS=1010,二极管=10(两个),电阻=10(4kOHM)
rcall wbyte ;写命令
cbi portc,2 ;ret=0
cbi portc,0 ;clk=0
sbi portc,2 ;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 portc,2 ;ret=0
ret
;---------------------多字节模式读出各个寄存器数据程序---------------------
rdcr: cbi portc,2 ;ret=0
nop
cbi portc,0 ;clk=0
nop
sbi portc,2 ;ret=1
sbi ddrc,1 ;PC1暂时为输出
ldi r18,0xbf ;多字节读命令
rcall wbyte ;写入命令
cbi ddrc,1 ;PC1暂时为输入
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 portc,2 ;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 portc,1 ;I/Oout=0,输出0
rjmp wb1 ;转移
b1: sbi portc,1 ;I/Oout=1,输出1
nop
wb1: sbi portc,0 ;clk=1
nop
nop
cbi portc,0 ;clk=0
dec r16 ;寄存器减1
cpi r16,0 ;与立即数0比较
brne wb0 ;不为0,继续发送下一位。
ret
;----------8位读出数据程序,读出的数据放在r18中----------------------
rbyte: ldi r16,0x08 ;一字节8位。
rb0: in r17,pinc ;读取端口PIND的数据
sbrc r17,1 ;指定位为0跳行
rjmp d1 ;否则肯定为1
d0: clc ;c=0
ror r18 ;带C循环右移,r18将放读出的数据
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -