用51单片机编写程序实现数码管的时钟数字显示

用51单片机编写程序实现数码管的时钟数字显示,第1张

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

#include <AT89X52H>

#include <intrinsh>

#define REST P3_4

#define SCLK P3_7

#define DATA P3_6

unsigned char code displayCode[]={0xc0,0xf9,0xa4,0xb0,0x99,

0x92,0x82,0xf8,0x80,0x90};

unsigned char code controladdress[]={0x80,0x82,0x84,0x86,0x88,

0x8a,0x8c,0x8e,0x90,0xbe};

unsigned char hour,minute,second;

unsigned char day,month,week,year;

unsigned char clockhour,clockminute;

unsigned int num;

unsigned char select,oneminute;

bit bdata modeselect;

void delay();

void writetime();

void display(unsigned char temp,unsigned char  mode);

void sound()

{

while(num<2000)

{

P3_0=0;

}

P3_0=1;

}

void initial()

{

P0=0;

TMOD=0x22;

IE=0xCF;

IT0=1;

IT1=1;

T2CON=0;

RCAP2L=0xf0;

RCAP2H=0x1f;

TH2=0x1c;

TL2=0xf0;

IP=0X06;

TH0=0x48;

TL0=0x48;

TH1=0X48;

TR0=1;

PCON=0x01;

hour=12;

minute=0;

second=0;

num=0;

select=0;

clockhour=12;

clockminute=0;

modeselect=0;

day=16;

month=8;

week=7;

year=9;

}

void interrupt0()interrupt 0 using 3

{

TR1=1;

select++;

if(select==8)

{

select=0;

}

if(select==1)

ET2=1;

oneminute=second-1;

}

void timer0()interrupt 1 using 3

{

num++;

if(num==5000)

{

num=0;

second++;

}

if(second>=60)

{

minute++;

second=0;

}

if(minute>=60)

{

hour++;

minute=0;

}

if(hour>=24)

hour=0;

}

void interrupt1()interrupt 2 using 3

{

oneminute=second-1;

switch(select)

{

case 4:{

hour++;

if(hour>=24)

hour=0;

break;

}

case 5:{

minute++;

if(minute>=60)

minute=0;

break;

}

case 6:{

second++;

if(second>=60)

second=0;

break;

}

case 2:{

clockhour++;

if(clockhour>=24)

clockhour=0;

break;

}

case 3:{

clockminute++;

if(clockminute>=60)

clockminute=0;

break;

}

default:{

modeselect=0;

ET2=!ET2;

break;

}

}

}

void timer1()interrupt 3 using 3

{

if(select)

{

if(second==oneminute)

{

select=0;

TR1=0;

}

}

}

void timer2()interrupt 5 using 3

{

sound();

TF2=0;

if(minute!=clockminute||hour!=clockhour)

TR2=0;

}

void delay()

{

unsigned char i=255;

while(--i)

{

;

}

}

void display(unsigned char temp,unsigned char  mode)

{

if(temp==4||temp==2)

P0=0;

else

P0=1;

if(mode)

P1=displayCode[hour/10];

else

P1=displayCode[clockhour/10];

delay();

if(temp==4||temp==2)

P0=0;

else

P0=2;

if(mode)

P1=displayCode[hour%10];

else

P1=displayCode[clockhour%10];

delay();

if(temp==1||temp==2||temp==3)

P0=0;

else

P0=4;

P1=0xbf;

delay();

if(temp==5||temp==3)

P0=0;

else

P0=8;

if(mode)

P1=displayCode[minute/10];

else

P1=displayCode[clockminute/10];

delay();

if(temp==5||temp==3)

P0=0;

else

P0=16;

if(mode)

P1=displayCode[minute%10];

else

P1=displayCode[clockminute%10];

delay();

if(temp==1||temp==2||temp==3)

P0=0;

else

P0=32;

P1=0xbf;

delay();

if(temp==6)

P0=0;

else

P0=64;

if(mode)

P1=displayCode[second/10];

else

P1=displayCode[0];

delay();

if(temp==6)

P0=0;

else

P0=128;

if(mode)

{

if(ET2)

P1=displayCode[second%10]+128;

else

P1=displayCode[second%10];

}

else

P1=displayCode[0];

delay();

}

