51单片机电子时钟汇编
时间: 2024-04-10 14:23:08 浏览: 28
以下是一个51单片机电子时钟的汇编程序,可以显示时分秒,有秒点闪烁,同时可以调整时间:
```assembly
; 51单片机电子时钟汇编程序
; 晶振12M,此程序仅有时钟功能,显示时分秒,有秒点闪烁
; 时钟可调,小时、分钟调整各一个键,只加不减
; 秒调整只是清零,用于精确校对秒
org 0h ; 程序从0地址开始执行
; 定义端口
sclk equ P1.0 ; 时钟信号
sda equ P1.1 ; 数据信号
; 定义变量
hour db 12 ; 小时
minute db 0 ; 分钟
second db 0 ; 秒
; 定义常量
delay_time equ 1 ; 延时时间
; 定义子程序
; 向DS1302写入一个字节
write_byte:
mov a, #08h ; 写入8位
mov c, sclk ; 时钟线置0
djnz a, $ ; 循环8次
ret ; 返回
; 从DS1302读取一个字节
read_byte:
mov a, #08h ; 读取8位
mov c, sclk ; 时钟线置0
djnz a, $ ; 循环8次
mov c, sda ; 读取数据
ret ; 返回
; 向DS1302写入一个字节
write_ds1302:
push psw ; 保存状态
push dpl ; 保存数据
push dph
clr c ; 清零进位标志
mov a, #08h ; 写入8位
mov dph, #0dh ; 地址为0dh
mov c, sclk ; 时钟线置0
djnz a, $ ; 循环8次
mov a, dpl ; 取出数据
mov dpl, #00h ; 数据地址为00h
djnz a, $ ; 循环8次
pop dph ; 恢复数据
pop dpl
pop psw ; 恢复状态
ret ; 返回
; 从DS1302读取一个字节
read_ds1302:
push psw ; 保存状态
push dph ; 保存地址
push dpl
clr c ; 清零进位标志
mov a, #08h ; 读取8位
mov dph, #0dh ; 地址为0dh
mov c, sclk ; 时钟线置0
djnz a, $ ; 循环8次
mov dpl, #00h ; 数据地址为00h
djnz a, $ ; 循环8次
mov a, #08h ; 读取8位
mov c, sclk ; 时钟线置0
djnz a, $ ; 循环8次
mov c, sda ; 读取数据
pop dpl ; 恢复地址
pop dph
pop psw ; 恢复状态
ret ; 返回
; 初始化DS1302
init_ds1302:
mov dpl, #0 ; 秒清零
call write_ds1302
mov dpl, #80h ; 关闭写保护
call write_ds1302
mov dpl, #8ch ; 打开时钟
call write_ds1302
mov dpl, #00h ; 分钟清零
call write_ds1302
mov dpl, #80h ; 关闭写保护
call write_ds1302
mov dpl, #90h ; 打开时钟
call write_ds1302
mov dpl, #00h ; 小时清零
call write_ds1302
mov dpl, #80h ; 关闭写保护
call write_ds1302
mov dpl, #80h ; 打开时钟
call write_ds1302
ret ; 返回
; 读取时间
read_time:
mov dpl, #00h ; 读取秒
call read_ds1302
mov second, a ; 保存秒
mov dpl, #01h ; 读取分
call read_ds1302
mov minute, a ; 保存分
mov dpl, #02h ; 读取时
call read_ds1302
mov hour, a ; 保存时
ret ; 返回
; 显示时间
display_time:
mov dpl, hour ; 显示小时
call display_digit
mov dpl, minute ; 显示分钟
call display_digit
mov dpl, second ; 显示秒
call display_digit
ret ; 返回
; 显示数字
display_digit:
push acc ; 保存寄存器
push dpl
push dph
mov a, dpl ; 取出数字
anl a, #0fh ; 取低4位
add a, #30h ; 转换为ASCII码
mov dph, #00h ; 数据地址为00h
mov dpl, a ; 存储数据
call write_ds1302 ; 写入数据
pop dph ; 恢复寄存器
pop dpl
pop acc
mov a, dpl ; 取出数字
swap a ; 交换高低4位
anl a, #0fh ; 取低4位
add a, #30h ; 转换为ASCII码
mov dph, #01h ; 数据地址为01h
mov dpl, a ; 存储数据
call write_ds1302 ; 写入数据
ret ; 返回
; 延时
delay:
push acc ; 保存寄存器
push dpl
push dph
mov dpl, #delay_time ; 设置延时时间
delay_loop:
mov dph, #0ffh ; 循环计数
delay_loop1:
djnz dph, delay_loop1 ; 循环
djnz dpl, delay_loop ; 循环
pop dph ; 恢复寄存器
pop dpl
pop acc
ret ; 返回
; 主程序
main:
call init_ds1302 ; 初始化DS1302
loop:
call read_time ; 读取时间
call display_time ; 显示时间
call delay ; 延时
cpl P2.0 ; 秒点闪烁
sjmp loop ; 循环
end ; 程序结束
```