#用keil和proteus设计单片机电子时钟,要求4位八段数码管显示小时分钟,中间的作为秒闪烁,两个按键,一个递增小时一个递增分钟
#有偿谢谢各位大佬!keil文件和proteus连接图都要,满足要求一定会采纳的!
#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
按键 K1 和 K2:5V
外部晶振:5V
电阻:1KΩ
如何连接:
C51 单片机的 P0 口连接到八段数码管的段选端,P1 口连接到数码管的数值选择端。按键 K1 和 K2 分别连接到单片机的 P3.2 和 P3.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++;
}
}
}
}