1. 求单片机程序:汇编语言数字钟
用DS1302+单片机比较简单 ;DS1302程序(51汇编)
;推荐
;1.每次上电,必须把秒寄存器高位(第7位)设置为0,时钟才能走时。
;2.如果需要写入数据和时钟日历信息,必须把“写保护”寄存器设置成为0
;内存数据定义
BitCnt data 3Ch ; 数据位计数器
ByteCnt data 3Dh ; 数据字节计数器
Command data 3Eh ; 命令字节地址
RcvDat DATA 40H ; 接收数据缓冲区
XmtDat DATA 50H ; 发送数据缓冲区
;端口位定义
IO_DATA bit P1.6 ; 数据传送总线
SCLK bit P1.5; 时钟控制总线
RST bit P1.7 ; 复位总线
RS BIT P3.5
RW BIT P3.6
EN BIT P3.7
ORG 0000H
ORG 0013H
LCALL JKS
AJMP KS
;**************************** ;main program
ORG 0030H
KS: CLR RST
MOV SP,#2AH
;----LCD初始化----
CLR EN ;使能端为0,液晶执行命令
INIT_LCD:
MOV A,#38H ;双列显示,字形5*7点阵
ACALL WCOM
ACALL DELAY1
MOV A,#38H ;双列显示,字形5*7点阵
ACALL WCOM
ACALL DELAY1
MOV A,#38H ;双列显示,字形5*7点阵
ACALL WCOM
ACALL DELAY1
MOV A,#0CH ;开显示,关光标
ACALL WCOM
ACALL DELAY1
MOV A,#01H ;清除 LCD 显示屏
ACALL WCOM
ACALL DELAY1
MOV A,#06H ;地址加1
ACALL WCOM
ACALL DELAY1
;------------------------------------初始化1302-------------------------
SET1302:
LCALL Write_Enable;写允许
LCALL Osc_Disable
LCALL Write_Multiplebyte;初始化1302,将我们要设定的数据写入
LCALL Read_Multiplebyte;将我们设定的数据读出来
LCALL Osc_Enable
START:
ACALL LCD
LCALL Read_Multiplebyte
AJMP START
;---------------------LCD显示-------------------------
LCD:
MOV A,#11001000B
LCALL WCOM
MOV A,#0;显示时间
MOV A,42H
LCALL SSH2
MOV A,#00111010B
LCALL WDATA
MOV A,41H
LCALL SSH2
MOV A,#00111010B
LCALL WDATA
MOV A,40H
LCALL SSH2
MOV A,#11000000B
LCALL WCOM
MOV A,#0;显示日期字符
MOV A,46H
LCALL SSH2
MOV A,#00101101B
LCALL WDATA
MOV A,44H
LCALL SSH2
MOV A,#00101101B
LCALL WDATA
MOV A,43H
LCALL SSH2
RET
SSH2:
MOV B,#16
DIV AB
MOV 58H,B
MOV 59H,A
MOV A,59H
MOV DPTR,#TAB
MOVC A,@A+DPTR
ACALL WDATA
MOV A,58H
MOV DPTR,#TAB
MOVC A,@A+DPTR
ACALL WDATA
RET
;-----------------------------------------------------
; 写指令、数据使能子程序
;-----------------------------------------------------
WCOM: ;写指令使能
ACALL DELAY0
MOV P0,A
CLR RS
CLR RW
CLR EN
CLR EN
CLR EN
SETB EN
RET
WDATA: ;写数据使能
ACALL DELAY0
MOV P0,A
SETB RS ;RS=H,RW=L,D0-D7=数据,E=高脉冲
CLR RW
CLR EN
CLR EN
CLR EN
SETB EN
RET
;****判忙音****
DELAY0:
MOV P0,#0FFH
CLR RS
SETB RW
CLR EN
NOP
SETB EN
JB P0.7,DELAY0
RET
TAB:DB 00110000B,00110001B,00110010B,00110011B
DB 00110100B,00110101B,00110110B,00110111B
DB 00111000B,00111001B
;********************************************************************************************
;发送数据程序
;名称:Send_Byte
;描述:发送ByteCnt 个字节给被控器DS1302
;命令字节地址在Command 中
;所发送数据的字节数在ByteCnt 中发送的数据在XmtDat 缓冲区中
;********************************************************************************************
Send_Byte:
CLR RST ;复位引脚为低电平所有数据传送终止
NOP
CLR SCLK; 清时钟总线
NOP
SETB RST ;复位引脚为高电平逻辑控制有效
NOP
MOV A,Command; 准备发送命令字节
MOV BitCnt,#08h ;传送位数为8
S_Byte0:
RRC A ;将最低位传送给进位位C
MOV IO_DATA,C ;位传送至数据总线
NOP
SETB SCLK ;时钟上升沿发送数据有效
NOP
CLR SCLK ;清时钟总线
DJNZ BitCnt,S_Byte0 ;位传送未完毕则继续
NOP
S_Byte1: ;准备发送数据
MOV A,@R0 ;传送数据过程与传送命令相同
MOV BitCnt,#08h
S_Byte2:
RRC A
MOV IO_DATA,C
NOP
SETB SCLK
NOP
CLR SCLK
DJNZ BitCnt,S_Byte2
INC R0 ;发送数据的内存地址加1
DJNZ ByteCnt,S_Byte1 ;字节传送未完毕则继续
NOP
CLR RST ;逻辑操作完毕清RST
RET
;***************************************************************************************
;接收数据程序;
;名称:Receive_Byte
;描述:从被控器DS1302 接收ByteCnt 个字节数据
;命令字节地址在Command 中
;所接收数据的字节数在ByteCnt 中接收的数据在RcvDat 缓冲区中
;***********************************************************************************
Receive_Byte:
CLR RST ;复位引脚为低电平所有数据传送终止
NOP
CLR SCLK ;清时钟总线
NOP
SETB RST ;复位引脚为高电平逻辑控制有效
MOV A,Command ;准备发送命令字节
MOV BitCnt,#08h ;传送位数为8
R_Byte0:
RRC A ;将最低位传送给进位位C
MOV IO_DATA,C ;位传送至数据总线
NOP
SETB SCLK ;时钟上升沿发送数据有效
NOP
CLR SCLK ;清时钟总线
DJNZ BitCnt,R_Byte0 ;位传送未完毕则继续
NOP
R_Byte1: ;准备接收数据
CLR A ;清类加器
CLR C ;清进位位C
MOV BitCnt,#08h ;接收位数为8
R_Byte2:
NOP
MOV C,IO_DATA ;数据总线上的数据传送给C
RRC A ;从最低位接收数据
SETB SCLK ;时钟总线置高
NOP
CLR SCLK ;时钟下降沿接收数据有效
DJNZ BitCnt,R_Byte2 ;位接收未完毕则继续
MOV @R1,A ;接收到的完整数据字节放入接收内存缓冲区
INC R1 ;接收数据的内存地址加1
DJNZ ByteCnt,R_Byte1 ;字节接收未完毕则继续
NOP
CLR RST ;逻辑操作完毕清RST
RET
;--写保护寄存器操作------------------------------------------
Write_Enable:
MOV Command,#8Eh ;命令字节为8E
MOV ByteCnt,#1 ;单字节传送模式
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat,#00h ;数据内容为0 写入允许
ACALL Send_Byte ;调用写入数据子程序
RET
;当写保护寄存器的最高位为1 时禁止数据写入寄存器---------------
Write_Disable:
MOV Command,#8Eh ;命令字节为8E
MOV ByteCnt,#1 ;单字节传送模式
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat,#80h ;数据内容为80h 禁止写入
ACALL Send_Byte ;调用写入数据子程序
RET ;返回调用本子程序处
;当把秒寄存器的第7 位时钟停止位设置为0 时起动时钟开始---------
Osc_Enable:
MOV Command,#80h ; 命令字节为80
MOV ByteCnt,#1 ; 单字节传送模式
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat,#00h ;数据内容为0 振荡器工作允许
ACALL Send_Byte ;调用写入数据子程序
RET ;返回调用本子程序处
;当把秒寄存器的第7 位时钟停止位设置为1 时时钟振荡器停止HT1380 进入低功耗方式---------------
Osc_Disable:
MOV Command,#80h ;命令字节为80
MOV ByteCnt,#1 ;单字节传送模式
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat,#80h ;数据内容为80h 振荡器停止
ACALL Send_Byte ;调用写入数据子程序
RET ;返回调用本子程序处
;写入00 年6 月21 日星期三13 时59 分59---------------------
Write_Multiplebyte:
MOV Command,#0BEh ;命令字节为BEh
MOV ByteCnt,#8 ;多字节写入模式此模块为8 个
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat,#59h ;秒单元内容为59h
MOV XmtDat+1,#59h ;分单元内容为59h
MOV XmtDat+2,#13h ;时单元内容为13h
MOV XmtDat+3,#21h ;日期单元内容为21h
MOV XmtDat+4,#06h ;月单元内容为06h
MOV XmtDat+5,#03h ;星期单元内容为03h
MOV XmtDat+6,#0 ;年单元内容为00h
MOV XmtDat+7,#0 ;写保护单元内容为00h
ACALL Send_Byte ;调用写入数据子程序
RET ;返回调用本子程序处
;读出寄存器0-7 的内容程序设置如下
Read_Multiplebyte:
MOV Command,#0BFh ;命令字节为BFh
MOV ByteCnt,#8 ;多字节读出模式此模块为8 个
MOV R1,#RcvDat ;数据地址覆给R1
ACALL Receive_Byte; 调用读出数据子程序
RET; 返回调用本子程序处
DELAY1: ;延时10MS
MOV 21H,#75
D2: MOV 22H,#100
DJNZ 22H,$
DJNZ 21H,D2
RET
;=============================================================================================
END