本设计是基于51单片机的LCD1602电子钟闹钟proteus仿真设计
源码+仿真+原理图+器件清单
仿真软件版本:proteus 7.8
程序编译器:keil 4/keil 5
编程语言:C语言
编号C0001
资料文件下载链接:
https://docs.qq.com/doc/DS1N1VEpDc2JHUlVx
功能介绍:
(1) 可由按键调整时间
(2) 可整点报时(“嘟、嘟”声)
(3) 可设定时,定时时间到发出“嘟、嘟”声
仿真图:
原理图(提供源文件):
程序:
main.c
#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);
}
}
}
}
}
/*********************************************************
函数名称:TIMER0
函数作用:定时器0中断
输入变量:无
返回值: 无
***********************************************************/
void TIMER0() interrupt 1 //定时器0中断
{
TH0=0XfC; //定时1ms
TL0=0X18;
if(timer<1000) //定时1s
timer++;
else
{
timer=0;
if(((shi==buzzr_shi)&&(fen==buzzr_fen))||(fen==0)) //判断是否到达闹钟时间
{
beep=!beep;//蜂鸣器每隔1s响一次
}
else
beep=1;//关闭蜂鸣器
if(moshi==0) //模式0,正常计时
{
if(miao<59) //秒计时
miao++;
else
{
miao=0;
if(fen<59) //分计时
fen++;
else
{
fen=0;
if(shi<23) //小时计时
shi++;
else
shi=0;
}
}
time[0]=shi/10+0x30; //把shi/fen/miao计算到显存,用于显示
time[1]=shi%10+0x30;
time[3]=fen/10+0x30;
time[4]=fen%10+0x30;
time[6]=miao/10+0x30;
time[7]=miao%10+0x30;
write_string(1,5,time);//显示时间
}
}
}
器件清单:
资料清单:
阅读全文