用keil和proteus设计单片机电子时钟

#用keil和proteus设计单片机电子时钟,要求4位八段数码管显示小时分钟,中间的作为秒闪烁,两个按键,一个递增小时一个递增分钟
#有偿谢谢各位大佬!keil文件和proteus连接图都要,满足要求一定会采纳的!

img

#include <reg51.h>

#define uchar unsigned char
#define uint unsigned int

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

sbit beep = P2 ^ 3;
sbit key1 = P3 ^ 2;
sbit key2 = P3 ^ 3;

uint time;
uchar second, minute, hour;

void delay(uint z)
{
    while (z--);
}

void init()
{
    TMOD = 0x01;
    TH0 = (65536 - 50000) / 256;
    TL0 = (65536 - 50000) % 256;
    ET0 = 1;
    EA = 1;
    TR0 = 1;
}

void interrupt_timer0() interrupt 1
{
    TH0 = (65536 - 50000) / 256;
    TL0 = (65536 - 50000) % 256;
    time++;
    if (time == 50)
    {
        time = 0;
        second++;
        if (second == 60)
        {
            second = 0;
            minute++;
            if (minute == 60)
            {
                minute = 0;
                hour++;
                if (hour == 24)
                {
                    hour = 0;
                }
            }
        }
    }
}

void main()
{
    init();
    while (1)
    {
        if (!key1)
        {
            delay(200);
            if (!key1)
            {
                hour++;
                if (hour == 24)
                {
                    hour = 0;
                }
                while (!key1)
                    ;
            }
        }
        if (!key2)
        {
            delay(200);
            if (!key2)
            {
                minute++;
                if (minute == 60)
                {
                    minute = 0;
                }
                while (!key2)
                    ;
            }
        }
        P1 = table[hour / 10];
        P0 = 0xfe;
        delay(5);
        P0 = 0xff;
        P1 = table[hour % 10];
        P0 = 0xfd;
        delay(5);
        P0 = 0xff;
        P1 = 0x80;
        P0 = 0xfb;
        delay(5);
        P0 = 0xff;
        P1 = table[minute / 10];
        P0 = 0xf7;
        delay(5);
        P0 = 0xff;
        P1 = table[minute % 10];
        P0 = 0xef;
        delay(5);
        P0 = 0xff;
        if (second % 2 == 0)
        {
            P1 = 0xff;
            P0 = 0xdf;
            delay(5);
            P0 = 0xff;
        }
    }
}

需要以下元件:

C51 单片机:AT89S52
八段数码管:5V
按键 K1K2:5V
外部晶振:5V
电阻:1KΩ

如何连接:

C51 单片机的 P0 口连接到八段数码管的段选端,P1 口连接到数码管的数值选择端。按键 K1 和 K2 分别连接到单片机的 P3.2P3.3 口。定时器的输入源选择为外部晶振。

仅供参考,望采纳,谢谢。

可参考该实例【基于单片机的电子时钟设计(keil+protues仿真,含代码及原理图)】,链接:https://blog.csdn.net/weixin_42194695/article/details/89765975

望采纳

