基于51单片机电子钟闹钟设计
(仿真+程序+原理图)
功能介绍
具体功能:
1.LCD1602实时显示时间和闹钟时间;
2.可整点报时。
3.按键设置时间、闹钟。
4.使用蜂鸣器报时和响闹钟;
演示视频:
基于51单片机电子钟闹钟—LCD1602显示
#include <reg51.h>
#include <lcd1602.h>
/***********************引脚定义************************/
sbit K1=P2^3; //切换。=1调整时间、=2调整闹钟、=0正常运行
sbit K2=P2^4; //下一个
sbit K3=P2^5; //加一
sbit K4=P2^6; //减一
sbit beep=P2^7; //蜂鸣器
/***********************变量定义************************/
unsigned char moshi=0; //用来指示当前处在哪个功能状态
unsigned int timer=0; //系统定时变量
unsigned char miao=0,fen=10,shi=6; //初始时间
unsigned char buzzr_fen=12,buzzr_shi=6; //闹钟时间
unsigned char two=0; //指示每个功能下对应的时间
unsigned char time[]={"06:10:10"}; //当前时间显示空间
unsigned char buzzr[]={"06:12"}; //闹钟缓存
/*********************************************************
函数名称:delay
函数作用:延时函数
输入变量:unsigned int i延时时间
返回值: 无
***********************************************************/
void delay(unsigned int i) //延时单位为10us
{
while(i--);
}
/*********************************************************
函数名称:main
函数作用:主函数
输入变量:无
返回值: 无
***********************************************************/
void main()
{
TMOD|=0X01; //T0工作方式1
TH0=0XfC; //设置初值1ms
TL0=0X18;
ET0=1; //打开定时器0中断允许
EA=1; //打开总中断
TR0=1; //打开定时器
init_1602(); //LCD1602初始化
write_string(1,0,"TIME:");
write_string(2,0,"CLOCK:");
write_string(1,5,time); //显示初始时间
write_string(2,6,buzzr); //显示闹钟时间
write_com(0x0c); //关闭光标
while(1) //主循环
{
if(!K1) //按钮1功能切换
{
delay(10000); //延时防抖
if(!K1)
{
two=0; //功能时间指示变量清零
if(moshi<2) //模式切换
moshi++;
else
moshi=0;
switch(moshi) //设置光标位置
{
case 0: write_com(0x0c);//正常模式,关闭光标
break;
case 1: write_com(0x0e);//模式1,打开光标
write_sfm(1,6); //设置光标位置
break;
case 2: write_com(0x0e);//模式2,打开光标
write_sfm(2,6); //设置光标位置
}
}
while(!K1); //等待按钮松开
}
if(moshi==1) //模式1,调整时间
{
if(!K2) //下一个
{
delay(10000); //延时防抖
if(!K2)
{
if(two<2)
two++;
else
two=0;
}
if(two==0) //光标设置在小时位置
{
write_com(0x0e);
write_sfm(1,6);
}
if(two==1) //光标设置在分钟位置
{
write_com(0x0e);
write_sfm(1,9);
}
if(two==2) //光标设置在秒位置
{
write_com(0x0e);
write_sfm(1,12);
}
while(!K2); //等待按钮松开
}
if(two==0)
{
if(!K3) //小时加一
{
delay(10000); //延时防抖
if(!K3)
{
if(shi<23) //限制小时最大值为23
shi++; //小时加一
else
shi=0;
}
time[0]=shi/10+0x30;//计算
time[1]=shi%10+0x30;
write_string(1,5,time);//显示
write_sfm(1,6); //保持光标位置
while(!K3);
}
if(!K4) //小时减一
{
delay(10000); //延时防抖
if(!K4)
{
if(shi>0)
shi--;
else
shi=23;
}
time[0]=shi/10+0x30;//计算
time[1]=shi%10+0x30;
write_string(1,5,time);//显示
write_sfm(1,6);
while(!K4);
}
}
if(two==1)
{
if(!K3) //分钟加一
{
delay(10000); //延时防抖
if(!K3)
{
if(fen<59) //限制分钟最大值为59
fen++;
else
fen=0;
}
time[3]=fen/10+0x30;//计算
time[4]=fen%10+0x30;
write_string(1,5,time);//显示
write_sfm(1,9);
while(!K3);
}
if(!K4) //分钟减一
{
delay(10000); //延时防抖
if(!K4)
{
if(fen>0)
fen--;
else
fen=59;
}
time[3]=fen/10+0x30;//计算
time[4]=fen%10+0x30;
write_string(1,5,time);//显示
write_sfm(1,9);
while(!K4);
}
}
if(two==2)
{
if(!K3) //秒加一
{
delay(10000); //延时防抖
if(!K3)
{
if(miao<59) //限制分钟最大值为59
miao++;
else
miao=0;
}
time[3]=miao/10+0x30;//计算
time[4]=miao%10+0x30;
write_string(1,5,time);//显示
write_sfm(1,9);
while(!K3);
}
if(!K4) //秒减一
{
delay(10000); //延时防抖
if(!K4)
{
if(miao>0)
miao--;
else
miao=59;
}
time[3]=miao/10+0x30;//计算
time[4]=miao%10+0x30;
write_string(1,5,time);//显示
write_sfm(1,9);
while(!K4);
}
}
}
if(moshi==2) //模式2,调整闹钟
{
if(!K2) //下一个
{
delay(10000); //延时防抖
if(!K2)
{
two=!two; //切换次序
}
if(two==0) //光标设置在小时
{
write_com(0x0e); //开启光标
write_sfm(2,6);
}
else //光标设置在分钟
{
write_com(0x0e); //开启光标
write_sfm(2,9);
}
while(!K2);
}
if(two==0)
{
if(!K3) //小时加一
{
delay(10000); //延时防抖
if(!K3)
{
if(buzzr_shi<23)//限制小时最大值为23
buzzr_shi++;
else
buzzr_shi=0;
}
buzzr[0]=buzzr_shi/10+0x30;//计算
buzzr[1]=buzzr_shi%10+0x30;
write_string(2,6,buzzr);//显示
write_sfm(2,6);
while(!K3);
}
if(!K4) //小时减一
{
delay(10000); //延时防抖
if(!K4)
{
if(buzzr_shi>0)
buzzr_shi--;
else
buzzr_shi=23;
}
buzzr[0]=buzzr_shi/10+0x30;//计算
buzzr[1]=buzzr_shi%10+0x30;
write_string(2,6,buzzr); //显示
write_sfm(2,6);
while(!K4);
}
}
else
{
if(!K3) //分钟加一
{
delay(10000); //延时防抖
if(!K3)
{
if(buzzr_fen<59)//限制分钟最大值为59
buzzr_fen++;
else
buzzr_fen=0;
}
buzzr[3]=buzzr_fen/10+0x30;//计算
buzzr[4]=buzzr_fen%10+0x30;
write_string(2,6,buzzr);//显示
write_sfm(2,9); //保持光标位置
while(!K3);
}
if(!K4) //分钟减一
{
delay(10000); //延时防抖
if(!K4)
{
if(buzzr_fen>0)
buzzr_fen--;
else
buzzr_fen=59;
}
buzzr[3]=buzzr_fen/10+0x30;//计算
buzzr[4]=buzzr_fen%10+0x30;
write_string(2,6,buzzr);//显示
write_sfm(2,9);
while(!K4);
}
}
}
}
硬件设计
使用元器件:
单片机:AT89C51;
(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)
电容:10uf;电容:30pf;
晶振:12MHZ;按键 ;
电阻:10k;电阻:1k;
三极管:PNP;蜂鸣器:有源;
显示器:LCD1602;排阻:10k;
导线若干;
流程图
设计资料
01 仿真图
本设计使用proteus7.8和proteus8.9两个版本设计,向下兼容,无需担心!具体如图!
02 原理图
本系统原理图采用Altium Designer19设计,具体如图!
03 程序
本设计使用软件keil4和keil5两个版本编程设计,无需担心!具体如图!
04 设计资料
资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)、AD原理图、元件清单、仿真视频等。具体内容如下,全网最全! !
资料获取请观看前面演示视频!
点赞分享一起学习成长。