void write(unsigned char Bdata)

{

unsigned char i=8;

for(;i>0;i--)

{

if(Bdata&0x01)

DATA=1;

else

DATA=0;

SCLK=1;

SCLK=0;

Bdata>>=1;

}

}

void  writedata(unsigned char address,Bdata)

{

REST=0;

SCLK=0;

_nop_();

REST=1;

write(address);

write(Bdata);

REST=0;

}

unsigned char read(unsigned char Bdata)

{

unsigned char tdata=0,i=8;

REST=0;

SCLK=0;

_nop_();

REST=1;

write(Bdata);

for(;i>0;i--)

{

tdata>>=1;

if(DATA)

tdata=tdata|0x80;

else

tdata|=0x00;

SCLK=1;

SCLK=0;

}

return tdata;

}

void writetime()

{

unsigned char i,time,temp[3];

temp[0]=second;

temp[1]=minute;

temp[2]=hour;

for(i=0;i<3;i++)

{

time=temp[i]%10;

time|=(temp[i]/10)<<4;

writedata(controladdress[i],time);

}

}

void writeyear()

{

unsigned char i,year0,temp[4];

temp[0]=day;

temp[1]=month;

temp[2]=week;

temp[3]=year;

for(i=0;i<4;i++)

{

year0=temp[i]%10;

year0|=(temp[i]/10)<<4;

writedata(controladdress[i+3],year0);

}

}

void readtime()

{

unsigned char i,time,temp[3];

for(i=0;i<3;i++)

{

temp[i]=read(1+controladdress[i]);

time=temp[i]&0x0f;

time+=(temp[i]>>4)10;

temp[i]=time;

}

second=temp[0];

minute=temp[1];

hour=temp[2];

}

void readyear()

{

unsigned char i,year0,temp[4];

for(i=0;i<4;i++)

{

temp[i]=read(1+controladdress[i+3]);

year0=temp[i]&0x0f;

year0+=(temp[i]>>4)10;

temp[i]=year0;

}

day=temp[0];

month=temp[1];

week=temp[2];

year=temp[3];

}

void main()

{

initial();

sound();

writedata(0x8e,0x00);

writedata(0x84,0x12);

writedata(0x8f,0x00);

readtime();

writeyear();

readyear();

while(1)

{

switch(select)

{

case 0:{

display(0,1);

break;

}

case 1:{

if(num<=2500)

{

display(1,0);

}

else

{

display(0,0);

}

break;

}

case 2:{

if(num<=2500)

{

display(2,0);

}

else

{

display(0,0);

}

break;

}

case 3:{

if(num<=2500)

{

display(3,0);

}

else

{

display(0,0);

}

break;

}

case 4:{

if(num<=2500)

{

display(4,1);

}

else

{

display(0,1);

}

break;

}

case 5:{

if(num<=2500)

{

display(5,1);

}

else

{

display(0,1);

}

break;

}

case 6:{

if(num<=2500)

{

display(6,1);

}

else

{

display(0,1);

}

break;

}

case 7:{

writetime();

writetime();

writetime();

select=0;

break;

}

default:break;

}

if(second==0)

{

if(minute==0||minute==30)

sound();

}

if(minute==clockminute&&hour==clockhour)

{

TR2=1;

modeselect=1;

}

if(modeselect==1&&hour==clockhour&&!((minute-clockminute)%5))

TR2=1;

}

}

#include<reg52h>

sbit ksec=P3^0;

sbit kmin=P3^1;

sbit khour=P3^2;

unsigned char secshi=0,secge=0,minshi=0,minge=0,hourshi=0,hourge=0;

unsigned int num=0,sec=0,min=0,hour=0;

unsigned char code table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

void delay(unsigned int z)