#include<reg51.h>
#define uChar unsigned char
#define uInt unsigned int
uChar a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 
uChar b[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; 
uChar second=50,minute=59,hour=12,year=18,month=07,day=21,count;
sbit Key1 = P3^0; //计时停止
sbit Key2 = P3^1; //调位
sbit Key3 = P3^2; //加一 
sbit Key4 = P3^3; //切换  
sbit Buzzer=P1^1;
/*********************延迟函数********************/
void Delay(uInt t)
{
while(t)
{
t--;
}
}
/*********************时分秒显示函数*******************/ 
void Dispaly1(uChar second,uChar minute,uChar hour)
{
/*********************第一位数码管*********************/
P2=b[0];
P0=a[hour/10];
Delay(10);
/*********************第二位数码管*********************/
P2=b[1];
P0=a[hour%10];
Delay(10);
/*********************第三位数码管*********************/
P2=b[2]; 
P0=0x40; 
Delay(10);
/*********************第四位数码管*********************/
P2=b[3]; 
P0=a[minute/10]; 
Delay(10);
/*********************第五位数码管*********************/
P2=b[4];
P0=a[minute%10]; 
Delay(10);
/*********************第六位数码管*********************/
P2=b[5]; 
P0=0x40; 
Delay(10);
/*********************第七位数码管*********************/
P2=b[6]; 
P0=a[second/10]; 
Delay(10);
/*********************第八位数码管*********************/
P2=b[7];; 
P0=a[second%10]; 
Delay(10);
}
/*********************年月日显示函数********************/
void Dispaly2(uChar day,uChar month,uChar year)
{
P2=b[0];
P0=a[day/10];
Delay(10);

P2=b[1];
P0=a[day%10];
Delay(10);

P2=b[2]; 
P0=0x40; 
Delay(10);

P2=b[3]; 
P0=a[month/10]; 
Delay(10);

P2=b[4]; 
P0=a[month%10]; 
Delay(10);

P2=b[5]; 
P0=0x40; 
Delay(10);

P2=b[6]; 
P0=a[year/10]; 
Delay(10);

P2=b[7]; 
P0=a[year%10]; 
Delay(10);
}
/*********************时钟按键扫描函数*********************/
void Keyscan1()
{
static uChar i=0,j=0; 
if(Key1==0) 
{
Delay(10); //消抖 
if(Key1==0) 
while(!Key1); //等待按键弹
i++;
}
/*时钟暂停功能*/
if(i%2==1) 
{
TR0=0;/*如果是奇数次按键自然关闭定时器0*/
}
if(i%2==0)
{
TR0=1;/*如果是偶数次按键则打开定时器0*/ 
}
/*时钟调位和数值加一功能*/
if(Key2==0) 
{
Delay(10); 
if(Key2==0)
while(!Key2);
j++; 
}
if(j%4==1)
{
if(Key3==0)
{
Delay(10); 
if(Key3==0)
while(!Key3);
second++;
if(second==60)
second=0;
}
}
if(j%4==2)
{
if(Key3==0)
{
Delay(10); 
if(Key3==0)
while(!Key3);
minute++;
if(minute==60)
minute=0; 
}
}
if(j%4==3)
{
if(Key3==0)
{ 
Delay(10); 
if(Key3==0)
while(!Key3);
hour++;
if(hour==24)
hour=0; 
}
}
}
/*日期按键扫描函数*/
void Keyscan2()
{
static uChar m=0,n=0; 
if(Key1==0) 
{
Delay(10); 
if(Key1==0)
while(!Key3);
m++;
}
if(m%2==1) 
{
TR0=0;/*奇数次按键则关闭定时器0*/
}

if(m%2==0)
{
TR0=1;/*偶数次按键则打开定时器0*/ 
}
if(Key2==0) 
{
Delay(10); 
if(Key2==0)
while(!Key2);
n++; 
}
/*日期调位和日期加一功能*/
if(n%4==1)
{
if(Key3==0)
{
Delay(10); 
if(Key3==0)
while(!Key3);
day++;
if(day==30)
day=0;
}
}
if(n%4==2)
{
if(Key3==0)
{ 
Delay(10); 
if(Key3==0)
while(!Key3);
month++;
if(month==12)
month=0; 
}
}
if(n%4==3)
{
if(Key3==0)
{ 
Delay(10); 
if(Key3==0)
while(!Key3);
year++;
if(year==99)
year=0; 
}
}
}

/************************************************/
/***************主函数***************************/
/************************************************/
void main()
{                        
TMOD=0x01;      /*定时器以方式一工作*/
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;/*10ms计时*/
EA=1;
ET0=1;/*允许定时器0中断*/
TR0=1;/*打开定时器0*/
while(1)
{
static uChar h=0;
/*时钟和日期切换功能*/ 
if(Key4==0) 
{
Delay(10); 
if(Key4==0)
while(!Key4);
h++;
}
if(h%2==0)/*如果按键偶数次则显示时钟*/
{
Dispaly1(second,minute,hour);
Keyscan1(); 
}

if(h%2==1)/*如果按键奇数次则显示日期*/ 
{
Dispaly2(year,month,day);
Keyscan2();
}
}
}
/**********************中断函数**************************/
void time0_int(void) interrupt 1
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
count++;
if(count==100)/*10ms??ê±£???100′??ò??o?1s*/
{
count=0;
second++;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
{
hour=0;
day++;
if(day==30)
{
day=0;
month++;
if(month==12)
{
month=0;
year++;
if(year==99)
{
year=0;
}
}
}
}
}
}
}
/*判断整点提醒*/
if(second==00&&minute==00)                                   
Buzzer=0;
else
Buzzer=1;
}



