本人做了个时钟,单片机显示在时钟跳转到日期时出现乱码,各位大虾帮忙,小弟不胜感激
[复制链接]
各位大虾,帮小弟找找错误,这是我的一个单片机程序,做的是一个时钟,用的ATMEL89C51单片机,显示在数码管7SEG-MPX8-CC-BLUE数码管上,但是在日期和时钟跳转时会出现乱码,而单独运行不会,其中P3口作为数码管的位选,P0作为时钟输出,P2作为日期输出,各位大虾请抽出点时间帮我看看,本人不胜感激!!!!
这是源代码:
//////////////////伪指令,类似于宏定义一下
S_SET BIT P1.1 ;秒设置
M_SET BIT P1.2 ;分设置
H_SET BIT P1.3 ;时设置
D_SET BIT P1.4 ;天设置
MON_SET BIT P1.5 ;月设置
Y_SET BIT P1.6 ;年设置
SELE BIT P1.0 ;日期与时钟转换开关,高电平时钟,低电平日期
///////////内容存储地址
SECOND EQU 30H
MINUTE EQU 31H
HOUR EQU 32H
SYMBOL EQU 34H ;中断1s标志
DAY EQU 35H
MONTH EQU 36H
YAER EQU 37H
/////////////////程序段说明伪指令
ORG 00H
SJMP START
ORG 0BH ;中断入口
LJMP INT_T0
//////////////////////始循环
START:
MOV DPTR,#TABLE ;初始化
SETB SELE
MOV HOUR,#23
MOV MINUTE,#59
MOV SECOND,#45
MOV DAY,#15
MOV MONTH,#06H
MOV YAER,#10
MOV SYMBOL,#00
MOV TMOD,#01H ;定时模式,16位计数器
MOV TH0,#(65536-50000)/256 ;T0定时50MS
MOV TL0,#(65536-50000)MOD 256
MOV IE,#82H ;中断设置,开中断允许,开定时器T0中断允许
SETB TR0
/////////////////////////////////////显示循环
RELOOP1:
LCALL DISPLAY
JNB S_SET,S1 ;是否有要设置的,如果有,进入设置
JNB M_SET,S2
JNB H_SET,S3
JNB D_SET,S4
JNB MON_SET,S5
JNB Y_SET,S6
LJMP RELOOP1 ;没有,再次进入循环RELOOP1
///////////////秒钟设置
S1:
LCALL DELAY
JB S_SET,RELOOP1 ;S_SET为1时,返回到显示循环
INC SECOND
MOV A,SECOND
CJNE A,#60,UP0 ;秒钟与60比较,相等,顺序执行,否则,转UP0
MOV SECOND,#0 ;置0
LJMP K1 ;跳转到K1,将分加1
///////////////////////////////
S2:
LCALL DELAY
JB M_SET,RELOOP1 ;M_SET为1时,返回到显示循环
///////////////////////////分钟设置
K1: INC MINUTE ;由于秒钟到了59转60,因此分钟加1
MOV A,MINUTE
CJNE A,#60,UP1 ;分钟与24比较,相等,顺序执行,否则,转UP1
MOV MINUTE,#0 ;置0
LJMP K2 ;跳转到K2,将时加1
///////////////////////////////
S3:
LCALL DELAY
JB H_SET,RELOOP1 ;H_SET为1时,返回到显示循环
////////////////////////////////
K2:
INC HOUR ;由于分钟到了59转60,因此时钟加1
MOV A,HOUR
CJNE A,#24,UP2 ;时钟与24比较,相等,顺序执行,否则,转UP2
MOV HOUR,#0 ;时钟置0
MOV MINUTE,#0 ;分钟置0
MOV SECOND,#0 ;秒钟置0
LJMP K3 ;跳转到K3,将天加1
/////////////////////////////////////
S4:
LCALL DELAY
JB D_SET,RELOOP
////////////////////////////
K3:
INC DAY
MOV A,DAY
CJNE A,#31,UP3 ;天与30比较,相等,顺序执行,否则,转UP3
MOV DAY,#0
LJMP K4
////////////////////////////////
S5:
LCALL DELAY
JB MON_SET,RELOOP
/////////////////////////////////
K4:
INC MONTH
MOV A,MONTH
CJNE A,#13,UP4 ;月与12比较,相等,顺序执行,否则,转UP4
MOV MONTH,#0
LJMP K5
////////////////////////////////
S6:
LCALL DELAY
JB Y_SET,RELOOP
/////////////////////////////
K5:
INC YAER
MOV A,YAER
CJNE A,#99,UP5
MOV YAER,#0
MOV MONTH,#0
MOV DAY,#0
LJMP RELOOP
////////////////////////////
RELOOP:
LJMP RELOOP1
///////////////////////////UP1--UP6为扫描设置端口,当恢复高电位时,返回主循环
UP0:
JB S_SET,RELOOP ;等待返回显示循环
LCALL DISPLAY
SJMP UP0
/////////////////////////
UP1:
JB M_SET,RELOOP ;等待返回显示循环
LCALL DISPLAY
SJMP UP1
////////////////
UP2:
JB H_SET,RELOOP ;等待返回显示循环
LCALL DISPLAY
SJMP UP2
//////////////////////////
UP3:
JB D_SET,RELOOP ;等待返回显示循环
LCALL DISPLAY
SJMP UP3
///////////////////////////
UP4:
JB MON_SET,RELOOP ;等待返回显示循环
LCALL DISPLAY
SJMP UP4
/////////////////////////
UP5:
JB Y_SET,RELOOP ;等待返回显示循环
LCALL DISPLAY
SJMP UP5
///////////////////////////////////
///////////////////////////////////T0中断服务程序,主要实现是秒钟加1计时以及进位问题
INT_T0:
MOV TH0,#(65536-50000)/256 ;装定时器定时器
MOV TL0,#(65536-50000)MOD 256
INC SYMBOL
MOV A,SYMBOL ;标记给ACC
CJNE A,#20,RETURN ;A等于20时,此时程序运行时间为1s,程序继续进行,否则中断返回
INC SECOND ;秒钟加1
MOV SYMBOL,#0
MOV A,SECOND
CJNE A,#60,RETURN ;秒钟与60相比较,相等继续执行,否则中断返回
INC MINUTE
MOV SECOND,#0 ;秒钟进位后置0
MOV A,MINUTE
CJNE A,#60,RETURN ;分钟与60相比较,相等继续执行,否则中断返回
INC HOUR
MOV MINUTE,#0 ;分钟进位后置0
MOV A,HOUR
CJNE A,#24,RETURN ;时钟与24相比较,相等继续执行,否则中断返回
MOV HOUR,#0 ;新的一天,全部清0
MOV MINUTE,#0
MOV SECOND,#0
MOV SYMBOL,#0
INC DAY ;新的一天到来,天数加1
MOV A,DAY
CJNE A,#30,RETURN ;天数与30相比较,相等继续执行,否则中断返回
INC MONTH
MOV DAY,#0
MOV A,MONTH
CJNE A,#12,RETURN
INC YAER
MOV MONTH,#0
MOV A,YAER
CJNE A,#99,RETURN
MOV YAER,#0 ;到一百年了,年月日以及标志全部清0
MOV MONTH,#0
MOV DAY,#0
MOV SYMBOL,#0
/////////////////////////////中断返回
RETURN:
RETI
/////////////////////////////////
//////////////////////////时钟显示,数据从P0口输出
DISPLAY:
LCALL DELAY
JNB P1.0,SHIFT_DATE ;P1.0为0,跳转显示日期
MOV A,SECOND ;秒送ACC
MOV B,#10
DIV AB ;秒钟的十位送A,个位送B
CLR P3.6 ;P3.6置0,秒钟的高位位选通
MOVC A,@A+DPTR ;查表
MOV P0,A ;送秒的十位
LCALL DELAY
SETB P3.6 ;置1,秒钟高位关闭
MOV A,B ;个位给A
CLR P3.7 ;秒钟的低位选通
MOVC A,@A+DPTR
MOV P0,A ;送秒钟的个位
LCALL DELAY
SETB P3.7 ;置1,秒钟低位关闭
CLR P3.5 ;将第三位弄成一杠
MOV P0,#40H
LCALL DELAY
SETB P3.5
MOV A,MINUTE ;分钟显示,原理同秒钟
MOV B,#10
DIV AB
CLR P3.3
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.3
MOV A,B
CLR P3.4
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.4
CLR P3.2 ;将第六位弄成一杠
MOV P0,#40H
LCALL DELAY
SETB P3.2
MOV A,HOUR ;时钟显示,原理同秒钟
MOV B,#10
DIV AB
CLR P3.0
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.0
MOV A,B
CLR P3.1
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.1
RET ;子程序返回
///////////////
SHIFT_DATE:
MOV P2,#00H
AJMP DISPLAY1
////////////////////////////////////
/////////////////////////////日期显示,数据从P2口输出
DISPLAY1:
LCALL DELAY
JB P1.0,SHIFT_TIME ;P1.0为1,跳转显示时间
MOV A,DAY ;天显示,显示原理和位置同秒钟
MOV B,#10
DIV AB
CLR P3.6
MOVC A,@A+DPTR
MOV P2,A
LCALL DELAY
SETB P3.6
MOV A,B
CLR P3.7
MOVC A,@A+DPTR
MOV P2,A
LCALL DELAY
SETB P3.7
CLR P3.5 ;第三位置一杠
MOV P2,#40H
LCALL DELAY
SETB P3.5
MOV A,MONTH ;月显示,显示原理同分钟
MOV B,#10
DIV AB
CLR P3.3
MOVC A,@A+DPTR
MOV P2,A
LCALL DELAY
SETB P3.3
MOV A,B
CLR P3.4
MOVC A,@A+DPTR
MOV P2,A
LCALL DELAY
SETB P3.4
CLR P3.2 ;将第六位弄成一杠
MOV P2,#40H
LCALL DELAY
SETB P3.2
MOV A,YAER ;年显示,显示原理同时钟
MOV B,#10
DIV AB
CLR P3.0
MOVC A,@A+DPTR
MOV P2,A
LCALL DELAY
SETB P3.0
MOV A,B
CLR P3.1
MOVC A,@A+DPTR
MOV P2,A
LCALL DELAY
SETB P3.1
RET ;子程序返回
//////////////
SHIFT_TIME:
MOV P0,#00H
AJMP DISPLAY
////////////////////////////////
/////////////////////////延时5毫秒
DELAY:
MOV R6,#10
////////////////延时250*10*2us=5ms
D1: MOV R7,#250
DJNZ R7,$
DJNZ R6,D1
RET
///////////////////字符表,共阴
TABLE:
DB 3FH,06H,5BH,4FH,66H ,6DH,7DH,07H,7FH,6FH
///////////////////////结束
END