{

unsigned int x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void keyscan();

void display();

void main()

{TMOD=0x01;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

EA=1;ET0=1;TR0=1;

while(1)

{display();

keyscan();

}

}

void time0() interrupt 1

{num++;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

}

void display()

{if(num==20)

{num=0;

sec++;

if(sec==60)

{sec=0;

min++;

if(min==60)

{min=0;

hour++;

if(hour==24)

{hour=0;

min=0;

sec=0;

}

}

}

}

secge=sec%10;

secshi=sec/10;

minge=min%10;

minshi=min/10;

hourge=hour%10;

hourshi=hour/10;

P2=0xfe;

P0=table[secge];

delay(5);

P2=0xfd;

P0=table[secshi];

delay(5);

P2=0xfb;

P0=0x40;

delay(5);

P2=0xf7;

P0=table[minge];

delay(5);

P2=0xef;

P0=table[minshi];

delay(5);

P2=0xdf;

P0=0x40;

delay(5);

P2=0xbf;

P0=table[hourge];

delay(5);

P2=0x7f;

P0=table[hourshi];

delay(5);

}

void keyscan()

{if(ksec==0)

{delay(10);

if(ksec==0)

{sec++;

if(sec>=60)

sec=0;

}

while(ksec==0)

display();}

if(kmin==0)

{delay(10);

if(kmin==0)

{min++;

if(min>=60)

min=0;

}

while(kmin==0)

display();

}

if(khour==0)

{delay(10);

if(khour==0)

{hour++;

if(hour>=60)

hour=0;

}

while(khour==0)

display();

}

}

已经编译通过了:发现的错误很多! 你自己比对一下吧!

QQ:361179146

/

ILONG编做

注意P3口输出模拟和在{实验板}上不一样。实验板不用取反

目的:用20次T0定时产生1s进而形成 HH-mm-ss时间

参数说明:

40H~47H :显示管,每位暂存器,存放要显示的数码的地址。可根据地址加1,实现该位数加1;

并且低4位可以代表管子要显示的值(42H、45H除外)。

48H :要显示的位值(0~7,由译码器翻译出)

49H :每位每次刷出时要显示的时间0~256us

4A :20次定时,的次数计数器

4BH,4CH :小时十位进位刷0,时,小时两位数的暂存

4DH :调试时,要调整类型,每次INT0中断自增一次

50H~5FH :0~F 16个数的码值

60H :"-"的码值

61H :"空" 的码值

62H,63H :要闪的两位地址暂存 (好像没用着)

R0 :存放 每位暂存器 的地址,用于 刷新位时 移位

00H(位) :是否有INT0(调整)中断

01H(位) :是闪亮,还是闪空,即:闪烁时的亮暗状态

存在问题:

1,调整时间时,分钟位开始乱码。

2,调整时间时,必须亮的时候才能调

3,时间差:慢于实际时间

20111021 ilong(crazy night)

/

SJMP 0x0030

ORG 0x0030

MAIN:

//启动外部中断

SETB IT0

SETB IE0

SETB EX0

SETB PX0

SETB IT1

SETB IE1

SETB EX1

SETB PX1

SETB EA

CLR 00H //没有调整中断

CLR 01H //闪空

MOV 4DH,#04H //0xFC

MOV P3,#0FH

MOV 62H,46H //从分开始闪

MOV 63H,47H

//十位数

MOV 50H,#3FH

MOV 51H,#06H

MOV 52H,#5BH

MOV 53H,#4FH

MOV 54H,#66H

MOV 55H,#6DH

MOV 56H,#7DH

MOV 57H,#07H

MOV 58H,#7FH

MOV 59H,#6FH

MOV 5AH,#77H

MOV 5BH,#7CH

MOV 5CH,#39H

MOV 5DH,#5EH

MOV 5EH,#79H

MOV 5FH,#71H

MOV 60H,#40H

MOV 61H,#00H

//八位管的暂存 从左到右40-47

MOV 40H,#50H

MOV 41H,#50H

MOV 42H,#60H

MOV 43H,#50H

MOV 44H,#50H

MOV 45H,#60H

MOV 46H,#50H

MOV 47H,#50H

MOV 48H,#00H //扫描位暂存

MOV R0,#40H //扫描值地址

MOV 4AH,00H //20次定时 计数

LCALL TIMER_GO20 //开启并初始定时器

//主函数进程,就是扫描码管值并显示,其他为中断 *** 作

SCAN: //显示器扫描输出

MOV P2,48H //选择显示位(从左到右0-7)

MOV A,@R0 //获取该位的数码值 地址

MOV R1,A

MOV A,@R1 //获取该位码值

//CPL A //根据数码管是共阴、共阳 是否取反

MOV P0,A //从P0输出每位的码值,注意:该端口时下面的“清屏”一起改

LCALL DELAY //进入每位延时

MOV P0,#0FFH //清屏

INC 48H //暂存器后移

INC R0 //位后移

MOV A,48H //通过 (48H)的值+08H 判断是否到了 位尾

ADD A,#08H

JB 0D6H,RER //D6H(位)为AC(辅助进位:半进位)。为1时说明(48H)的值+08H=F,即(48H)=8,此时跳向RER

SJMP SCAN

RER: //扫描重置

CLR 0D6H //重置 AC(辅助进位:半进位)

MOV 48H,#00H

MOV R0,#40H

SJMP SCAN

//End 主函数

DELAY: //延时,用于扫描7段管时,在每一位停留的时间时间太短,回使不该亮的段也有些亮

MOV 49H,#25H //49H的值不可以等于FF,因为FF取反后49H为0,不会延迟了

MOV A,0FEH //用取反设置循环次数,

CPL A

MOV 49H,A

ADD_1:

INC 49H

MOV R1,49H //因为DJNZ判断完后要把判断的地址减去1,所以为了DJNZ不对49H的内容造成影响,把49H的值装到R1中去判断

DJNZ R1,ADD_1

RET

//20次定时

TIMER_GO20:

//用4AH 设置循环次数

MOV 4AH,#15H //20(=0x15)次定时

MOV A,4AH //用取反设置定时次数,

CPL A

MOV 4AH,A

SJMP TIMER_S

TIMER_GO5: //与TIMER_GO20类似,只是这里只让定时5次一循环。用于调整闪烁

MOV 4AH,#05H //5(=0x05)次定时

MOV A,4AH //用取反设置定时次数,

CPL A

MOV 4AH,A

TIMER_S://未重置(4AH)的调用,

//设置启动T0

MOV TMOD,#01H //设置模式:T0模式1

MOV TH0,#3CH //T0初值高8位

MOV TL0,#0AH //T0初值低8位

//CLR TF0 //未知问题

SETB ET0 //T0允许中断

SETB EA //CPU允许中断

SETB TR0 //启动T0

RET

T0_INT: //T0中断程序段

CPL P17 //测试端口:T0重新定时一次发生一次跳转

LCALL TIMER_S //T0重新定时,继续跑。但:不会初始化20次计数

INC 4AH //T0定时次数加1

MOV A,4AH

JNZ CY_20 //50H加到FF再加就到0了。不为0回去接着执行主程序;为0 则20次定时 溢出即:00H(位)为1

CPL P16 //测试端口每秒发生一次跳转

JB 00H,GO_BLINK //如果00H(位)被置1,则不再执行时间系统加1。用于调整时显示闪烁

LCALL CLOCK_GO //时间系统加1秒

LCALL TIMER_GO20 //20次重新开始

SJMP CY_20

GO_BLINK:

LCALL TIMER_GO5 //5次重新开始,

LCALL BLINK

CY_20: RET

//时间系统进位设置

CLOCK_GO:

INC 47H //秒加1

//个位秒 进位 十位

MOV A,#5AH //主要是看"#5A"中的“A”,

SUBB A,47H

JNZ SS_OUT //如果(47H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位

MOV 47H,#50H

INC 46H

SS_OUT:

//秒 进位 分

MOV A,#56H //

SUBB A,46H

JNZ SM_OUT //如果(46H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位

MOV 46H,#50H

CLOCK_GO_M:INC 44H

//分调整用

SM_OUT:

//分个位 进位 分

MOV A,#5AH //

SUBB A,44H

JNZ MM_OUT //如果(44H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位

MOV 44H,#50H

INC 43H

MM_OUT:

//分 进位 时

MOV A,#56H //

SUBB A,43H

JNZ MH_OUT //如果(43H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位

MOV 43H,#50H

CLOCK_GO_H:INC 41H

//时调整用

MH_OUT:

//时个位 进位 时

MOV A,#5AH //

CLR CY //排除借位影响

SUBB A,41H

JNZ HH_OUT //如果(41H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位

MOV 41H,#50H

INC 40H

HH_OUT:

//时十位置0

MOV 4BH,40H //为了不影响暂存器数据,把40H、41H转到4BH、4CH中进行 *** 作

MOV 4CH,41H

MOV A,4BH

SWAP A //获得小时十位数,并放到A的高4位上

ANL A,#0F0H //清0低4位

ANL 4CH,#0FH //小时个位 高4位清0

ADD A,4CH //小时的十位与个位相加(高4位来自小时的十位暂存器40H,低四位来自小时个位的寄存器41H)

SUBB A,#24H

JNZ HD_OUT //如果(46H)值 低4 与A中的低4不相同,跳到“SS_OUT”,不进位

MOV 41H,#50H //个位 清零

MOV 40H,#50H //十位清零

HD_OUT:

CG_OUT: RET

//END 时间系统进位设置

//INTO中断程序段

INT0_INT:

SETB 00H

CPL P15

CPL P15

CLR 01H //使得在换位闪烁时不会把上位的数带给下一位,

HMS_BACK: //在每次换位时都要把,被放到暂存上的值那回去,使其显示出来

MOV A,4DH

CJNE A,#02H,BSH_S //back second OR hour _select

LCALL LIGHT_M

SJMP B_END

BSH_S: //恢复秒小时选择

JB CY,B_H

SJMP B_S

B_S: LCALL LIGHT_S //把调好的数据装回暂存器

SJMP B_END

B_H: LCALL LIGHT_H

B_END:

// CLR TR0 //定时器0,停止计时

DEC 4DH //调整类型(时、分、秒)改变

MOV A,4DH

JNZ INT0_OUT //是否恢复时钟

CLR 00H //置0,调整中断(ilong 定义)

CLR 01H

MOV 4DH,#04H //初始化调整类型

INT0_OUT:

RET

////闪烁

BLINK:

CPL P11

CPL 01H

MOV A,4DH

CJNE A,#02H,SH_S

SJMP MM_SET

SH_S: //闪烁秒小时选择

JB CY,HH_SET

SJMP SS_SET

SS_SET: //秒钟设置

JB 01H,DACK_S

LIGHT_S:

MOV 46H,4EH

MOV 47H,4FH

SJMP BLINK_OUT

DACK_S:

MOV 4EH,46H

MOV 4FH,47H

MOV 46H,#61H

MOV 47H,#61H

RET

MM_SET: // 分钟设置

JB 01H,DACK_M

LIGHT_M:

MOV 43H,4EH

MOV 44H,4FH

SJMP BLINK_OUT

DACK_M:

MOV 4EH,43H

MOV 4FH,44H

MOV 43H,#61H

MOV 44H,#61H

RET

HH_SET: //小时设置

JB 01H,DACK_H

LIGHT_H:

MOV 40H,4EH

MOV 41H,4FH

SJMP BLINK_OUT

DACK_H:

MOV 4EH,40H

MOV 4FH,41H

MOV 40H,#61H

MOV 41H,#61H

BLINK_OUT:RET

//INT1中断程序段

INT1_INT:

//lcall HMS_BACK

//clr tr0

CPL P14

MOV A,4DH

CJNE A,#02H,ADDSH_S //ADD Hour OR ADD second OR _select

SJMP ADD_M

ADDSH_S: //调整秒小时选择

JB CY,ADD_H

SJMP ADD_S

ADD_S: LCALL CLOCK_GO

SJMP ADD_END

ADD_M: LCALL CLOCK_GO_M

SJMP ADD_END

ADD_H: LCALL CLOCK_GO_H

ADD_END:

// LCALL CLOCK_GO

RET

/

最后放中断保险些

/

//T0中断程序

ORG 000BH

LCALL T0_INT

RETI

//INT0中断

ORG 0003H

LCALL INT0_INT

RETI

//INT1中断

ORG 0013H

LCALL INT1_INT

RETI

END

给你ds18b20温度传感器代码你参考,我的空间还有些资料

/

//DS18B20温度传感器//

//作者:jammylee

//日期:2008-2-25

//版本:V10

//晶振:12MHZ

/

//包含头文件

#include<reg51h>

#include<stdioh>

//

typedef unsigned char uint8; //定义八位无符号变量

//

//定义引脚(根据硬件改变)

sbit highbit = P2^7;

sbit lowbit = P2^6;

sbit DQ = P3^0; //温度传感器数据引脚通信定义

//

unsigned char Code[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //定义数字显示数组

//0, 1, 2 3 4 5 6 7 8 9

//

//定义延时子函数

void mDelay(uint8 Delay)

{

while(Delay--);

}

//

//温度传感器DS18B20的初始化函数

Init_DS18B20(void)

{

uint8 x = 0;

DQ = 1; //DQ复位信号

mDelay(8); //延时

DQ = 0; //将DQ电平拉低

mDelay(80); //延时大于480us

DQ = 1; //将DQ电平拉高

mDelay(14); //延时

x = DQ; //如果x=0则初始化成功,x=1则初始化失败

mDelay(20); //延时

}

//

//读一个字节

ReadOneChar(void)

{

uint8 i = 0;

uint8 dat = 0;

for(i=8;i>0;i--)

{

DQ = 0; //低电平脉冲信号

dat>>=1; //dat右移一位

DQ = 1; //高低平脉冲信号

if(DQ)

{

dat |= 0x80;

}

mDelay(4);//延时

}

return(dat); //返回dat值

}

//

//写一个字节

WriteOneChar(uint8 dat)

{

uint8 i = 0;

for(i=8;i>0;i--)

{

DQ = 0; //低电平脉冲信号

DQ = dat&0x01;

mDelay(5);//延时

DQ = 1; //高电平脉冲信号

dat >>= 1;//dat右移一位

}

mDelay(4);

}

//

//读取温度

ReadTemperature(void)

{

uint8 L = 0; //定义温度高八位

uint8 H = 0; //定义温度低八位

uint8 temp = 0;

Init_DS18B20(); //温度传感器DS18B20初始化

WriteOneChar(0xCC); // 跳过读序号列号的 *** 作

WriteOneChar(0x44); // 启动温度转换

Init_DS18B20();

WriteOneChar(0xCC); //跳过读序号列号的 *** 作

WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度

L = ReadOneChar(); //读取温度值低位

H = ReadOneChar(); //读取温度值高位

L = L>>4;

temp = H<<4;

temp = temp|L;

return(temp);

}

//

//温度显示函数

void DisplayTemperture(uint8 temp)

{

P0 = Code[temp%10];

lowbit = 0;

mDelay(100);

lowbit = 1;

P0=Code[temp/10];

highbit = 0;

mDelay(100);

highbit = 1;

}

//

//主函数

void main(void)

{

uint8 temp;

while(1) //主循环

{

temp = ReadTemperature();

DisplayTemperture(temp);

}

}

以上就是关于用51单片机编写程序实现数码管的时钟数字显示全部的内容,包括:用51单片机编写程序实现数码管的时钟数字显示、求89c52单片机 C语言实现数字时钟程序、C语言 单片机 数字钟等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/9336411.html

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

发表评论

登录后才能评论

评论列表(0条)

保存