建议你可以分为以下几个步骤来操作

1.使用 Keil 软件设计单片机程序。在这一步,你需要先设计单片机的硬件连接方式,然后编写单片机的程序代码。单片机程序中应该包含控制数码管显示小时分钟、秒闪烁、按键递增小时和分钟的代码。
2.使用 Proteus 软件设计电路连接图。在这一步,你需要根据单片机的硬件连接方式,使用 Proteus 软件设计出电路连接图。这一步应该包含连接数码管、按键等电路元件的设计。
3.将单片机程序烧写到单片机芯片中。在这一步,你需要使用单片机编程器将单片机程序烧写到单片机芯片中。
4.连接数码管、按键等电路元件。在这一步,你需要根据电路连接图连接数码管、按键等电路元件。
5.测试程序是否正常运行。在这一步,你需要测试单片机电子时钟的功能是否正常,并确保程序能够正常运行。

望采取,我这里还有课程设计,以及其他的电子时钟设计,有需要可以联系


/********时钟程序********/
/*功能描述*/
//6位数码管显示时分秒
/*******硬件配置*********/
//AT89C52 12M晶振



#include <REGX52.H>
//段选
#define smg_data    P0//定义数码管数据口

//数码管位选
//sbit    dis_bit1 = P2 ^ 5; //定义数码管控制口
//sbit    dis_bit2 = P2 ^ 4; //定义数码管控制口
//sbit    dis_bit3 = P2 ^ 3; //定义数码管控制口
//sbit    dis_bit4 = P2 ^ 2; //定义数码管控制口
//sbit    dis_bit5 = P2 ^ 1; //定义数码管控制口
//sbit    dis_bit6 = P2 ^ 0; //定义数码管控制口
#define smg_Pgs P2
//共阴数码管断码表
unsigned char code tabl1[16] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
                                0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71
                               };

