基于51单片机电子钟闹钟数码管显示12-24时制proteus仿真+程序+设计报告+讲解视频
基于51单片机的电子钟系统设计实现了数码管显示时间、闹钟功能及12/24小时制切换。系统采用DS1302时钟芯片提供精准计时,通过独立按键实现时间设置(时分秒调整)、闹钟设定(默认00:01)和显示模式切换。12小时制下配有AM/PM指示灯显示。设计包含Proteus仿真(兼容多型号51单片机)、Keil开发环境下的C语言程序、详细设计报告及讲解视频。硬件电路由51单片机、数码管、蜂鸣器(闹铃功能
基于51单片机电子钟闹钟数码管显示12-24时制切换( proteus仿真+程序+设计报告+讲解视频)
仿真图proteus8.17(有低版本)
程序编译器:keil 4/keil 5
编程语言:C语言
设计编号:P22
1主要功能:
1、用 7 段数码管作为显示设备,设计时钟功能;
2、可以分别调校小时、分钟和秒,复位后时间为00:00:00,并可设置为24 或 12 小时格式;
3、可以有其他扩展功能。
扩展功能:
具有闹钟功能,可以通过按键设定闹钟时间,默认闹钟时间是00:01;
12/24小时制有对应的指示灯,上午下午具有指示灯显示。
主要硬件 51单片机 DS1302 数码管 独立按键 LED
(目前仅完全适配普中51-实验板234,其他普中开发板型号需要接线)

需注意仿真中51单片机芯片是兼容的,AT89C51,AT89C52是51单片机的具体型号,内核是一样的。相同的原理图里,无论stc还是at都一样,引脚功能都是一样的,程序是兼容的,芯片可以替换为STC89C52/STC89C51/AT89C52/AT89C51等51单片机芯片。
资料下载链接:
P系列单片机设计下载链接(复制到浏览器打开)
https://docs.qq.com/doc/DS2pPenNRaHB6SlR1
以下为本设计资料展示图:
2.实物图:
显示的时间是09:01:13

普中实验板上的指示灯说明

3.仿真设计
打开仿真工程,双击proteus中的单片机,选择hex文件路径,然后开始仿真。开始仿真后数码管显示时间00:00:00。时间逐秒递增。

显示时间的情况下,按下设置键进入设置模式,时钟闪烁表示当前正在设置时钟,再按下设置键进入分钟设置模式,分钟闪烁,再按下设置键进入秒钟设置模式,秒钟闪烁。设置完秒钟再按设置退出设置模式,数码管正常显示。
未进入设置状态下,按键+作为切换按键,切换显示12/24小时制。12小时制下具有灯光指示是上午还是下午,以此实现AM/PM只是。

按下功能切换按键显示闹钟时间。闹钟时间显示下按下设置键进入闹钟设置模式,时钟闪烁表示当前正在设置闹钟时钟,再按下设置键进入闹钟分钟设置模式,闹钟分钟闪烁,再按下设置键进入闹钟秒钟设置模式,闹钟秒钟闪烁。设置完秒钟再按设置退出设置模式,数码管正常显示闹钟时间。
闹钟时间到,蜂鸣器闹铃,蜂鸣器响持续6s。
4.程序代码
使用keil4或者keil5编译,代码有注释,可以结合视频理解代码含义。
#include "reg51.h" //此文件中定义了单片机的一些特殊功能寄存器
#include"ds1302.h"
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit beep=P2^5;//蜂鸣器
sbit led_clock=P2^0;
sbit led_data=P2^1;
sbit led_alarm=P2^6;
sbit key1=P3^0;//功能切换.时间/闹钟
sbit key2=P3^1;//选择时、分、秒(按第4次确认)
sbit key3=P3^2;//加
sbit key4=P3^3;//减
完整代码见文章下载链接
sbit smg1=P2^2; //74LS138
sbit smg2=P2^3;
sbit smg3=P2^4;
u8 mode=0;//模式。0时间1闹钟
u8 cixu=0;//设置模式。1时2分3秒
u16 time=0;//计时变量,1s
u8 beep_flag=0,beep_flag0=0;//蜂鸣器标志
u8 shi0=0,fen0=1,miao0=0;//闹钟
u8 code smgduan0[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//显示0~9,无小数点
u8 code smgduan1[11]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0x40};//显示0~9,有小数点
u8 flag=0;
void delay(u16 i)//延时
{
while(i--);
}
void display1()//显示时间
{
if((cixu==3)&& flag)
{
}
else
{
P0=0;smg3=0;smg2=0;smg1=0;P0=smgduan0[ds1302_time[0]%10];delay(50); //当前显示是时钟
P0=0;smg3=0;smg2=0;smg1=1;P0=smgduan0[ds1302_time[0]/10];delay(50);
}
P0=0;smg3=0;smg2=1;smg1=0;P0=0x40;delay(50);
if((cixu==2)&& flag)
{
}
else
{
P0=0;smg3=0;smg2=1;smg1=1;P0=smgduan0[ds1302_time[1]%10];delay(50); //当前显示是分钟
P0=0;smg3=1;smg2=0;smg1=0;P0=smgduan0[ds1302_time[1]/10];delay(50);
}
P0=0;smg3=1;smg2=0;smg1=1;P0=0x40;delay(50);
if((cixu==1)&& flag)
{
}
else
{
P0=0;smg3=1;smg2=1;smg1=0;P0=smgduan0[ds1302_time[2]%10];delay(50); //当前显示是秒钟
P0=0;smg3=1;smg2=1;smg1=1;P0=smgduan0[ds1302_time[2]/10];delay(50);
}
}
void display2()//显示日期
{
if((cixu==1)&& flag)
{
}
else
{
P0=0;smg3=1;smg2=1;smg1=1;P0=smgduan0[2];delay(50);
P0=0;smg3=1;smg2=1;smg1=0;P0=smgduan0[0];delay(50);
P0=0;smg3=1;smg2=0;smg1=1;P0=smgduan0[ds1302_time[6]/10];delay(50);//
P0=0;smg3=1;smg2=0;smg1=0;P0=smgduan1[ds1302_time[6]%10];delay(50);
}
if((cixu==2)&& flag)
{
}
else
{
P0=0;smg3=0;smg2=1;smg1=1;P0=smgduan0[ds1302_time[4]/10];delay(50); //当前显示是月份
P0=0;smg3=0;smg2=1;smg1=0;P0=smgduan1[ds1302_time[4]%10];delay(50);
}
if((cixu==3)&& flag)
{
}
else
{
P0=0;smg3=0;smg2=0;smg1=1;P0=smgduan0[ds1302_time[3]/10];delay(50); //当前显示是日期
P0=0;smg3=0;smg2=0;smg1=0;P0=smgduan0[ds1302_time[3]%10];delay(50);
}
}
void display3()//显示闹钟
{
if((cixu==1)&& flag)
{
}
else
{
P0=0;smg3=1;smg2=1;smg1=1;P0=smgduan0[shi0/10];delay(50); //当前显示是时钟
P0=0;smg3=1;smg2=1;smg1=0;P0=smgduan0[shi0%10];delay(50);
}
if((cixu==2)&& flag)
{
}
else
{
P0=0;smg3=1;smg2=0;smg1=0;P0=smgduan0[fen0/10];delay(50); //当前显示是分钟
P0=0;smg3=0;smg2=1;smg1=1;P0=smgduan0[fen0%10];delay(50);
}
if((cixu==3)&& flag)
{
}
else
{
P0=0;smg3=0;smg2=0;smg1=1;P0=smgduan0[miao0/10];delay(50); //当前显示是秒钟
P0=0;smg3=0;smg2=0;smg1=0;P0=smgduan0[miao0%10];delay(50);
}
}
/*******************************************************************************
* 函 数 名 : Timer0Init
* 函数功能 : 定时器0初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer0Init()
{
TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0Xfc; //给定时器赋初值,定时1ms
TL0=0X18;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
}
/*******************************************************************************
* 函 数 名 : MonthDays
* 函数功能 : 得到当月的天数
* 输 入 : 年月日
* 输 出 : 月份天数
*******************************************************************************/
int MonthDays(int year, int month) { //区分闰年大小月
int days;
if (month == 2) { // 二月份
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) { // 闰年2月29天,其他年份28天
days = 29;
} else {
days = 28;
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) { // 四、六、九、十一月份各30天
days = 30;
} else { // 其他月份各31天
days = 31;
}
return days;
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
uchar k=0;
Ds1302Init();
Timer0Init(); //定时器0初始化
beep=0;
mode=0;
while(1)
{
if(mode==0){
display1();//显示时间
led_clock=0; //对应的灯亮
led_data=1;
led_alarm=1;
}
if(mode==1){
display2();//显示日期
led_clock=1; //对应的灯亮
led_data=0;
led_alarm=1;
}
if(mode==2){
display3();//显示闹钟
led_clock=1; //对应的灯亮
led_data=1;
led_alarm=0;
}
if(!key1 &&(k!=1)) //功能切换
{
k=1;cixu=0;
if(mode<2)
mode++;
else
mode=0;
}
if(!key2 &&(k!=2))//选择
{
if(cixu<3)
cixu++;
else
cixu=0;
k=2;
}
if(!key3 &&(k!=3)) //加
{
k=3;
if(mode==0)//时间
{
switch(cixu)
{
case 1:
if(ds1302_time[2]<23)
ds1302_time[2]++;
Ds1302Init();
break;
case 2:
if(ds1302_time[1]<59)
ds1302_time[1]++;
Ds1302Init();
break;
case 3:
if(ds1302_time[0]<59)
ds1302_time[0]++;
Ds1302Init();
}
}
if(mode==1)//日期
{
switch(cixu)
{
case 1:
if(ds1302_time[6]<50)
ds1302_time[6]++;
Ds1302Init();
break;
case 2:
if(ds1302_time[4]<12)
ds1302_time[4]++;
Ds1302Init();
break;
case 3:
if(ds1302_time[3]<MonthDays((ds1302_time[6]+2000),ds1302_time[4]))
ds1302_time[3]++;
Ds1302Init();
}
}
if(mode==2)//闹钟
{
switch(cixu)
{
case 1:
if(shi0<23){
shi0++;
}else{
shi0=0;
}
break;
case 2:
if(fen0<59){
fen0++;
}else{
fen0=0;
}
break;
case 3:
if(miao0<59){
miao0++;
}else{
miao0=0;
}
}
}
}
if(!key4 &&(k!=4)) //减
{
k=4;
if(mode==0)//时间
{
switch(cixu)
{
case 1:
if(ds1302_time[2]>0)
ds1302_time[2]--;
Ds1302Init();
break;
case 2:
if(ds1302_time[1]>0)
ds1302_time[1]--;
Ds1302Init();
break;
case 3:
if(ds1302_time[0]>0)
ds1302_time[0]--;
Ds1302Init();
}
}
if(mode==1)//日期
{
switch(cixu)
{
case 1:
if(ds1302_time[6]>0)
ds1302_time[6]--;
Ds1302Init();
break;
case 2:
if(ds1302_time[4]>0)
ds1302_time[4]--;
Ds1302Init();
break;
case 3:
if(ds1302_time[3]>0)
ds1302_time[3]--;
Ds1302Init();
}
}
if(mode==2)//闹钟
{
switch(cixu)
{
case 1:
if(shi0>0){
shi0--;
}else{
shi0=23;
}
break;
case 2:
if(fen0>0){
fen0--;
}else{
fen0=59;
}
break;
case 3:
if(miao0>0){
miao0--;
}else{
miao0=59;
}
}
}
}
// if(!key5) //停止响铃
// {
// beep_flag=0;
// }
if(key1 && key2 && key3 && key4)//按键清零
k=0;
if((ds1302_time[2]==shi0)&&(ds1302_time[1]==fen0)&&(ds1302_time[0]<15))//判断响铃
{
beep_flag=1;
}else{
beep_flag=0;
}
}
}
5.设计报告
6138字设计报告,内容包括硬件设计、软件设计、软硬件框图、调试、结论等

6.设计资料内容清单&&下载链接
资料设计资料包括仿真,程序代码、讲解视频、功能要求、设计报告、软硬件设计框图等。

0、常见使用问题及解决方法–必读!!!!
1、程序
2、proteus仿真
3、功能要求
4、软硬件流程图
5、开题报告
6、设计报告
7、烧录工具
8、讲解视频
9、实物图
Altium Designer 安装破解
KEIL+proteus 单片机仿真设计教程
KEIL安装破解
Proteus元器件查找
Proteus安装
Proteus简易使用教程
单片机学习资料
相关数据手册
答辩技巧
设计报告常用描述
鼠标双击打开查找嘉盛单片机51 STM32单片机课程毕业设计.url
更多推荐



所有评论(0)