利用AT89C51单片机设计简易电子钟(六位),通过8位LED数码管实现时间显示;系统可以通过三个按键实现时间

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-07-06
利用AT89C51单片机设计简易电子钟(六位),通过8位LED数码管实现时间显

我曾经做过,单单编程这一项就麻烦死了.
还不如去网购买现成的,整套都有的卖.

#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit ds1302_RST =P2^0;
sbit ds1302_IO =P2^1;
sbit ds1302_SCLK=P2^2;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit A1=P3^0;
sbit A2=P3^1;
sbit A3=P3^2;
sbit A4=P3^3;
sbit A5=P3^4;
sbit A6=P3^5;
sbit key1=P3^6;
sbit key2=P3^7;
uchar now_time[3],wei,d[3]={0,0,0};
uchar code s[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
};
void delay(uint x)
{
uchar i;
for(x;x>0;x--)
for(i=0;i<100;i++);
}
void disp()
{
P1=s[now_time[2]/16];
A1=d[2];
delay(5);
A1=1;
P1=s[now_time[2]%16];
A2=d[2];
delay(5);
A2=1;
P1=s[now_time[1]/16];
A3=d[1];
delay(5);
A3=1;
P1=s[now_time[1]%16];
A4=d[1];
delay(5);
A4=1;
P1=s[now_time[0]/16];
A5=d[0];
delay(5);
A5=1;
P1=s[now_time[0]%16];
A6=d[0];
delay(5);
A6=1;
}
/***********************************************************************/
uchar read_Byte()
{
uchar i;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=ds1302_IO;
ds1302_SCLK=1;
ds1302_SCLK=0;
}
return(ACC);
}



void write_Byte(uchar tdata)
{
uchar i;
ACC=tdata;
for(i=8;i>0;i--)
{
ds1302_IO=ACC0;
ds1302_SCLK=1;
ds1302_SCLK=0;
ACC=ACC>>1;
}

}
/***********************************************************************************/
void write_data_ds1302(uchar taddr,uchar tdata)
{
ds1302_RST=0;
ds1302_SCLK=0;
ds1302_RST=1;
write_Byte(taddr);
write_Byte(tdata);
ds1302_RST=0;
ds1302_SCLK=1;
}


uchar read_data_ds1302(uchar taddr)
{
uchar tdata;

ds1302_RST=0;
ds1302_SCLK=0;
ds1302_RST=1;
write_Byte(taddr);
tdata=read_Byte();
ds1302_RST=0;
ds1302_SCLK=1;
return(tdata);
}
/***********************************************************************************/

void get_ds1302()
{
uchar k;
uchar taddr = 0x81;
for (k=0; k<3; k++)
{
now_time[k] = read_data_ds1302(taddr);
taddr+=2;

}
}
/***********************************************************************************/

void init_ds1302()
{
ds1302_RST=0;
ds1302_SCLK=0;
A1=1;
A2=1;
A3=1;
A4=1;
A5=1;
A6=1;
write_data_ds1302(0x80,0x00);
}
/***********************************************************************************/
void Time();
/***********************************************************************************/
main()
{
init_ds1302();

while(1)
{
disp();
get_ds1302();
if(key1==0);
{delay(10);
if(key1==0)
Time();
}

}
}
void timer() interrupt 3
{
uchar i;i++;
TH1=(65535-50000)/256;
TL2=(65535-50000)%256;
if(i==50)
{
d[wei]=1;
}
if(i==100)
{i=0;
d[wei]=0;
}
}
/***********************************************************************************/


void Time()
{
uchar temp;
uint r=0,p=1;
wei=2;
TMOD=0x01;
EA=1;
ET1=1;
TH1=(65535-50000)/256;
TL2=(65535-50000)%256;
TR1=1;
for(r=0;r<50;r++)
disp();

while( key1 )
{
wei=2;
disp();
if(key2==0)
{
disp();
if(key2==0)
{
temp=now_time[2]/16*10+now_time[2]%16;
temp++;
if(temp>=24)
temp=0;
now_time[2]=temp/10*16+temp%10;
write_data_ds1302(0x84,now_time[2]);
}
while(!key2);

}

}
wei=1;
d[2]=0;
for(r=0;r<50;r++)
disp();

while(key1 )
{disp();
if(key2==0)
{
disp();
if(key2==0)
{
temp=now_time[1]/16*10+now_time[1]%16;
temp++;
if(temp>=60)
temp=0;
now_time[1]=temp/10*16+temp%10;
write_data_ds1302(0x82,now_time[1]);
}
while(!key2);
}
}
wei=0;
d[1]=0;

for(r=0;r<50;r++)
disp();

while(key1 )
{
disp();
if(key2==0)
{
now_time[0]=0;
write_data_ds1302(0x80,now_time[0]);
}

} TR1=0;

d[0]=0;
for(r=0;r<30;r++)
disp();

}

