
这个电子钟程序已经基本符合你的要求。希望能对你有用。
程序说明:
显示的时间格式为:12-00-00,既,时-分-秒
按键说明:P32为时调节。P33为分调节。P34为秒调节。这三个按键均是每按一次加一。
晶振说明:12MHZ
数码管说明:共阳数码管。共8个数码管。共用了两个4连共阳数码管。
其中,P0口为数码管的段选,P2口为数码管的位选。
本程序已通过实践验证!!!
汇编源程序如下:
SECOND EQU 30H
MINITE EQU 31H
HOUR EQU 32H
HOURK BIT P32
MINITEK BIT P33
SECONDK BIT P34
DISPBUF EQU 40H
DISPBIT EQU 48H
T2SCNTA EQU 49H
T2SCNTB EQU 4AH
TEMP EQU 4BH
ORG 00H
LJMP START
ORG 0BH
LJMP INT_T0
START:MOV SECOND,#00H
MOV MINITE,#00H
MOV HOUR,#12
MOV DISPBIT,#00H
MOV T2SCNTA,#00H
MOV T2SCNTB,#00H
MOV TEMP,#0FEH
LCALL DISP
MOV TMOD,#01H
MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
SETB TR0
SETB ET0
SETB EA
WT:JB SECONDK,NK1
LCALL DELY10MS
JB SECONDK,NK1
INC SECOND
MOV A,SECOND
CJNE A,#60,NS60
MOV SECOND,#00H
NS60:LCALL DISP
JNB SECONDK,$
NK1:JB MINITEK,NK2
LCALL DELY10MS
JB MINITEK,NK2
INC MINITE
MOV A,MINITE
CJNE A,#60,NM60
MOV MINITE,#00H
NM60:LCALL DISP
JNB MINITEK,$
NK2:JB HOURK,NK3
LCALL DELY10MS
JB HOURK,NK3
INC HOUR
MOV A,HOUR
CJNE A,#24,NH24
MOV HOUR,#00H
NH24:LCALL DISP
JNB HOURK,$
NK3:LJMP WT
DELY10MS:MOV R6,#10
D1:MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
DISP:MOV A,#DISPBUF
ADD A,#8
DEC A
MOV R1,A
MOV A,HOUR
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV @R1,A
DEC R1
MOV A,MINITE
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV@R1,A
DEC R1
MOV A,SECOND
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
RET
INT_T0:MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
MOV A,#DISPBUF
ADD A,DISPBIT
MOV R0,A
MOV A,@R0
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,DISPBIT
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P2,A
INC DISPBIT
MOV A,DISPBIT
CJNE A,#08H,KNA
MOV DISPBIT,#00H
KNA:INC T2SCNTA
MOV A,T2SCNTA
CJNE A,#100,DONE
MOV T2SCNTA,#00H
INC T2SCNTB
MOV A,T2SCNTB
CJNE A,#05H,DONE
MOV T2SCNTB,#00H
INC SECOND
MOV A,SECOND
CJNE A,#60,NEXT
MOV SECOND,#00H
INC MINITE
MOV A,MINITE
CJNE A,#60,NEXT
MOV MINITE,#00H
INC HOUR
MOV A,HOUR
CJNE A,#24,NEXT
MOV HOUR,#00H
NEXT:LCALL DISP
DONE:RETI
TABLE:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0BFH
TAB:DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FH
END
CD BIT P12;用于液晶
W BIT P36
R BIT P37
CE BIT P17
DATA1 EQU 43H;第一参数
DATA2 EQU 44H;第二参数
COM EQU 45H;命令寄存器
;
ORG 0000H
jmp MAIN
ORG 0100H
;
MAIN:
;;;;;;;;;;;;;;;;;;;液晶初始化;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV COM,#80H ;SET or 模式命令
LCALL WRITEDATA3
NOP
MOV DATA1,#00H ;SET TEXT HOME AREA ADDRESS 1000H
MOV DATA2,#10H
MOV COM,#40H
LCALL WRITEDATA
NOP
MOV DATA1,#1EH ;SET TEXT AREA ADDRESS 001EH
MOV DATA2,#00H
MOV COM,#41H
LCALL WRITEDATA
NOP
MOV DATA1,#00H ;SET GRAPHIC HOME AREA ADDRESS 2000H
MOV DATA2,#20H
MOV COM,#42H
LCALL WRITEDATA
NOP
MOV DATA1,#1EH ;SET GRAPHIC AREA ADDRESS 001EH
MOV DATA2,00H
MOV COM,#43H
LCALL WRITEDATA
NOP
MOV DATA1,#0FH ;SET OFFSET REGISTER 000FH
MOV DATA2,#00H
MOV COM,#22H
LCALL WRITEDATA
NOP
MOV DATA1,#00H ;SET ADDRESS POINTER 7C00H
MOV DATA2,#7CH
MOV COM,#24H
LCALL WRITEDATA
NOP
MOV COM,#9CH ;SET TEXT ON,GRAPHIC ON
LCALL WRITEDATA3
NOP
;
ORG 0000H;程序起始于地址0000H,(一般不这样用)
LJMP MAIN;跳到主程序MAIN
ORG 000BH;外部中断INT0程序的地址,此为规定的
LJMP INTT0;跳到外部中断INTT0程序
ORG 001BH;外部中断INT1程序的地址,此也为规定的
LJMP INTT1;跳到外部中断INTT1程序
ORG 0100H;主程序MAIN地址
MAIN: MOV SP,#60H;给堆栈指针SP附内部数据存储器地址60H
MOV 31H,#0;给31H地址内清零即(31H)=0
MOV 20H,#0FEH ;(20H)=11111110B
MOV 21H,#0FFH;(21H)=11111111B
MOV P1,20H;P1=11111110B
LCALL SHEZHI1;调用程序段SHEZHI1
MOV 20H,#0FDH;(20H)=11111101B
MOV P1,20H;P1=11111101B
MOV 40H,#10;(40H)=0AH
SETB EA;开总中断
SETB ET0;开定时中断T0
MOV TMOD,#11H;设置T0工作于定时方式1
MOV TH0,#3CH;定时初值设置高位
MOV TL0,#0B0H;定时初值设置低位
SETB TR0;允许T0中断
LL: LCALL KEY;调用KEY
LCALL KEYC;调用KEYC
SJMP LL;循环调用回LL
INTT0: PUSH ACC;将ACC值压栈
PUSH PSW;将PSW值继续压栈
SETB RS1;RS1位置1
SETB RS0;RS0位置1,即选中内部数据存储器组的3组
DJNZ 40H,DOWN;判断十次结束否?且计数值自减一,若没有够十次,则转入程序DOWN , 否则顺序执行
MOV 40H,#10;继续在(40H)存入计数值十
MOV R0,#41H;(R0)=41H
MOV A,@R0 ; 判秒是否到60
ADD A,#1;A中值加一
DA A;十进制调整
MOV @R0,A;再送回原单元
CLR C;清进位位
SUBB A,#60H;与60相减
JC DOWN;通过判断进位位看是否到60了,没到就去DOWN,到了就顺序执行
MOV @R0,#0;41H单元清零
INC R0;地址自加一
MOV A,@R0 ; 判分是否到60
ADD A,#1
DA A
MOV @R0,A
CLR C
SUBB A,#60H
JC DOWN
MOV @R0,#0
INC R0
MOV A,@R0 ; 判时是否到24
ADD A,#1
DA A
MOV @R0,A
CLR C
SUBB A,#24H
JC DOWN
MOV @R0,#0
INC R0
MOV A,@R0 ; 判日是否到指定天数
ADD A,#1
DA A
MOV @R0,A
INC R0
MOV A,@R0
MOV R4,A ;月份送R4,本月天数送R5
JNB ACC4,NEXT2
CLR C
SUBB A,#06H
NEXT2: MOV DPTR,#DAYTAB
DEC A
MOVC A,@A+DPTR
MOV R5,A
CJNE R4,#2,NEXT
JNB 08H,NEXT1
NEXT: INC R5
NEXT1: DEC R0
MOV A,R5
CLR C
SUBB A,@R0
JNC DOWN
MOV @R0,#1
INC R0
MOV A,@R0 ; 判月是否到13
ADD A,#1
DA A
MOV @R0,A
CLR C
SUBB A,#13H
JC DOWN
MOV @R0,#1
INC R0
MOV A,@R0 ; 判年低位是否到00
ADD A,#1
DA A
MOV @R0,A
INC R0
MOV A,@R0
ADDC A,#0
DA A
MOV @R0,A
DOWN: MOV A,#42H
CJNE A,4EH,DOWN2
MOV A,#43H
CJNE A,4FH,DOWN2
CLR 07H
DOWN2: JB 06H,DOWN4
DOWN4: CLR TR0
MOV A,#0B7H
ADD A,TL0
MOV TL0,A
MOV A,#3CH
ADDC A,TH0
MOV TH0,A
SETB TR0
POP PSW
POP ACC
RETI
DAYTAB: DB 31H,28H,31H,30H,31H,30H,31H,31H,30H,31H,30H,31H
STACK1 SEGMENT STACK
DW 200 DUP ()
STACK1 ENDS
DATA SEGMENT
SPACE DB 1000 DUP (' ')
PATTERN DB 6 DUP (' '),0C9H,26 DUP (0CDH),0BBH,6 DUP (' ')
DB 6 DUP (' '),0BAH,26 DUP (20H),0BAH,6 DUP (' ')
DB 6 DUP (' '),0C8H,26 DUP (0CDH),0BCH,6 DUP (' ')
DBUFFER DB 8 DUP (':'),12 DUP (' ')
DBUFFER1 DB 20 DUP (' ')
STR1 DB 0DH,0AH, 'PLEASE INPUT DATE(D) OR TIME(T) OR QUIT(Q): $'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK1
START: MOV AX,0001H ;设置显示方式为4025彩色文本方式
INT 10H
MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV BP,OFFSET SPACE
MOV DX,0B00H
MOV CX,1000
MOV BX,0040H
MOV AX,1300H
INT 10H
MOV BP,OFFSET PATTERN ;显示矩形条
MOV DX,0B00H
MOV CX,120
MOV BX,004EH
MOV AX,1301H
INT 10H
LEA DX,STR1 ;显示提示信息
MOV AH,9
INT 21H
MOV AH,1 ;从键盘输入单个字符
INT 21H
CMP AL,44H ;AL='D'?
JNE A
CALL DATE ;显示系统日期
A: CMP AL,54H ;AL='T'?
JNE B
CALL TIME ;显示系统时间
B: CMP AL,51H ;AL='Q'?
JNE START
MOV AH,4CH ;返回dos状态
INT 21H
DATE PROC NEAR ;显示日期子程序
dis:MOV AH,2AH ;取日期
INT 21H
MOV SI,0
MOV AX,CX
MOV BX,100
DIV BL
MOV BL,AH
CALL BCDASC1 ;日期数值转换成相应的ASCII码字符
MOV AL,BL
CALL BCDASC1
INC SI
MOV AL,DH
CALL BCDASC1
INC SI
MOV AL,DL
CALL BCDASC1
MOV BP,OFFSET DBUFFER1
MOV DX,0C0DH
MOV CX,20
MOV BX,004EH
MOV AX,1301H
INT 10H
MOV AH,02H ;设置光标位置
MOV DX,0300H
MOV BH,0
INT 10H
MOV BX,0018H
REPEA: MOV CX,0FFFFH ;延时
REPEAT:LOOP REPEAT
DEC BX
JNZ REPEA
MOV AH,01H ;读键盘缓冲区字符到AL寄存器
INT 16H
JE dis
JMP START
MOV AX,4C00H
INT 21H
RET
DATE ENDP
TIME PROC NEAR ;显示时间子程序
DISPLAY1:MOV SI,0
MOV BX,100
DIV BL
MOV AH,2CH ;取时间
INT 21H
MOV AL,CH
CALL BCDASC ;将时间数值转换成ASCII码字符
INC SI
MOV AL,CL
CALL BCDASC
INC SI
MOV AL,DH
CALL BCDASC
MOV BP,OFFSET DBUFFER
MOV DX,0C0DH
MOV CX,20
MOV BX,004EH
MOV AX,1301H
INT 10H
MOV AH,02H
MOV DX,0300H
MOV BH,0
INT 10H
MOV BX,0018H
RE: MOV CX,0FFFFH
REA: LOOP REA
DEC BX
JNZ RE
MOV AH,01H
INT 16H
JE DISPLAY1
JMP START
MOV AX,4C00H
INT 21H
RET
TIME ENDP
BCDASC PROC NEAR ;时间数值转换成ASCII码字符子程序
PUSH BX
CBW
MOV BL,10
DIV BL
ADD AL,'0'
MOV DBUFFER[SI],AL
INC SI
ADD AH,'0'
MOV DBUFFER[SI],AH
INC SI
POP BX
RET
BCDASC ENDP
BCDASC1 PROC NEAR ;日期数值转换成ASCII码字符子程序
PUSH BX
CBW
MOV BL,10
DIV BL
ADD AL,'0'
MOV DBUFFER1[SI],AL
INC SI
ADD AH,'0'
MOV DBUFFER1[SI],AH
INC SI
POP BX
RET
BCDASC1 ENDP
CODE ENDS
END START
cursor equ 45H
attrib equ 2fh
code segment
assume cs:code,ds:code
start:
jmp go
oldcur dw
OLD1C DW 2 DUP()
NEWINT1C:
PUSHF
CALL DWORD PTR CS:OLD1C
push ax
PUSH BX
PUSH CX
PUSH DX
XOR BH,BH
MOV AH,3
INT 10H
MOV CS:OLDCUR,DX
MOV AH,2
xor bh,bh
MOV DX,CURSOR
INT 10H
MOV AH,2 ;读取系统时钟
INT 1AH
PUSH DX
PUSH CX
POP BX
PUSH BX
CALL SHOWBYTE
CALL SHOWCOLON
POP BX
XCHG BH,BL
CALL SHOWBYTE
CALL SHOWCOLON
POP BX
CALL SHOWBYTE
MOV DX,CS:OLDCUR
MOV AH,2
XOR BH,BH
INT 10H
POP DX
POP CX
POP BX
POP AX
IRET
SHOWBYTE PROC NEAR
PUSH BX
MOV CL,4
MOV AL,BH
SHR AL,CL
ADD AL,30H
CALL SHOW
CALL CURMOVE
POP BX
MOV AL,BH
AND AL,0FH
ADD AL,30H
CALL SHOW
CALL CURMOVE
RET
SHOWBYTE ENDP
SHOWCOLON PROC NEAR
MOV AL,':'
CALL SHOW
CALL CURMOVE
RET
SHOWCOLON ENDP
CURMOVE PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,3
MOV BH,0
INT 10H
INC DL
MOV AH,2
INT 10H
POP DX
POP CX
POP BX
POP AX
RET
CURMOVE ENDP
SHOW PROC NEAR
PUSH AX
PUSH BX
PUSH CX
MOV AH,09H
MOV BX,attrib
MOV CX,1
INT 10H
POP CX
POP BX
POP AX
RET
SHOW ENDP
GO:
PUSH CS
POP DS
MOV AX,351CH ;取中断向量
INT 21H
MOV OLD1C,BX;保存原中断向量
MOV BX,ES
MOV OLD1C+2,BX
MOV DX,OFFSET NEWINT1C ;置新的中断向量
MOV AX,251CH
INT 21H
MOV DX,OFFSET GO
SUB DX,OFFSET START
MOV CL,4
SHR DX,CL
ADD DX,11H
MOV AX,3100H ;结束并驻留
INT 21H
CODE ENDS
END START
用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 P16 ; 数据传送总线
SCLK bit P15; 时钟控制总线
RST bit P17 ; 复位总线
RS BIT P35
RW BIT P36
EN BIT P37
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 ;双列显示,字形57点阵
ACALL WCOM
ACALL DELAY1
MOV A,#38H ;双列显示,字形57点阵
ACALL WCOM
ACALL DELAY1
MOV A,#38H ;双列显示,字形57点阵
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 P07,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
基于c8051f020单片机最小系统的实时时钟显示程序
c8051f020 FYD12864-0402B LCD显示,按键电子时钟//
#include <c8051f020h>
#include<lcdh>
#include <intrinsh>
#define uchar unsigned char
void lcd_ini();
void DISPInitial();
void ascii_change(void);
void delay();
void wri_add(uchar com);
void wri_dat(uchar com1);
void shan(void);
void disp();
void tkey(void);
void PORT_Init (void);
sbit cs=P1^7;
sbit sid=P1^6;
sbit sclk=P1^5;
bit flag=1;
uchar dat,count,f=1;//f测试哪个单元为当前闪烁状态
uchar data clock[3]={24,00,00};
uchar code clockname[10]={"北京时间:"};
uchar data num[6];
/主程序/
void main()
{
lcd_ini();
count=10;//机器周期为1us,每次定时50ms,此变量用来控制循环次数,在下面赋值为20,共定时1秒
TMOD=0x01;
TL0=0XB0;
TH0=0X3C;
EA=1;
ET0=1;
IT0=1;
EX0=1;
TR0=1;
while(1)
{
back:ascii_change();
disp();
delay();
if(flag==1)
goto back;
tkey();
shan();
delay();
}
}
/lcd初始化/
/void lcd_ini()
{
wri_add(0x30);
delay();
wri_add(0x0c);
delay();
wri_add(0x01);
delay();
wri_add(0x06);
delay();
}/
void PORT_Init (void)
{
XBR0 = 0x00; //不让他连上IO口
XBR1 = 0x14; //允许外部中断连在端口上
XBR2 = 0x40; // Enable crossbar and weak pull-ups
P0MDOUT |= 0x00; // enable TX0 as a push-pull output
// P1MDOUT |= 0x07; // enable P16 (LED) as push-pull output
P2MDOUT=0xfe; //为了驱动步进电机的控制线
//P3MDOUT = 0xFF;
P74OUT=0x00; //配置成漏极方式可以让LCD显示成功 ,我试了配置成推挽方式不能正常显示
}
/定时程序/
void timer1() interrupt 1 using 2
{
TL0=0XB0;
TH0=0X3C;
count--;
if(count==0)
{
count=10;
clock[2]++;//秒//
}
else
goto out;
if(clock[2]==60)
{
clock[2]=0;
clock[1]++;//分//
}
if(clock[1]==60)
{
clock[1]=0;
clock[0]++;
}
if(clock[0]==24)//时//
clock[0]=0;
out:_nop_();
}
/十位个位转换成ASCII码/
void ascii_change(void)
{
num[5]=clock[2]-(clock[2]/10)10+0x30;
num[4]=clock[2]/10+0x30;
num[3]=clock[1]-(clock[1]/10)10+0x30;
num[2]=clock[1]/10+0x30;
num[1]=clock[0]-(clock[0]/10)10+0x30;
num[0]=clock[0]/10+0x30;
}
/廷时程序/
void delay()
{
uchar i,j;
for (i=250;i>0;i--)
for (j=250;j>0;j--);
}
/Write address/
void wri_add(uchar com)
{
uchar i,j,k;
cs=0;
cs=1;
dat=0xf8;
for(i=1;i<=8;i++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com;
dat=dat&0xf0;
for(j=1;j<=8;j++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com;
dat=_cror_(dat,4);// 此为高低四位交换
dat=dat&0xf0;
for(k=1;k<=8;k++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
}
/Write data/
void wri_dat(uchar com1)
{
uchar i,j,k;
cs=0;
cs=1;
dat=0xfa;
for(i=1;i<=8;i++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com1;
dat=dat&0xf0;
for(j=1;j<=8;j++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com1;
dat=_cror_(dat,4);// 此为高低四位交换
dat=dat&0xf0;
for(k=1;k<=8;k++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
}
/display program/ //显示时间
void disp()
{
uchar i,k=0;
wri_add(0x80);
for (i=1;i<=9;i++)
wri_dat(clockname[i-1]);
wri_add(0x90);
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
}
/闪烁程序/
void shan(void)
{
uchar i,k=0;
wri_add(0x90);
if(f==1)
{
num[0]=' ';
num[1]=' ';
}
else
goto next;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
goto return1;
next: if(f==2)
{
num[2]=' ';
num[3]=' ';
}
else
goto next1;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
goto return1;
next1: if(f==3)
{
num[4]=' ';
num[5]=' ';
}
else
goto return1;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
return1:_nop_();
}
/外部中断/
void intr0() interrupt 0 using 2
{
flag=~flag;//判断是否闪烁位//
TR0=~TR0; //闪关定时否则开定时
f=1;
}
/按键程序/
void tkey(void)
{
uchar judcekey;
judcekey=P1&0x0f;
if(judcekey==0x0f)
goto return2;
/移位键/
if (judcekey==0x0e)
f++;
if (f==4)
f=1;
/加一键/
if(judcekey==0x0d)
{clock[f-1]++;}
if (f==1)
{ if (clock[f-1]==24){
clock[f-1]=0;}
}
else{ if (clock[f-1]==60)
clock[f-1]=0;
}
/减一键/
if(judcekey==0x0b)
{clock[f-1]--;}
if (f==1)
{ if (clock[f-1]==0xff){
clock[f-1]=23;}
}
else
{ if (clock[f-1]==0xff)
clock[f-1]=59;
}
return2:_nop_();
}
//本程序已经调试成功并能够正确执行
以上就是关于电子时钟程序(单片机汇编语言编写,不要C语言)全部的内容,包括:电子时钟程序(单片机汇编语言编写,不要C语言)、电子日历时钟程序设计(汇编语言)、单片机时钟和倒计时器的汇编语言代码,哪位大侠能给出每个语句的注释解释,感激不尽等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)