51单片机 电子时钟程序(共阳)。为何老是乱码,求大神指点

51单片机 电子时钟程序(共阳)。为何老是乱码,求大神指点,第1张

小问题还是挺多的。

首先,像楼上说的,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位数码管电子钟时钟等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9356773.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存