/*********************************************************************************/


程序设计思路:1.利用单片机内部定时器作为计时器,调用timer函数;2、设计一套按键子程序;(3)设计一套数码显示管子程序。下列提供一套程序供参考。


#include<iom16v.h>

#include <macros.h>

#define uchar unsigned char

#define uint unsigned int


const uchar table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0-9对应字符

const uchar key_value[16]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

uchar data[4]={0}; //显示初始值为0

uint count=0;   //初始计数值为0

uchar keynum;



void port_init()  //端口初始化函数

{DDRA=0XFF;     //端口A为推挽1输出

 PORTA=0XFF;   

 PORTB=0XFF;  //端口B为推挽1输出

 DDRB=0XFF;

 DDRC=0XFF;  //端口C为不带上拉电阻的输入

 PORTC=0XFF;

 DDRD=0XFF;  //端口D低4位为输出

 PORTD=0X0F;

}



void delay(uint j)   //延时函数

{uint k;

 while(j--)

 {for(k=1000;k>0;k--) ;}

}



void display(uchar *p)   //显示函数

{uchar i,sel=0x01;

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

 {PORTA=sel;       //选通最右边的数码管

  PORTB=table[p[i]]; //送字型码

  delay(1);

  sel=sel<<1;     //左移一位

 }

}



uchar get_key(void)

{if((PIND&0X0F)!=0X0F) delay(3);

 {

  PORTD=0XEF;

  switch(PIND&0X0F)

  {case 0x0e: keynum=key_value[0];break;

   case 0x0d: keynum=key_value[4];break;

   case 0x0b: keynum=key_value[8];break;

   case 0x07: keynum=key_value[12];break;

   default:break;

  }

  PORTD=0xdf;

  switch(PIND&0X0F)

  {case 0x0e:keynum=key_value[1];break;

   case 0x0d:keynum=key_value[5];break;

   case 0x0b:keynum=key_value[9];break;

   case 0x07:keynum=key_value[13];break;

   default:break;

  }


  PORTD=0xbf;

  switch(PIND&0X0F)

  {case 0x0e:keynum=key_value[2];break;

   case 0x0d:keynum=key_value[6];break;

   case 0x0b:keynum=key_value[10];break;

   case 0x07:keynum=key_value[14];break;

   default:break;

  }

  

  PORTD=0x7f;

  switch(PIND&0X0F)

  {case 0x0e:keynum=key_value[3];break;

   case 0x0d:keynum=key_value[7];break;

   case 0x0b:keynum=key_value[11];break;

   case 0x07:keynum=key_value[15];break;

   default:break;

  } 

 while((PIND&0x0f)!=0x0f);

 }


 return keynum;

}


void process(uint i,uchar *q) //拆分BCD码函数,显示千、百、十、个位

{  q[0]=i/1000;

   i=i%1000;

   q[1]=i/100;

   i=i%100;

   q[2]=i/10;

   i=i%10;

   q[3]=i;

}


void main(void)

{port_init();

 PORTB=0xff;

 PORTA=0X00;

 delay(50);

 PORTA=0xff;

 

 while(1)

 {get_key();

  count=keynum;

  process(count,data);

  display(data);

 }

}

   



这个做起来也辛苦的好吧???我这正好有一份可以改改,这个分也太对不起劳动力了。。。。人民币10元还差不多。。。。。

汇编可以么

