
小问题还是挺多的。
首先,像楼上说的,P0送显示数据前应该关一下显示。考虑到你是共阳显示,mov P1,#0才对。像这样
mov P1, #0 // 关显示。
mov P0, 显示数据
mov P1, 显示哪一位。
acall delay // 延时一小段时间,调试的时候可以适当延时长一点。
djnz 。。。// 显示下一位。
关显示的位置应该在MOV P0,@R1之前。当然在delay后面也可以,但考虑到将来要改成使用定时中断,最好还是像上面这样做。
另外,这个程序应该先把中断全部关了调,不然肯定显示乱码。
数码管用8位一体的,共阴的。仿真图如下
程序如下
#include<reg51h>
#define uchar unsigned char
#define uint unsigned int
sbit k1=P3^1; //第一个按键,选择设置
uchar code distab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共阴数码管段码表
uchar disbuf[8]; //声明显示缓冲区8个单元
uchar hour=12; //声明小时变量,初值为12
uchar minute=59; //声明分变量,初值为59
uchar second; //声明秒变量
uchar t0n; //定时器T0中断计数,定时50ms,中断20次为1秒
uchar dis; //调时状态下,显示小数点位
void delay() //延时子程序,用于显示子程序
{
uint j;
for(j=300;j>0;j--);
}
//显示子程序,参数dis为显示小数点位
void display(uchar dis)
{
uchar j,disbit=0x01; //位码
for(j=0;j<8;j++)
{
P2=~disbit; //P2口输出位码
if(dis>0&&dis==j) //调时状态下,显示小数点
P0=distab[disbuf[j]]+0x80; //在小时,分,秒位上显示小数点
else
P0=distab[disbuf[j]]; //其它位正常显示
disbit<<=1; //取下一个位码
delay(); //延时
}
}
void main()
{
disbuf[2]=disbuf[5]=10;//数码管第3,6位显示-
TMOD=0x01;
TH0 =0x3C; //单片机晶振频率=12M,定时50ms,时间常数=3CB0
TL0 =0xB0;
IE =0x82; //开定时器T0中断
TR0 =1; //启动定时器T0
IT0 =1; //设置外部中断为下降沿有效
IT1 =1;
while(1)
{
display(dis); //调显示子程序
if(k1==0) //选择设置
{
dis++; //停止计时,进入调时状态
EX0=1; //调时状态下,允许外部INT0,INT1中断
EX1=1; //用来调小时,分,秒
if(dis>7) //调小时,在小时位显示小数点
{
dis=0; //灭小数点
t0n=0; //调时结束,开始计时
TR0=1;
EX0=0; //关外部中断
EX1=0;
}
else if(dis==2)dis=4; //调分,在分位显示小数点
else if(dis==5)dis=7; //调秒,在秒位显示小数点
while(k1==0)display(dis); //等待按键释放
}
if(t0n>=20&&dis==0) //中断20次,1秒到,计时状态下时钟计时
{
t0n=0;
second++; //秒加1
if(second>=60) //到60秒
{
second=0;
minute++; //分加1
if(minute>=60) //到60分
{
minute=0;
hour++; //小时加1
if(hour>=24)
hour=0;
}
}
}
disbuf[0]=hour/10; //显示小时十位
disbuf[1]=hour%10; //显示小时个位
disbuf[3]=minute/10; //显示分十位
disbuf[4]=minute%10; //显示分个位
disbuf[6]=second/10; //显示秒十位
disbuf[7]=second%10; //显示秒个位
}
}
//定时器T0中断服务子程序
void T0_isr() interrupt 1
{
TH0=0x3C; //重写时间常数
TL0=0xb0;
t0n++; //中断次加1
}
//外部中断INT0服务程序,调时状态下,加1
void INT0_ISR() interrupt 0
{
if(dis==1) //调小时
{
hour++; //小时加1
if(hour>=24)
hour=0;
}
if(dis==4) //调分
{
minute++; //分加1
if(minute>=60)
minute=0;
}
if(dis==7) //调秒
{
second++; //秒加1
if(second>=60)
second=0;
}
}
//外部中断INT1服务程序,调时状态下,减1
void INT1_ISR() interrupt 2
{
if(dis==1) //调小时
{
hour--; //小时减1
if(hour==0xff)
hour=23;
}
if(dis==4) //调分
{
minute--; //分减1
if(minute==0xff)
minute=59;
}
if(dis==7) //调秒
{
second--;//秒减1
if(second==0xff)
second=59;
}
}
#include<reg52h>
#define uchar unsigned char
#define uint unsigned int
sbit wela=P2^7;
sbit dula=P2^6;
sbit rs=P3^5;
sbit lcden=P3^4;
sbit rw=P3^6;
sbit s1=P3^0;
sbit s2=P3^1;
sbit s3=P3^2;
sbit rd=P3^7;
uchar code table[]=" 2012-6-09 SAT";
uchar code table1[]=" 20:00:00";
uchar count,s1num,shi,fen,miao;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=10;y>0;y--);
}
void write_com(uchar com)
{
rs=0;
rw=0;
lcden=0;
P0=com;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
void write_date(uchar date)
{
rs=1;
rw=0;
lcden=0;
P0=date;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void keyscan()
{
if(s1==0)
{
delay(5);
if(s1==0)
{
s1num++;
while(!s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+11);
write_com(0x0f);
}
if(s1num==2)
{
write_com(0x80+0x40+8);
}
if(s1num==3)
{
write_com(0x80+0x40+5);
}
if(s1num==4)
{ s1num=0;
write_com(0x0c);
TR0=1;
}
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
}
}
void init()
{
uchar num;
rw=0;
dula=0;
wela=0;
lcden=0;
write_com(0x38);
delay(20);
write_com(0x0c);
delay(20);
write_com(0x06);
delay(20);
write_com(0x01);
delay(20);
write_com(0x80);
delay(20);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(20);
}
write_com(0x80+0x40);
delay(20);
for(num=0;num<11;num++)
{ write_date(table1[num]);
delay(40);
}
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void main()
{
init();
while(1)
{
keyscan();
}
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==20)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);
}
}
KEYVAL EQU 30H
KEYTM EQU 31H
KEYSCAN EQU 32H
DAT EQU 33H
SCANLED EQU 39H
CLK EQU 77H
SEC EQU 78H
MIN EQU 79H
HOUR EQU 7AH
PAUSE BIT 00H
DOT BIT 01H
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0ISR ;50ms定时
ORG 001BH
LJMP T1ISR ;扫描显示
ORG 0030H
MAIN:
MOV SP,#5FH
MOV TMOD,#11H
MOV TH0,#03CH
MOV TL0,#0B0H
MOV TH1,#0ECH
MOV TL1,#078H
MOV KEYVAL,#0
MOV SCANLED,#0
MOV 33H,#10H
MOV 34H,#10H
MOV 35H,#10H
MOV 36H,#10H
MOV 37H,#10H
MOV 38H,#10H
MOV SEC,#0
MOV MIN,#0
MOV HOUR,#0
MOV CLK,#0
CLR PAUSE
SETB EA
SETB ET1
SETB TR1
LOOP:
LCALL KEYSEL
MOV A,KEYVAL
CJNE A,#0FFH,LOOP1
SJMP LOOP
LOOP1:
CJNE A,#10,LOOP2 ;“ON”启动
SETB TR0
SETB ET0
SETB PAUSE
SJMP LOOP
LOOP2:
CJNE A,#11,LOOP3 ;“=”清零
MOV SEC,#0
MOV MIN,#0
MOV HOUR,#0
LCALL DISCHG
SJMP LOOP
LOOP3:
CJNE A,#15,LOOP4 ;“+”暂停
CLR TR0
CLR ET0
CLR PAUSE
SJMP LOOP
LOOP4:
CJNE A,#14,LOOP5 ;“-”清显示暂停
MOV 33H,#10H
MOV 34H,#10H
MOV 35H,#10H
MOV 36H,#10H
MOV 37H,#10H
MOV 38H,#10H
CLR TR0
CLR ET0
CLR PAUSE
SJMP LOOP
LOOP5:
CJNE A,#10,LOOP6 ;数字键
LOOP6:
JC LOOP7
LJMP LOOP
LOOP7:
JNB PAUSE,LOOP8 ;暂停状态可以输入数字键
LJMP LOOP
LOOP8:
MOV 33H,34H
MOV 34H,35H
MOV 35H,36H
MOV 36H,37H
MOV 37H,38H
MOV 38H,KEYVAL
MOV A,33H
SWAP A
ORL A,34H
LCALL BCDH
MOV HOUR,A
MOV A,35H
SWAP A
ORL A,36H
LCALL BCDH
MOV MIN,A
MOV A,37H
SWAP A
ORL A,38H
LCALL BCDH
MOV SEC,A
LJMP LOOP
;------------------
;BCD转换为十六进制
BCDH:
MOV B,#10H
DIV AB
MOV R7,B
MOV B,#10
MUL AB
ADD A,R7
RET
;------------------
;十六进制转换为BCD
HBCD:
MOV B,#10
DIV AB
SWAP A
ORL A,B
RET
;------------------
KEYSEL:
MOV KEYVAL,#0
MOV KEYSCAN,#0EFH
LCALL GETKEY
MOV A,KEYTM
JZ KEYS1
MOV KEYVAL,A
SJMP KEYRTN
KEYS1:
MOV KEYSCAN,#0DFH
LCALL GETKEY
MOV A,KEYTM
JZ KEYS2
CLR C
ADD A,#4
MOV KEYVAL,A
SJMP KEYRTN
KEYS2:
MOV KEYSCAN,#0BFH
LCALL GETKEY
MOV A,KEYTM
JZ KEYS3
CLR C
ADD A,#8
MOV KEYVAL,A
SJMP KEYRTN
KEYS3:
MOV KEYSCAN,#7FH
LCALL GETKEY
MOV A,KEYTM
JZ KEYRTN
CLR C
ADD A,#12
MOV KEYVAL,A
KEYRTN:
LCALL CHGKEY
RET
;--------------------
GETKEY:
MOV KEYTM,#0
MOV A,KEYSCAN
MOV P3,A
NOP
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY
MOV R2,#10
LCALL DELAY
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY
MOV A,P3
ANL A,#0FH
MOV R7,A
SF:
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ SF
MOV A,R7
CJNE A,#0EH,NK1
MOV KEYTM,#1
SJMP NOKEY
NK1:
CJNE A,#0DH,NK2
MOV KEYTM,#2
SJMP NOKEY
NK2:
CJNE A,#0BH,NK3
MOV KEYTM,#3
SJMP NOKEY
NK3:
CJNE A,#07H,NOKEY
MOV KEYTM,#4
NOKEY: RET
;--------------------
DELAY:
MOV R3,#50
DELAY1:
MOV R4,#100
DJNZ R4,$
DJNZ R3,DELAY1
DJNZ R2,DELAY
RET
;--------------------
T0ISR:
PUSH ACC
CLR TR0
MOV TH0,#3CH
MOV TL0,#0B0H
SETB TR0
INC CLK
MOV A,CLK
CJNE A,#20,T0ISRE
MOV CLK,#0
INC SEC
MOV A,SEC
CJNE A,#60,T0ISRE
MOV SEC,#0
INC MIN
MOV A,MIN
CJNE A,#60,T0ISRE
MOV MIN,#0
INC HOUR
MOV A,HOUR
CJNE A,#24,T0ISRE
MOV SEC,#0
MOV MIN,#0
MOV HOUR,#0
T0ISRE:
LCALL DISCHG
POP ACC
RETI
;--------------------
DISCHG:
MOV A,HOUR
LCALL HBCD
PUSH ACC
ANL A,#0FH
MOV 34H,A
POP ACC
ANL A,#0F0H
SWAP A
MOV 33H,A
MOV A,MIN
LCALL HBCD
PUSH ACC
ANL A,#0FH
MOV 36H,A
POP ACC
ANL A,#0F0H
SWAP A
MOV 35H,A
MOV A,SEC
LCALL HBCD
PUSH ACC
ANL A,#0FH
MOV 38H,A
POP ACC
ANL A,#0F0H
SWAP A
MOV 37H,A
RET
;--------------------
T1ISR:
PUSH ACC
CLR TR1
MOV TH1,#0ECH
MOV TL1,#78H
SETB TR1
MOV DPTR,#LEDTAB
T100:
MOV R0,#DAT
MOV A,SCANLED
ADD A,R0
MOV R0,A
MOV A,SCANLED
JNZ T101
MOV P2,#01H
CLR DOT
SJMP T1DIS
T101:
DEC A
JNZ T102
MOV P2,#02H
SETB DOT
SJMP T1DIS
T102:
DEC A
JNZ T103
MOV P2,#04H
CLR DOT
SJMP T1DIS
T103:
DEC A
JNZ T104
MOV P2,#08H
SETB DOT
SJMP T1DIS
T104:
DEC A
JNZ T105
MOV P2,#10H
CLR DOT
SJMP T1DIS
T105:
MOV P2,#20H
CLR DOT
T1DIS:
MOV A,@R0
MOVC A,@A+DPTR
JNB DOT,T1DIS1
ORL A,#01H
T1DIS1:
CPL A
MOV P0,A
INC SCANLED
MOV A,SCANLED
CJNE A,#6,T1END
MOV SCANLED,#0
T1END:
POP ACC
RETI
;--------------------
CHGKEY:
MOV A,KEYVAL
JZ KV16
DEC A
JNZ KV01
MOV KEYVAL,#7
RET
KV01:
DEC A
JNZ KV02
MOV KEYVAL,#4
RET
KV02:
DEC A
JNZ KV03
MOV KEYVAL,#1
RET
KV03:
DEC A
JNZ KV04
MOV KEYVAL,#10
RET
KV04:
DEC A
JNZ KV05
MOV KEYVAL,#8
RET
KV05:
DEC A
JNZ KV06
MOV KEYVAL,#5
RET
KV06:
DEC A
JNZ KV07
MOV KEYVAL,#2
RET
KV07:
DEC A
JNZ KV08
MOV KEYVAL,#0
RET
KV08:
DEC A
JNZ KV09
MOV KEYVAL,#9
RET
KV09:
DEC A
JNZ KV10
MOV KEYVAL,#6
RET
KV10:
DEC A
JNZ KV11
MOV KEYVAL,#3
RET
KV11:
DEC A
JNZ KV12
MOV KEYVAL,#11
RET
KV12:
DEC A
JNZ KV13
MOV KEYVAL,#12
RET
KV13:
DEC A
JNZ KV14
MOV KEYVAL,#13
RET
KV14:
DEC A
JNZ KV15
MOV KEYVAL,#14
RET
KV15:
DEC A
JNZ KV16
MOV KEYVAL,#15
RET
KV16:
MOV KEYVAL,#0FFH
RET
;--------------------
LEDTAB: DB 0FCH ;"0" 00H
DB 60H ;"1" 01H
DB 0DAH ;"2" 02H
DB 0F2H ;"3" 03H
DB 66H ;"4" 04H
DB 0B6H ;"5" 05H
DB 0BEH ;"6" 06H
DB 0E0H ;"7" 07H
DB 0FEH ;"8" 08H
DB 0F6H ;"9" 09H
DB 0EEH ;"A" 0AH
DB 3EH ;"B" 0BH
DB 9CH ;"C" 0CH
DB 7AH ;"D" 0DH
DB 9EH ;"E" 0EH
DB 8EH ;"F" 0FH
DB 00H ;" " 10H
;--------------------
END
以上就是关于51单片机 电子时钟程序(共阳)。为何老是乱码,求大神指点全部的内容,包括:51单片机 电子时钟程序(共阳)。为何老是乱码,求大神指点、单片机外部中断控制数码管电子时钟。、STC89c52单片机设计6位数码管电子钟时钟等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)