一、硬件电路:
硬件电路原理图如下,这是我15年前设计的一个LED数码管电子表,它是由一片51单片机,3片ULN2803,一个7805集成稳压器、SD2001A时钟模块及8只9014npn三极管和8只8550pnp三极管,红外线接收头组成,51单片机完成读写时钟,接收红外遥控指令,驱动数码管显示等任务。由于要驱动2.3寸的数码管,单片机的驱动能力不足,采用了NPN,PNP三极管组成的位驱动,用ULN2803组成段驱动,可以驱动24个数码管,可以显示日、月、年、星期、安全生产天数等。 二、51汇编程序
;电子表程序(源文件dzbc512.asm)
YEAR EQU 20H ;年
MONTH EQU 21H ;月
DAY EQU 22H ;日
WEEK EQU 23H ;星期
HOUR EQU 24H ;小时3031
MINUTE EQU 25H ;分钟3233
SECOND EQU 26H ;秒3435
FLAG EQU 27H ;通用标志寄存器
;BIT0=1, ACK ERR
;BIT0=0,ACK OK
;BIT1=1,TEST MODE
;BIT1=0,NORMAL MODE
TIMETEMP EQU 28H ;时间数据缓存器
TIMETX EQU 52H ;时间数据发送寄存器
TIMERX EQU 51H ;时间数据接收寄存器
SDA EQU 0b1h ;IIC的SDA口线
SCL EQU 0b0h ;IIC的SCL口线
ORG 0000
AJMP L0
ORG 000BH
AJMP CT
ORG 001BH
RETI
ORG 0023H
AJMP SI
ORG 0030H
L0: ;初始化程序
MOV SP,#60H ;定义堆栈
CLR A ;开始初始化各寄存器
MOV IE,A ;关中断
MOV P1,A
MOV P2,A ;PORT1,PORT2置0
MOV TMOD,#91H ;定时器0为16位定时器,
MOV 8CH, #3CH
MOV 8AH, #0B0H
CLR FLAG
LCALL LONGDELAY ;延时300ms
LCALL LONGDELAY ;延时300ms
LCALL TIMESTATUS_INT12 ;24小时制
;-----------------------------------------------------------------
GET_TIME:
CLR ET0 ;关闭AT89C51的TIME0中断
LCALL READ_TIME ;读SD2000内的实时时钟数据
JNB SECOND.7,NO_TESTMODE
LCALL TIME_TESTMODE ;测试模式结束
; CLR SECOND.7 ;秒的最高位屏蔽为0
NO_TESTMODE:
MOV R2,#3 ;读预置数据时分秒到30-35H内存单元
MOV R0, #30H
MOV R1,#24H
L1: MOV A,@R1
SWAP A
ANL A,#0FH
MOV @R0,A
INC R0
MOV A,@R1
ANL A,#0FH
MOV @R0,A
INC R1
INC R0
DJNZ R2,L1
MOV A,WEEK ;星期数据
ANL A,#0FH
MOV 37H,A
MOV R2,#3 ;读预置数据年月日20H,21H,22H--42,43,44,45,46,47
MOV R0, #42H
MOV R1,#20H
L2: MOV A,@R1
SWAP A
ANL A,#0FH
MOV @R0,A
INC R0
MOV A,@R1
ANL A,#0FH
MOV @R0,A
INC R1
INC R0
DJNZ R2,L2
MOV A,#2 ;2003年表示成0003所以把2加上
MOV 40H,A
MOV R3, #30H
CLRA
MOV R7,A
MOV 29H, A
MOV 2AH,A
MOV 2BH,A
MOV 2CH, A
MOV 2DH, A
MOV 2EH, A
MOV 2FH,A
MOV 50H,#01H
SETB EA ;开AT89C51中断
SETB ET0 ;允许AT89C51的TIME0中断
SETB TR0 ;T0开始计数
DIS:MOV DPTR,#0700H ;显示子程序
MOV R2, #01H
MOV R1, #30H
DIS1:MOV A, @R1
MOVC A,@A+DPTR
; CPL A MOV B,A
MOV P0,A
MOV A, R1
MOV R4, A
MOV A, #08H
ADD A, R1
MOV R1, A
MOV A, @R1
MOVC A, @A+DPTR
; CPL A MOV B,A
MOV P2,A
MOV A, #08H
ADD A, R1
MOV R1, A
MOV A, @R1
MOVC A, @A+DPTR
; CPL A MOV B,A
MOV P3,A
MOV A, R4
MOV R1, A
MOV A, R2
MOV P1, A
ACALL DELAY
AJMP JPCL
AN: MOV A, #01H;置闪动标志
MOV R7, A
MOV A,2CH ;
XRL A,#0AH ;键值=“A”显示地址加1
JZ JIA
MOV A, 2CH
XRL A, #0BH;键值=“B”显示地址减1
JZ JIAN1
MOV A, 2CH
XRL A, #0CH;键值=“C”复位
JNZ BJ
AJMP L0
BJ:MOV A, 2CH
AJMP J5
SS: MOV A, R3
MOV R0, A
MOV A, b;2CH
MOV @R0, A
CLR A
MOV R7, A
AJMP J6;SHAN
JIA:MOV A, R3
XRL A, #47H
JZ QCHU
; MOV A,#01H ;置闪动标志
; MOV R7, A
MOV A,50H
JNZ SHAN
ACALL JIA1
INC R3
MOV 50H,#01H
QCHU: MOV A, R3
MOV R0, A
MOV 2CH, @R0
AJMP SHAN
JIAN1:MOV A, R3
XRL A, #30H
JZ QCHU1
; MOV A, #01H
; MOV R7, A
MOV A,50H
JNZ SHAN
ACALL JIAN
DEC R3
MOV 50H,#01H
QCHU1:MOV A, R3
MOV R0, A
MOV 2CH, @R0
SHAN: MOV A,R7 ;字符闪动用R7识别
SETB TR0
JNZ G
AJMP J5
G: MOV A, 2FH
CJNE A, #05H, J4
MOV A, R3
MOV R0, A
MOV A,#11H ;熄灭显示
MOV @R0, A
AJMP J5
J4: MOV A, R3
MOV R0, A
MOV A, 2CH
MOV @R0,A ;显示字符
J5: MOV A,R2 ;移位
RL A
MOV R2, A
INC R1
MOV A, R2
JB 0E0H, J6
AJMP DIS1
J6: AJMP DIS
ORG0200H ;定时器子程序
CT: MOV 8CH, #3CH
MOV 8AH, #0BEH
PUSH 0D0H
PUSH 0E0H
PUSH 82H
PUSH 83H
MOV A, 2FH
INC A
MOV 2FH, A
CJNE A, #0AH, DONE;1/10
MOV 2FH, #00H
MOV A,36H ;1秒
CPL A
MOV 36H,A
MOV A,35H ;1秒
INC A
MOV 35H, A
CJNE A, #0AH, DONE
MOV 35H, #00H
MOV A,34H ;10秒
INC A
MOV 34H, A
CJNE A, #06H, done
MOV 34H, #00H
MOV A,33H ;分
INC A
MOV 33H, A
CJNE A, #0AH,DONE
MOV 33H, #00H
MOV A,32H ;十分
INC A
MOV 32H, A
CJNE A, #06H, DONE
MOV 32H, #00H
MOV R0, #31H;时
ACALL GIA1
MOV R0, #30H;10时
MOV A, @R0
INC R0
SWAP A
ADD A, @R0
MOV 2DH, A
CJNE A, #24H, DONE
CLR A
MOV 30H, A
MOV 31H, A
QC:; CLR P3.0
DONE: NOP
POP 83H
POP 82H
POP 0E0H
POP 0D0H
RETI
X: MOV R0, #3BH
ACALL GIA1
MOV R0, #3FH
ACALL GIA1
MOV R0,#37H ;天
MOV A, @R0
INC A
MOV @R0, A
CJNE A, #09H, XQ
MOV A, #01H
MOV @R0, A
XQ: CJNE A, #07H, XQ1
INC A
MOV @R0, A
XQ1: nop
RHB:MOV R0, #47H
ACALL GIA1
MOV R0, #46H
MOV A, @R0
INC R0
SWAP A
ADD A, @R0
MOV 2BH, A
YHB:MOV R0, #44H
MOV A, @R0
INC R0
SWAP A
ADD A, @R0
MOV 2AH, A
CJNE A, #02H, XY
NHB:MOV R0,#42H
MOV A, @R0
INC R0
SWAP A
ADD A, @R0
MOV 0F0H, #04H
DIV AB
MOV A, 0F0H
JNZ PY
MOV A, 2BH
CJNE A, #30H, FH
AJMP QLFH
XY: MOV A, 2AH
CJNE A, #04H, XY1
AJMP 01E4H
XY1:CJNE A, #06H, XY2
AJMP XY4
XY2:CJNE A, #09H, XY3
AJMP XY4
XY3:CJNE A, #11H, DY
XY4:MOV A, 2BH
CJNE A, #31H, FH
AJMP QLFH
DY: MOV A, 2BH
CJNE A, #32H, FH
AJMP QLFH
PY: MOV A, 2BH
CJNE A, #29H, FH
QLFH:LJMP R
NOP
NOP
NOP
FH: LJMP SXI
JIAN: MOV A,R3
DEC R3
AJMP FHJ
JIAN2: MOV A,R3
XRL A,#44H
JNZ FHJ
DEC R3
DEC R3
DEC R3
DEC R3
FHJ: RET
JIA1: MOV A,R3
INC R3
AJMP JIA3
JIA2: MOV A,R3
XRL A,#3FH
JNZ JIA3
INC R3
INC R3
INC R3
INC R3
JIA3: RET
ORG 0330H
R: MOV A, #01H
MOV 47H, A
MOV A, #00H
MOV 46H, A
MOV R0, #45H
ACALL GIA1
MOV A, 2AH
CJNE A, #12H, FH1
MOV A, #01H
MOV 45H, A
MOV A, #00H
MOV 44H, A
NJ1:MOV A, 2AH
CJNE A, #12H, FH1
MOV A, 2BH
CJNE A, #32H, FH1
MOV R0, #43H
ACALL GIA1
FH1:LJMP DONE
ORG 0360H
SXI:MOV R0, #47H
MOV A, 2BH
MOV R4, A
ANL A, #0FH
MOV @R0, A
DEC R0
MOV A, R4
SWAP A
ANL A, #0FH
MOV @R0, A
LJMP DONE
ORG 0380H
DL: MOV R0, #30H
MOV A, @R0
INC R0
SWAP A
ADD A, @R0
MOV 2DH, A
MOV R0, #32H
MOV A, @R0
INC R0
SWAP A
ADD A, @R0
MOV 29H, A
MOV R4, #1BH
MOV DPTR, #0500H
MOV A, #00H
DL1:MOVC A, @A+DPTR
CJNE A, 2DH, DL2
INC DPTR
MOV A,#00H
MOVC A, @A+DPTR
CJNE A, 29H, DL3
AJMP DL4
DL2:INC DPTR
DL3:INC DPTR
MOV A, #00H
DJNZ R4, DL1
AJMP DL5
DL4:SETB P2.0
ACALL DELAY
DL5:RET
; 键盘扫描处理子程序
ORG0400H
JPCL: ORL P3,#08H ;因P3口复用,既作数码管的段选,又作遥控接收,
JP: JNB P3.3,YS2 ;为检测红外线接收头有无信号,必须使P3.3=1.
clr p3.3
AJMP J0 ;无信号输入转移
YS2: ANL P1,#00H ;否则关显示,位选信号为0
CLR A
MOV 48H, A
MOV R0,#48H ;遥控数据存储指针
MOV R6, #1EH
S0: MOV 8DH,#00H ;定时器1时间常数
MOV 8BH, #00H
S1: JB 0B3H,JP ;若50微秒内P3.3变高则返回,正常解码信号持续低电平应大于50微秒.
SETB TR1 ;是解码信号,准备启动定时器1(为高时启动),
S2: JNB 0B3H,S2 ;等待变高,如果是干扰信号,很快消失而变高.
S3: MOV A,TH1 ;如果高电平持续时间太长,则是干扰信号,超过FE,则返回.
XRL A,#0FEH
JZ J0
JB 0B3H,S3 ;等待再次变低.
CLR TR1 ;再次变低后,高脉冲宽度测量完毕,应关闭定时器.
MOV A,8DH ;读数据
JZ S4 ;译码
MOV A, #80H
ADD A, @R0
MOV @R0, A
S4: MOV A, @R0
RL A
MOV @R0, A
NOP
DJNZ R6, S0
MOV A, 48H
MOVC A, @A+DPTR
ANL A, #0FH
MOV 2CH, A
ACALL DELAY2
ACALL DELAY2
SETB TR0
SUBB A,#0AH
JNCS5 ;是功能键转移
MOV A,R3 ;是数字键写显示
MOV R0, A
MOV A, 2CH
MOV @R0, A
MOVR7,#00H ;清闪动标志
MOV 50H,#00H ;置确定标志,
AJMP DIS
S5: LJMP AN
NOP
JJ6: JNB 0B1H, JJ6
ACALL DELAY2
MOV A, R3
MOV R0, A
MOVC A, @A+DPTR
XRL A, @R0
JNZ J7
AJMP G1
J7: INC @R0
G1: CLR A
MOV R7, A
AJMP J00
J8: JNB 0B2H, J8
ACALL DELAY2
MOV A, R3
MOV R0, A
MOV A, @R0
XRL A, #00H
JNZ J9
AJMP G0
J9: DEC @R0
G0: CLR A
MOV R7, A
AJMP J00
J: JNB 0B4H, J
ACALL DELAY2
MOV A, #01H
MOV R7, A
MOV A, R3
XRL A, #48H
JNZ JJ4
MOV R3, #2FH
JJ4: INC R3
MOV A, R3
MOV R0, A
MOV 2CH, @R0
J00: ACALL DELAY2
J0: CLR TR1
SETB TR0
J01: LJMP SHAN
ORG0500H ;打铃时间
DB06,30H,06,00,06,15H,07,15H,07,40H,07,45H,08,30H,08,40H,09,25H
DB09,50H,10H,35H,10H,45H,11H,30H,12H,30H,13H,30H
DB13H,40H,13H,45H,14H,30H,14H,40H,15H,25H,16H,30H,17H,00H
DB18H,00,18H,45H,20H,20H,21H,00,21H,10H
ORG 0550H
DB00,08,05,04,00,00,00,04;p2
DB00,00,00,01,00,00,00,01;p0
DB01,09,09,08,00,07,01,06;p3
ORG 0600H
SIO: MOVA,#20H
MOV R0,#20H
MOV 89H,A
MOV 8DH,#0F3H
SETB 0BCH
SETB 0AFH
CLR 0ABH
SETB 8EH
SETB 0ACH
MOV A,#50H
MOV 98H,A
RET
SI: MOV DPTR,#0700H
CLR 98H
MOV A,99H
MOVC A,@A+DPTR
MOV R2,A
MOV A,R7
XRL A,#01H
JZ SI1
MOV A,R2
MOV @R0,A
MOV R7,#01H
AJMP SI2
SI1: MOVA,@R0
SWAP A
ADD A,R2
MOV @R0,A
INC R0
MOV R7,#00H
SI2: RETI
SO: CLR 99H
MOV A,99H
MOV @R0,A
RETI
ORG 0700H;数码管段编码
DB0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH
DB 8EH,0CEH,00
ORG 0712H
DELAY: MOV R5, #88H
DEL: NOP
DJNZ R5, DEL
RET
DELAY1: MOV R6, #10H
DELA: ACALL DELAY
DJNZ R6, DELA
RET
DELAY2: MOV R6, #0FFH
DE: ACALL DELAY
DJNZ R6,DE
RET
ORG 0730H
DB00,01,02,03,04,05,06,07,08,09,09,09,09,09,09,09,02,0AH,0BH,0CH,0DH,0EH,0FH,09
ORG 0748H
GIA1: MOV R1, #04H
GIA2: MOV A, @R0
GIA: INC A
MOV @R0, A
CJNE A, #0AH, GIA3
CLR A
MOV @R0, A
DEC R0
DJNZ R1, GIA2
GIA3: RET
ORG 0761H
DB02H,00H, 00H,00H, 06H,0EH,00H, 0AH,04H,00H,0DH,00H,08H,00H,00H,00H
DB01H,00H, 09H,0BH,05H,00H,00H,00H,03H,00H,0CH,00H,07H,0FH
ORG 07A0H
DB0AH,03H,00H,07H,09H,01H,0CH,05H,04H,0BH,08H,00H,02H,00H,06H,0DH
ORG 07B0H
DB00H,07H,0AH,03H,0CH,05H,09H,01H,08H,00H,04H,0BH,06H,0DH,02H,00H
ORG 07C0h
DD: MOV R2,#0FEH
MOV R1,#0FEH
CC: MOV A,R1
MOV P1,A
MOV P0,A
MOV P3,A
MOV A,R2
MOV P2,A
MOV R6,#50H
BB: MOV R5,#0FFH
AA:NOP
DJNZ R5,AA
DJNZ R6,BB
MOV A,R1
RL A
MOV R1,A
JB 0E0H,CC
MOV A,R2
RL A
MOV R2,A
JNB 0E0H,CC
RET
;读实时时钟实时数据寄存器子程序
;功能:从实时时钟读入当前时间数据 |
;入口:NONE
;出口:接收数据放在年、月、日、星期、时、分、秒各寄存器
;影响资源:A,R0,R3,TIMETX,TIMERX,YEAR,MONTH,DAY,WEEK,HOUR,MINUTE,SECOND |
READ_TIME:
RDTIME_LOOP:
LCALL IICSTART
JB FLAG.1,ERR_IICSTOP ;如SDA线被箝位为低电平则退出
MOV TIMETX,#65H ;发送读时钟数据命令
LCALL SENDH_L
JB FLAG.0,ERR_IICSTOP ;ACK信号不正常则退出.
MOV R0,#YEAR
MOV R3,#07H
RDTIME1:
LCALL RXL_H
MOV A,TIMERX
MOV @R0,A
INC R0
DJNZ R3,RDTIME2 ;读完一个字节数据后确认数据传输
JMP RDTIME3 ;若为最后一个字节数据则为NOACK
RDTIME2:
CALL ACK
JMP RDTIME1
RDTIME3:
CALL NOACK
LCALL IICSTOP
CLR HOUR.7 ;小时的最高位在24小时制时没有用,如果是12小时制请删掉此行.
RDTIME_RET:
RET
ERR_IICSTOP:
LCALL IICSTOP
RET
ACK: CLR TIMETEMP.1
LCALL BITOUT
RET
NOACK: SETB TIMETEMP.1
LCALL BITOUT
RET
;保存错误代码
;功能:保存MCU与IIC接口通信时的错误状态 |
;入口:TIMETEMP.0=ACK位缙? |
;出口:FLAG.0=错误代码 |
ACK_ERR:
JNB TIMETEMP.0,ACK_ERR_RET ;检查ACK信号是否正常
SETB FLAG.0 ;置ACK出错标志位
ACK_ERR_RET:
RET
;启用IIC总线
;功能:开启实时时钟的IIC总线
;入口:NONE 出口:NONE
;影响资源:NONE
IICSTART:
CLR FLAG.1
SETB SDA
SETB SCL
LCALL DELAY3
JB SDA,IIC_SDAHI
SETB FLAG.1
IIC_SDAHI:
CLR SDA
LCALL DELAY3
CLR SCL
LCALL DELAY3
RET
;关闭IIC总线
;功能:关闭实时时钟IIC总线
;入口:NONE 出口:NONE
;影响资源:NONE
IICSTOP:CLR SDA
SETB SCL
LCALL DELAY3
SETB SDA
LCALL DELAY3
RET
;短延时子程序
;功能:延时 入口:NONE 出口:NONE
;影响资源:R7,PSW
DELAY3: MOV R7,#05H ;此延时至少10us,
DELAY5: NOP
DJNZ R7,DELAY5
RET
LONGDELAY: ;DELAY 300MS
MOV R6,#240
LD0: MOV R7,#250 ;5*250*240
LD1: NOP
NOP
NOP
DJNZ R7,LD1
DJNZ R6,LD0
RET
;发送一个字节,由高位到低位发送
;功能:从MCU发送一个字节给实时时钟,由高位到低位发送
;入口:发送数据放在TIMETX 出口:NONE
;影响资源:A,R2,TIMETX
SENDH_L:MOV A,TIMETX
MOV R2,#08H
CLR FLAG.0
SENDH_L1:
MOV C,ACC.7
MOV TIMETEMP.1,C
LCALL BITOUT
RL A
DJNZ R2,SENDH_L1
LCALL BITIN
LCALL ACK_ERR
RET
;发送一个字节,由低位到高位发送
;功能:从MCU发送一个字节给实时时钟,由低位到高位发送
;入口:发送数据放在TIMETX 出口:NONE
;影响资源:A,R2,TIMETX
SENDL_H:MOV A,TIMETX
MOV R2,#08H
CLR FLAG.0
SENDL_H1:
MOV C,ACC.0
MOV TIMETEMP.1,C
LCALL BITOUT
RR A
DJNZ R2,SENDL_H1
LCALL BITIN
LCALL ACK_ERR
RET
;接收一个字节
;功能:MCU从IIC总线接收一个字节,MSB在前,LSB在后
;入口:NONE 出口:接收数据放在RXBUF中
;影响资源:A,R2,TIMEBIT,RXBUF
RXH_L: MOV R2,#08H
RXH_L1:LCALL BITIN
MOV C,TIMETEMP.0
MOV ACC.7,C
RLC A
DJNZ R2,RXH_L1
MOV TIMERX,A
RET
;接收一个字节
;功能:MCU从IIC总线接收一个字节,LSB在前,MSB在后
;入口:NONE 出口:接收数据放在RXBUF中
;影响资源:A,R2,TIMEBIT,RXBUF
RXL_H: MOV R2,#08H
RXL_H1:LCALL BITIN
MOV C,TIMETEMP.0
RRC A
DJNZ R2,RXL_H1
MOV TIMERX,A
RET
;送出一位数
;功能:从MCU发送一位数给实时时钟
;入口:发送位数放在EEPREM.1 出口:NONE
;影响资源:A,TIMETEMP
BITOUT:
MOV C,TIMETEMP.1
MOV SDA,C
LCALL DELAY3
SETB SCL
LCALL DELAY3
CLR SCL
LCALL DELAY3
RET
;读入一位数
;功能:MCU从实时时钟接收一位数
;入口:NONE 出口:接收位数放在TIMETEMP.0
;影响资源:A,TIMETEMP
BITIN:
SETB SDA
SETB SCL
LCALL DELAY3
MOV C,SDA
MOV TIMETEMP.0,C
CLR SCL
CLR SDA
LCALL DELAY3
RET
ORG 0900H
;状态异常处理程序
;功能:在干扰严重的情况下,时钟进入异常状态的处理
;入口:NONE 出口:NONE
;影响资源: A,TIMETX
TIME_TESTMODE:
TIME_TESTMODE_LOOP:
LCALL IICSTART
JNB FLAG.1,TIME_TESTMODE_1
LJMP ERR_IICSTOP ;SDA线被箝位为低电平则退出
TIME_TESTMODE_1:
MOV TIMETX,#6EH ;发送测试模式结束命令,#6EH
LCALL SENDH_L
LCALL IICSTOP ;
JB FLAG.0,TIME_TESTMODE_LOOP;ACK信号不正常则重写.
;
RET
;写状态寄存器程序
;功能:读/写实时时钟状态寄存器,对其进行设置
;入口:NONE 出口:NONE
;影响资源: A,TIMETX
TIMESTATUS_INT12:
LCALL IICSTART
JNB FLAG.1,TIME_SETMODE_1
LJMP ERR_IICSTOP ;SDA线被箝位为低电平则退出
TIME_SETMODE_1:
MOV TIMETX,#62H ;发送写时钟状态寄存器命令
LCALL SENDH_L
JNB FLAG.0,TIME_SETMODE_2
LJMP ERR_IICSTOP ;ACK信号不正常则退出?
TIME_SETMODE_2:
MOV TIMETX,#40H ;24小时进制,
LCALL SENDL_H ;关闭/INT1及/INT2脚的输出
LCALL IICSTOP ;
RET
END
|