typedef struct
{
    unsigned char Value;
    unsigned char State;
    unsigned char lastValue;
} KeyStruct;
enum KeyState {CheckKey,DelayKey,KeyFallEdge,KeyDown,KeyRisEdge};

                            
typedef struct
{
  unsigned char hour;
  unsigned char min;
  unsigned char sec;
  unsigned char  SetFlag; 
} Time;
//初始化时间
Time DateTime = {12, 0, 0};
//全局心跳时钟 10ms
unsigned char systemTick = 0;
unsigned char DipBuff[6];
void time0Init();
void Display();
//按键检测
unsigned char key_scan(KeyStruct* KeyNum);
void Control (unsigned char keyValue);
void main()
{
  KeyStruct key_SetTime;
  //硬件初始化
  time0Init();

  while (1)
  {
    Display();
    if (key_scan (&key_SetTime) == KeyFallEdge)
    {
      Control (key_SetTime.Value);
    }
  }
}
void Control (unsigned char keyValue)
{
  switch (keyValue)
  {
  case 0x01://设置按键
    DateTime.SetFlag++;
    DateTime.SetFlag = DateTime.SetFlag% 4;
    break;

  case 0x02://数值减
    switch (DateTime.SetFlag)
    {
    case 1:
      DateTime.sec = DateTime.sec > 0 ? --DateTime.sec : 59;
      break;

    case 2:
      DateTime.min = DateTime.min > 0 ? --DateTime.min : 59;
      break;

    case 3:
      DateTime.hour = DateTime.hour > 0 ? --DateTime.hour : 23;
      break;
    }

    break;

  case 0x04:
    switch (DateTime.SetFlag)
    {
    case 1:
      DateTime.sec++;
      DateTime.sec = DateTime.sec % 60;
      break;

    case 2:
      DateTime.min++;
      DateTime.min = DateTime.min% 60;
      break;

    case 3:
      DateTime.hour++;
      DateTime.hour = DateTime.hour % 24;
      break;
    }

    break;
  }
}
void Display()
{
  char i, j;
  DipBuff[0] = tabl1[DateTime.hour / 10 % 10];
  DipBuff[1] = tabl1[DateTime.hour % 10]|((DateTime.SetFlag ==3)?0x80:0x00 );
  DipBuff[2] = tabl1[DateTime.min / 10 % 10];
  DipBuff[3] = tabl1[DateTime.min % 10]|((DateTime.SetFlag ==2)?0x80:0x00 );
  DipBuff[4] = tabl1[DateTime.sec / 10 % 10];
  DipBuff[5] = tabl1[DateTime.sec % 10]|((DateTime.SetFlag ==1)?0x80:0x00 );

  for (i = 0; i < 6; i++)
  {
    smg_data = 0xff;
    smg_Pgs = ~ (0x01 << i);
    smg_data = DipBuff[i];

    j = 100;
    while (j--);
    smg_Pgs = 0xff;
  }

}



void delay2ms(void)   //延时函数
{
    unsigned char i,j;
    for(i=133; i>0; i--)
        for(j=6; j>0; j--);
}
sbit Key0=P1^0;
sbit Key1=P1^1;
sbit Key2=P1^2;
unsigned char IndependentKeyboard()
{
    unsigned char keyValue=0;
    keyValue |=!Key0;
    keyValue<<=1; 
    keyValue |=!Key1;
    keyValue<<=1;
    keyValue|=!Key2;
    return keyValue;
}
//按键检测
unsigned char key_scan(KeyStruct* KeyNum)
{
    unsigned char keyValue=0;
    unsigned char State=KeyNum->State;
    unsigned char KeyTemp=KeyNum->Value;
    /*******矩阵键盘读取操作******/
    keyValue =    IndependentKeyboard();//独立按键检测
    switch(State)
    {
    case CheckKey:
        if(keyValue !=0)
        {
            KeyTemp=keyValue;
            State=DelayKey;
        }
        break;
    case DelayKey:
        delay2ms();
        State= KeyTemp==keyValue ? KeyFallEdge:CheckKey;
        break;
    case KeyFallEdge:
        State=KeyDown;
        break;
    case KeyDown:
        if(KeyTemp != keyValue)
        {
            State=KeyRisEdge;
            KeyNum->lastValue= KeyTemp;
        }
        break;
    case KeyRisEdge:
        State=CheckKey;
        break;
    default:
        break;
    }
    KeyNum->State=State;
    KeyNum->Value=keyValue;
    return State;
}

void time0Init()
{
  TR0 = 0; //关定时器
  TF0 = 0;
  TMOD = TMOD & 0xf0 | 0x01; //设定T0定时器工作模式1
  TH0 = (-10000) >> 8;
  TL0 = (-10000) & 0xff;
  ET0 = 1;  //开中断
  EA = 1; //开总中断
  TR0 = 1; //开定时器
}

void t0() interrupt 1
{
  //定时重载
  TH0 = (-10000) >> 8;
  TL0 = (-10000) & 0xff;
  systemTick++;

  if (systemTick > 99)
  {
    systemTick = 0;
    DateTime.sec++;

    if (DateTime.sec > 59)
    {
      DateTime.sec = 0;
      DateTime.min++;

      if (DateTime.min > 59)
      {
        DateTime.min = 0;
        DateTime.hour++;
      }
    }
  }
}

img