LED_1 EQU 30H
LED_2 EQU 31H
LED_3 EQU 32H
LED_4 EQU 33H
LED_5 EQU 34H
LED_6 EQU 35H
LED_7 EQU 36H
LED_8 EQU 37H
TIMER EQU 38H
MODE EQU 39H ;模式判断
FLASH EQU 40H ;闪烁判断 1亮 0不亮
BUTTON1 EQU 41H ;按钮开关
BUTTON2 EQU 42H ;按钮开关
BUTTON3 EQU 43H ;按钮开关
BUTTON4 EQU 44H ;按钮灵敏
CS1 EQU P2.0
CS2 EQU P2.1
WR_ON EQU P2.2
;-------------------------------
; 按钮
;-------------------------------
IN_SET EQU P2.3
IN_GAL EQU P2.4
IN_SUB EQU P2.5
;-------------------------------
; 主程序
;接口:D0-D7 接 P1.0-P1.7
; CS1 P2.0 CS2 P2.1 WR P2.2
;-------------------------------
ORG 0000H
JMP MAIN
ORG 000BH
JMP T0INT
ORG 0030H
MAIN:
CALL SYSINIT
;-------------------------------
START:
JMP START
;-------------------------------
; 计时器子程序
;-------------------------------
T0INT:
MOV TH0,#03CH
MOV TL0,#0AFH
CALL SHOW
DJNZ BUTTON4,T0INT1
MOV BUTTON4,#10
CALL AJ1
CALL AJ3
CALL AJ5
T0INT1:
DJNZ TIMER,T0INTEND
CALL MODE_PD1
T0INTEND:
RETI
;-------------------------------
; 模式判断
;-------------------------------
MODE_PD1:
MOV A,MODE
CJNE A,#0,MODE_PD2
MOV TIMER,#200
CALL CADD
JMP MODE_PDEND
MODE_PD2:
MOV A,MODE
CJNE A,#1,MODE_PD3
MOV TIMER,#50
CALL FLASH1
JMP MODE_PDEND
MODE_PD3:
MOV A,MODE
CJNE A,#2,MODE_PD4
MOV TIMER,#50
CALL FLASH3
JMP MODE_PDEND
MODE_PD4:
MOV A,MODE
CJNE A,#3,MODE_PDEND
MOV TIMER,#50
CALL FLASH5
MODE_PDEND:
RET
;-------------------------------
; 按钮
;-------------------------------
AJ1:
MOV A,BUTTON1
CJNE A,#1,AJ2
JB IN_SET,AJEND
MOV BUTTON1,#0
CALL SAVE2
MOV TIMER,#1
INC MODE
MOV A,MODE
CJNE A,#4,AJEND
MOV MODE,#0
MOV TIMER,#100
JMP AJEND
AJ2:
MOV A,BUTTON1
CJNE A,#0,AJ1
JNB IN_SET,AJEND
MOV BUTTON1,#1
JMP AJEND
AJ3:
MOV A,BUTTON2
CJNE A,#1,AJ4
JB IN_GAL,AJEND
MOV BUTTON2,#0
CALL GAL1
JMP AJEND
AJ4:
MOV A,BUTTON2
CJNE A,#0,AJ3
JNB IN_GAL,AJEND
MOV BUTTON2,#1
JMP AJEND
AJ5:
MOV A,BUTTON3
CJNE A,#1,AJ6
JB IN_SUB,AJEND
MOV BUTTON3,#0
CALL SUB1
JMP AJEND
AJ6:
MOV A,BUTTON3
CJNE A,#0,AJ5
JNB IN_SUB,AJEND
MOV BUTTON3,#1
JMP AJEND
AJEND:
RET
;-------------------------------
; 加法
;-------------------------------
GAL1:
MOV A,MODE
CJNE A,#3,GAL2
INC 58H
MOV A,58H
CJNE A,#10,GALEND
MOV 58H,#0
INC 57H
MOV A,57H
CJNE A,#6,GALEND
MOV 57H,#0
GAL2:
MOV A,MODE
CJNE A,#2,GAL3
INC 55H
MOV A,55H
CJNE A,#10,GALEND
MOV 55H,#0
INC 54H
MOV A,54H
CJNE A,#6,GALEND
MOV 54H,#0
GAL3:
MOV A,MODE
CJNE A,#1,GALEND
INC 52H
MOV A,52H
CJNE A,#10,GAL32
MOV 52H,#0
INC 51H
GAL32:
CJNE A,#4,GALEND
MOV A,51H
CJNE A,#2,GALEND
MOV 52H,#0
MOV 51H,#0
GALEND:
CALL SAVE2
RET
;-------------------------------
; 减法
;-------------------------------
SUB1:
MOV A,MODE
CJNE A,#3,SUB2
DEC 58H
MOV A,58H
CJNE A,#-1,SUBEND
MOV 58H,#9
DEC 57H
MOV A,57H
CJNE A,#-1,SUBEND
MOV 57H,#5
SUB2:
MOV A,MODE
CJNE A,#2,SUB3
DEC 55H
MOV A,55H
CJNE A,#-1,SUBEND
MOV 55H,#9
DEC 54H
MOV A,54H
CJNE A,#-1,SUBEND
MOV 54H,#5
SUB3:
MOV A,MODE
CJNE A,#1,SUBEND
DEC 52H
MOV A,52H
CJNE A,#-1,SUBEND
MOV 52H,#9
DEC 51H
MOV A,51H
CJNE A,#-1,GALEND
MOV 52H,#3
MOV 51H,#2
SUBEND:
CALL SAVE2
RET
;-------------------------------
; 闪烁
;-------------------------------
FLASH1:
MOV A,FLASH
CJNE A,#0,FLASH2
MOV 51H,LED_1
MOV 52H,LED_2
MOV LED_1,#11
MOV LED_2,#11
MOV FLASH,#1
JMP FLASHEND
FLASH2:
MOV A,FLASH
CJNE A,#1,FLASHEND
MOV LED_1,51H
MOV LED_2,52H
MOV FLASH,#0
JMP FLASHEND ;小时闪烁
FLASH3:
MOV A,FLASH
CJNE A,#0,FLASH4
MOV 54H,LED_4
MOV 55H,LED_5
MOV LED_4,#11
MOV LED_5,#11
MOV FLASH,#1
JMP FLASHEND
FLASH4:
MOV A,FLASH
CJNE A,#1,FLASHEND
MOV LED_4,54H
MOV LED_5,55H
MOV FLASH,#0
JMP FLASHEND ;分钟闪烁
FLASH5:
MOV A,FLASH
CJNE A,#0,FLASH6
MOV 57H,LED_7
MOV 58H,LED_8
MOV LED_7,#11
MOV LED_8,#11
MOV FLASH,#1
JMP FLASHEND
FLASH6:
MOV A,FLASH
CJNE A,#1,FLASHEND
MOV LED_7,57H
MOV LED_8,58H
MOV FLASH,#0 ;秒钟闪烁
FLASHEND:
RET
;-------------------------------
; 数据加减
;-------------------------------
CADD:
INC LED_8
MOV A,LED_8
CJNE A,#10,CADDEND
MOV LED_8,#0
INC LED_7
MOV A,LED_7
CJNE A,#6,CADDEND
MOV LED_7,#0
INC LED_5
MOV A,LED_5
CJNE A,#10,CADDEND
MOV LED_5,#0
INC LED_4
MOV A,LED_4
CJNE A,#6,CADDEND
MOV LED_4,#0
INC LED_2
MOV A,LED_2
CJNE A,#10,CADD2
MOV LED_2,#0
INC LED_1
CADD2:
CJNE A,#4,CADDEND
MOV A,LED_1
CJNE A,#2,CADDEND
CALL SYSINIT
CADDEND:
CALL SAVE1
RET
;-------------------------------
; 数据显示
;-------------------------------
SHOW:
MOV R0,#30H
MOV R1,#8
MOV R2,#01111111B
SHOW1:
MOV A,R2
MOV P0,A
CALL CS2_ON
RR A
MOV R2,A
MOV A,@R0
MOVC A,@A+DPTR
MOV P0,A
CALL CS1_ON
CALL DELAY
MOV P0,#0FFH
CALL CS1_ON
CALL CS2_ON
INC R0
DJNZ R1,SHOW1
RET
CS1_ON:
CLR WR_ON
CLR CS1
SETB WR_ON
SETB CS1
RET
CS2_ON:
CLR WR_ON
CLR CS2
SETB WR_ON
SETB CS2
RET
;-------------------------------
; 数据储存
;-------------------------------
SAVE1:
MOV 51H,LED_1
MOV 52H,LED_2
MOV 54H,LED_4
MOV 55H,LED_5
MOV 57H,LED_7
MOV 58H,LED_8
RET
SAVE2:
MOV LED_1,51H
MOV LED_2,52H
MOV LED_4,54H
MOV LED_5,55H
MOV LED_7,57H
MOV LED_8,58H
RET
;-------------------------------
; 数据初始化
;-------------------------------
SYSINIT:
MOV LED_1,#0
MOV LED_2,#0
MOV LED_3,#10
MOV LED_4,#0
MOV LED_5,#0
MOV LED_6,#10
MOV LED_7,#0
MOV LED_8,#0
CALL SAVE1
MOV TIMER,#200
MOV MODE,#0
MOV FLASH,#0
MOV BUTTON1,#1
MOV BUTTON2,#1
MOV BUTTON3,#1
MOV BUTTON4,#3
MOV TH0,#03CH
MOV TL0,#0AFH
SETB TR0
SETB ET0
SETB EA
MOV DPTR,#TAB
RET
;-------------------------------
; 延迟
;-------------------------------
DELAY:
MOV R6,#255
DJNZ R6,$
RET
;-------------------------------
; 段码
;-------------------------------
TAB:
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0BFH,0FFH
;0- "0"
;1- "1"
;2- "2"
;...
;9- "9"
;10-"-"
;11-" "
END

  • 利用AT89C51单片机设计简易电子钟(六位),通过8位LED数码管实现时间显示...
    答:程序设计思路:1.利用单片机内部定时器作为计时器,调用timer函数;2、设计一套按键子程序;(3)设计一套数码显示管子程序。下列提供一套程序供参考。include<iom16v.h> include <macros.h> define uchar unsigned char define uint unsigned int const uchar table[10]={0x3f,0x06,0x5b,0x4f,0x6...
  • ...任务要求:利用AT89C51单片机设计简易电子钟(六位),通过6位共阴_百度...
    答:没有的话程序上省点脑筋)主按键就用INT0,我没用P0口是因为懒得加上拉电阻,高低电平暂时先设成低的,思路就是P2口片选,当INT0触发时,你可以用while循环兜住不让出去,第一次是片选前两位“时”,
  • 用AT89C51单片机设计一电子闹钟,C语言程序和仿真
    答:这个一个时钟的仿真效果,可以调整时间,同时具有闹钟功能
  • 以AT89C51单片机为核心,制作一个LCD显示的智能电子钟
    答:void init();void delay(uint);void time_display();void date_display();void control();void time();/*** 函数名称:lcd1602_CheckBusy()* 函数功能:状态查询***/void lcd1602_CheckBusy(){do{lcd1602_busy=1;lcd1602_rs=0;lcd1602_rw=1;lcd1602_e=0;lcd1602_e=1;}while(lcd1602_busy)...
  • AT89C51单片机设计独立按键,静态数码管电路,并编程实现按下Ki键,数码...
    答:一位共阳数码管接在P0口,为静态显示。P3口接有8个独立式按键,按键为K1~K8,按键8个按键中的任意一个,数码管则显示出按键编号。仿真图如下,这是按下K6时显示6。
  • 利用AT89C51单片机结合字符型LCD显示器设计一个简易的倒数计数器_百度...
    答:define INT8U unsigned char#define lcd_starthang 0b11000000 // 起始行 define lcd_ye 0XB8 // 页指令 define lcd_lie 0X40 // 列指令 define RW PD0 define DI PD1 define E PD2 define CS1 PD3 define CS2 PD4 define RST PD5#define lcd_...
  • 利用单片机AT89C51与ADC0808设计一个数字电压表,能够测量0~5V的直流电...
    答:为此,我们设计了数字电压表,此作品主要由A/D0808转换器和单片机AT89C51构成,A/D转换器在单片机的控制下完成对模拟信号的采集和转换功能,最后由数码管显示采集的电压值。此设计通过调试完全满足设计的指标要求。电路设计简单,设计制作方便有较强的实用性。关键词:ADC0808;单片机AT89C51;数字电压表Abstract: In this ...
  • 用单片机AT89C51制作电子秒表,需要用什么元器件。
    答:元件:89c51,四位共阴极数码管,非自锁按键,10K电阻,10uf电解电容,30pf瓷片电容,10k排阻,晶振 留个邮箱,我把Proteus仿真图发给你,以下是程序,临时写的,Proteus测试正常,不知道符不符合你的要求,你可以自己再稍作修改。用的是12M晶振 include<reg51.h> define uchar unsigned char define uint...
  • 基于AT89C51单片机的6位数码管显示的简易电子时钟设计
    答:include <reg52.h> include <intrins.h> define uchar unsigned char define uint unsigned int sbit ds1302_RST =P2^0;sbit ds1302_IO =P2^1;sbit ds1302_SCLK=P2^2;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit A1=P3^0;sbit A2=P3^1;sbit A3=P3^2;sbit A4=P3^3;sbit A5=P3^4;...
  • 基于AT89C51的电饭煲控制系统设计
    答:本设计主要由硬件电路设计和软件编程两大部分来实现, 以AT89C51单片机为核心,配备显示模块、定时信息等, 能通过数码管进行显示计时。备有按键,以便人工定时与修改当前时间。用户可以通过按键修改时间,以便达到用户所要实现的功能。软件采用汇编语言程序设计实现程序控制和定点时间显示。由于本系统采用了数码管...