点击这里找小助理0元领取:扫码进群领资料
一、项目功能
1、可以显示当前韶光、星期、日期2、可以修合法前韶光、星期、日期3、可以获取环境的温度,并显示到LCD4、可以设置闹钟,当时间到蜂鸣器鸣叫、按下按键后关闭鸣叫
(一)主控选择:STC89C52RCSTC89C52是一种低功耗、高性能CMOS8位微掌握器,具有8K在系统可编程Flash存储器。在单芯片上,拥有机动的8位CPU和在系统可编程Flash,使得STC89C52为浩瀚嵌入式掌握运用系统供应高灵巧、超有效的办理方案。

(二)显示屏选择:LCD1602LCD1602液晶显示器是广泛利用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、掌握驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和构造件等装置在PCB板上而组成。不同厂家生产的LCD1602芯片可能有所不同,但利用方法都是一样的。为了降落本钱,绝大多数制造商都直接将裸片做到板子上。
(三)时钟芯片选择:DS1302DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,并且具有闰年补偿等多种功能。
(四)温度传感器选择:DS18B20DS18B20是常用的数字温度传感器,其输出的是数字旗子暗记,具有体积小,硬件开销低,抗滋扰能力强,精度高的特点。 [1] DS18B20数字温度传感器接线方便,封装成后可运用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。
(五)外围器件:按键、蜂鸣器、开关、纽扣电池、电位器、三极管等
三、事理图设计(一)最小系统供电、晶振、复位电路
(二)显示屏电路数据线接到P0,把稳要接1K上拉电阻
四、PCB设计
五、程序设计
/项目:51单片机时钟万年历设计作者:化作尘版本:V1.1邮箱:2809786963@qq.com韶光:2020年12月1日16:43:51哔哩哔哩视频地址:https://www.bilibili.com/video/BV1VQ4y1M79K把稳事变:闹钟根据实物设计,不能仿真,利用的是内部eeprom/#include "reg52.h" //此文件中定义了单片机的一些分外功能寄存器#include "ds1302.h"#include "temp.h"#include "lcd.h"#include "eeprom.h"sbit k1 = P1^0; //按键sbit k2 = P1^1; sbit k3 = P1^2;sbit k4 = P1^3;sbit lcdled = P2^4; //lcd背光sbit beep = P1^4;//蜂鸣器unsigned int ti=0,alarm=0; //修正第几个韶光参数 、修正第几个闹钟参数unsigned char alarm_hour=0x12,alarm_min=0x00; //闹钟时、分参数enum Mode//定义列举、三种模式{DISPLAYDATA,MODIFYDATA,SETALARMCLOCK,NONE,ALARMCLOCK}mode;enum Alarmswitch //定义闹钟开关{OFF,ON}alarmswitch;/延时函数/ void delay(unsigned int t) //短延时{ while(t--);}void delay_ms(unsigned int t)//毫秒延时{unsigned int a,b;for(a=0;a<t;a++)for(b=0;b<120;b++);}/显示日期、韶光、星期/void display_data(void){LcdWriteCom(0x80);LcdWritestr("20");LcdWriteData(TIME[6]/16+0x30); //年LcdWriteData(TIME[6]%16+0x30);LcdWriteData('-');LcdWriteData(TIME[4]/16+0x30); //月LcdWriteData(TIME[4]%16+0x30);LcdWriteData('-');LcdWriteData(TIME[3]/16+0x30); //日LcdWriteData(TIME[3]%16+0x30);LcdWritestr(" ");switch(TIME[5]) //显示星期{case 0:LcdWritestr("Mon"); break;case 1:LcdWritestr("Tue"); break;case 2:LcdWritestr("Wed"); break;case 3:LcdWritestr("Thu"); break;case 4:LcdWritestr("Fri"); break;case 5:LcdWritestr("Sat"); break;case 6:LcdWritestr("Sun"); break;}if(alarmswitch==ON)LcdWriteData('.');else LcdWriteData(' ');LcdWriteCom(0xC0);LcdWriteData(' ');LcdWriteData(TIME[2]/16+0x30); //时LcdWriteData(TIME[2]%16+0x30);LcdWriteData(':');LcdWriteData(TIME[1]/16+0x30); //分LcdWriteData(TIME[1]%16+0x30);LcdWriteData(':');LcdWriteData(TIME[0]/16+0x30); //秒LcdWriteData(TIME[0]%16+0x30);LcdWritestr(" ");}/显示温度/void displaytemp(int temp) //显示温度{ float tp; static char flag = 1;if(temp< 0) {LcdWriteCom(0xca);LcdWriteData('-'); temp=temp-1;temp=~temp;tp=temp;temp=tp0.0625100+0.5; } else {LcdWriteCom(0xca);LcdWriteData('+'); tp=temp;temp=tp0.0625100+0.5;}if(flag){flag =0;temp = 2600;}if(temp==8500)return ;LcdWriteData(temp % 10000 / 1000 + 0x30);LcdWriteData(temp % 1000 / 100 + 0x30);LcdWriteData('.');LcdWriteData(temp % 100 / 10 + 0x30);LcdWriteData(temp % 10 + 0x30);}/ 函 数 名 : keypros 函数功能 : 按键处理函数,判断按键K1是否按下/void keypros() //初始页面按键检测{if(k1 == 0) //切换模式{delay(1000); //肃清抖动 一样平常大约10msif(k1==0) //再次判断按键是否按下{mode+= 1;if(mode == 3)mode = DISPLAYDATA;}while(k1 == 0);}else if(k2 == 0) //蜂鸣器测试{delay(1000); //肃清抖动 一样平常大约10msif(k2==0) //再次判断按键是否按下{beep = !beep; }while(k2 == 0);}else if(k3 == 0) //背光灯测试{delay(1000); //肃清抖动 一样平常大约10msif(k3==0) //再次判断按键是否按下{lcdled = !lcdled; }while(k3 == 0);}else if(k4 == 0)//背光灯测试{delay(1000); //肃清抖动 一样平常大约10msif(k4==0) //再次判断按键是否按下{alarmswitch=!alarmswitch; }while(k4 == 0);}}/修正韶光/void modify(void){static int time=0;time++;if(k1 == 0)//切换模式{delay(1000); //肃清抖动 一样平常大约10msif(k1==0) //再次判断按键是否按下{mode+= 1;if(mode == 3)mode = DISPLAYDATA;}while(k1 == 0);}else if(k2 == 0) //选择修正参数{delay(1000); //肃清抖动 一样平常大约10msif(k2==0) //再次判断按键是否按下{ti++; if(ti == 8)ti=0; }while(k2 == 0);}else if(k3 == 0 ||k4 == 0)switch(ti) //选择进入修正参数{case 0:if(k4==0 | k3==0){delay(1000); //肃清抖动 一样平常大约10msif(k4==0 | k3 ==0) //再次判断按键是否按下{ TIME[0]=0;}while(k4 == 0 | k3==0);}break; //?case 1:if(k3==0){delay(1000); //肃清抖动 一样平常大约10msif(k3 ==0) //再次判断按键是否按下{ TIME[1]++; if(TIME[1]%16 == 0x0a) { TIME[1] += 16;TIME[1] &= 0xf0; }if(TIME[1]==0x60)TIME[1]=0;}while(k3==0);}if(k4==0){delay(1000); //肃清抖动 一样平常大约10msif(k4 ==0) //再次判断按键是否按下{ TIME[1]--; if(TIME[1]%16==0x0f && TIME[1]!=0xff) {TIME[1] &= 0xf9; } if(TIME[1]==0xff)TIME[1]=0x59;}while(k4==0);}break; //?case 2:if(k3==0){delay(1000); //肃清抖动 一样平常大约10msif(k3 ==0) //再次判断按键是否按下{ TIME[2]++; if(TIME[2]%16 == 0x0a) { TIME[2] += 16;TIME[2] &= 0xf0; }if(TIME[2]==0x24)TIME[2]=0;}while(k3==0);}if(k4==0){delay(1000); //肃清抖动 一样平常大约10msif(k4 ==0) //再次判断按键是否按下{ TIME[2]--; if(TIME[2]%16==0x0f && TIME[2]!=0xff) {TIME[2] &= 0xf9; } if(TIME[2]==0xff)TIME[2]=0x23;}while(k4==0);}break; //?case 3:if(k3==0){delay(1000); //肃清抖动 一样平常大约10msif(k3 ==0) //再次判断按键是否按下{ TIME[3]++; if(TIME[3]%16 == 0x0a) { TIME[3] += 16;TIME[3] &= 0xf0; }if(TIME[3]==0x32)TIME[3]=0;}while(k3==0);}if(k4==0){delay(1000); //肃清抖动 一样平常大约10msif(k4 ==0) //再次判断按键是否按下{ TIME[3]--; if(TIME[3]%16==0x0f && TIME[3]!=0xff) {TIME[3] &= 0xf9; } if(TIME[3]==0xff)TIME[3]=0x31;}while(k4==0);}break; //日case 4:if(k3==0){delay(1000); //肃清抖动 一样平常大约10msif(k3 ==0) //再次判断按键是否按下{ TIME[4]++; if(TIME[4]%16 == 0x0a) { TIME[4] += 16;TIME[4] &= 0xf0; }if(TIME[4]==0x13)TIME[4]=0;}while(k3==0);}if(k4==0){delay(1000); //肃清抖动 一样平常大约10msif(k4 ==0) //再次判断按键是否按下{ TIME[4]--; if(TIME[4]%16==0x0f && TIME[4]!=0xff) {TIME[4] &= 0xf9; } if(TIME[4]==0xff)TIME[4]=0x12;}while(k4==0);}break; //月case 5:if(k3==0){delay(1000); //肃清抖动 一样平常大约10msif(k3 ==0) //再次判断按键是否按下{ TIME[5]++;if(TIME[5]==7)TIME[5]=0;}while(k3==0);}if(k4==0){delay(1000); //肃清抖动 一样平常大约10msif(k4 ==0) //再次判断按键是否按下{ TIME[5]--;if(TIME[5]==0xff)TIME[5]=6;}while(k4==0);}break; //周case 6:if(k3==0){delay(1000); //肃清抖动 一样平常大约10msif(k3 ==0) //再次判断按键是否按下{ TIME[6]++; if(TIME[6]%16 == 0x0a) { TIME[6] += 16;TIME[6] &= 0xf0; }if(TIME[6]==0xa0)TIME[6]=0;}while(k3==0);}if(k4==0){delay(1000); //肃清抖动 一样平常大约10msif(k4 ==0) //再次判断按键是否按下{ TIME[6]--; if(TIME[6]%16==0x0f && TIME[6]!=0xff) {TIME[6] &= 0xf9; } if(TIME[6]==0xff)TIME[6]=0x99;}while(k4==0);}break; //年case 7: if(k3==0){delay(1000); //肃清抖动 一样平常大约10msif(k3 ==0) //再次判断按键是否按下{ mode=DISPLAYDATA; ti=0;}while(k3==0);}if(k4==0){delay(1000); //肃清抖动 一样平常大约10msif(k4 ==0) //再次判断按键是否按下{ Ds1302Init(); //时钟初始化mode = DISPLAYDATA; //返回日期ti = 0;//还原初始修正}while(k4==0);}break; //年}if(time == 200){display_data();if(ti == 7){LcdWriteCom(0xca);LcdWritestr(" <- OK");}}else if(time == 400)switch(ti) //选择进入修正参数{case 0: LcdWriteCom(0xc7);LcdWritestr(" ");break;case 1: LcdWriteCom(0xc4);LcdWritestr(" ");break;case 2: LcdWriteCom(0xc1);LcdWritestr(" ");break;case 3: LcdWriteCom(0x88);LcdWritestr(" ");break;case 4: LcdWriteCom(0x85);LcdWritestr(" ");break;case 5: LcdWriteCom(0x8c);LcdWritestr(" ");break;case 6: LcdWriteCom(0x80);LcdWritestr(" ");break;case 7: LcdWriteCom(0xca);LcdWritestr(" ");break;}else if(time>400) time=0;delay_ms(1);}void setalarmclock(void)//设置闹钟模式{static int time=0;time++;if(k1 == 0) //切换模式{delay(1000); //肃清抖动 一样平常大约10msif(k1==0) //再次判断按键是否按下{mode+= 1;if(mode == 3)mode = DISPLAYDATA;}while(k1 == 0);}if(k2 == 0) //选择闹钟修正参数{delay(1000); //肃清抖动 一样平常大约10msif(k2==0) //再次判断按键是否按下{alarm++; if(alarm == 3)alarm=0; }while(k2 == 0);}switch(alarm)//选择进入修正参数{case 0:if(k3 == 0) //掌握闹钟开{delay(1000); //肃清抖动 一样平常大约10msif(k3==0) //再次判断按键是否按下{alarmswitch = ON;SectorErase(0x2401);byte_write(0x2401,alarmswitch);}while(k3 == 0);}if(k4 == 0) //掌握闹钟关闭{delay(1000); //肃清抖动 一样平常大约10msif(k4==0) //再次判断按键是否按下{alarmswitch = OFF;SectorErase(0x2401);byte_write(0x2401,alarmswitch);}while(k4 == 0);}break;case 1:if(k3==0) //掌握闹钟时针加{delay(1000); //肃清抖动 一样平常大约10msif(k3 ==0) //再次判断按键是否按下{ alarm_hour++; if(alarm_hour%16 == 0x0a) { alarm_hour += 16;alarm_hour &= 0xf0; }if(alarm_hour==0x24)alarm_hour=0; SectorErase(0x2601);byte_write(0x2601,alarm_hour);}while(k3==0);}if(k4==0) //掌握闹钟时针减{delay(1000); //肃清抖动 一样平常大约10msif(k4 ==0) //再次判断按键是否按下{ alarm_hour--; if(alarm_hour%16==0x0f && alarm_hour!=0xff) {alarm_hour &= 0xf9; } if(alarm_hour==0xff)alarm_hour=0x23; SectorErase(0x2601); byte_write(0x2601,alarm_hour);}while(k4==0);}break;case 2:if(k3==0){delay(1000); //肃清抖动 一样平常大约10msif(k3 ==0) //再次判断按键是否按下{ alarm_min++; if(alarm_min%16 == 0x0a) { alarm_min += 16;alarm_min &= 0xf0; }if(alarm_min==0x60)alarm_min=0; SectorErase(0x2201); byte_write(0x2201,alarm_min);}while(k3==0);}if(k4==0){delay(1000); //肃清抖动 一样平常大约10msif(k4 ==0) //再次判断按键是否按下{ alarm_min--; if(alarm_min%16==0x0f && alarm_min!=0xff) {alarm_min &= 0xf9; } if(alarm_min==0xff)alarm_min=0x59; SectorErase(0x2201); byte_write(0x2201,alarm_min);}while(k4==0);}break;}if(time == 200){alarm_hour=byte_read(0x2601);alarm_min=byte_read(0x2201);alarmswitch=byte_read(0x2401);LcdWriteCom(0x80); //显示LcdWritestr("alarm clock: ");LcdWriteCom(0xc0); if(alarmswitch == OFF)LcdWritestr(" OFF ");else LcdWritestr(" ON ");LcdWriteCom(0xc9); LcdWriteData(alarm_hour/16+0x30);LcdWriteData(alarm_hour%16+0x30);LcdWriteData(':'); LcdWriteData(alarm_min/16+0x30);LcdWriteData(alarm_min%16+0x30);LcdWritestr(" ");}else if(time == 400)switch(alarm) //选择进入修正参数{case 0: LcdWriteCom(0xc0);LcdWritestr(" ");break;case 1: LcdWriteCom(0xc9);LcdWritestr(" ");break;case 2: LcdWriteCom(0xcc);LcdWritestr(" ");break;}else if(time>400) time=0;delay_ms(1);}/闹钟模式/void alarmclock(void){ if(alarmswitch==ON && alarm_hour==TIME[2] && alarm_min==TIME[1]) //闹钟{beep=1;delay_ms(100);beep=0;delay_ms(100); beep=1;delay_ms(100);beep=0;LcdWriteCom(0x80);LcdWritestr(" time out! ");LcdWriteCom(0xc0);LcdWritestr("now time: ");LcdWriteData(alarm_hour/16+0x30);LcdWriteData(alarm_hour%16+0x30);LcdWriteData(':'); LcdWriteData(alarm_min/16+0x30);LcdWriteData(alarm_min%16+0x30);LcdWritestr(" ");delay_ms(500);LcdClean();}else mode=DISPLAYDATA;if(k4==0){delay(1000); //肃清抖动 一样平常大约10msif(k4 ==0) //再次判断按键是否按下{ alarmswitch=OFF;}while(k4==0);} }/ 函 数 名 : main 函数功能 : 主函数 输 入 : 无 输 出 : 无/void main(void){int ucount=0;unsigned char lastSec;beep= 0;LcdInit(); //lcd初始化//Ds1302Init(); //时钟初始化Ds18b20Init(); //温度传感器初始化SectorErase(0x2001);//byte_write(0x2001,0x08); //实行一遍初始化//byte_write(0x2201,0x00);//byte_write(0x2401,0x00);alarm_hour=byte_read(0x2601);alarm_min=byte_read(0x2201);alarmswitch=byte_read(0x2401);while(1){switch(mode)//模式选择{case DISPLAYDATA://韶光显示模式Ds1302ReadTime(); //更新韶光if(TIME[0] != lastSec){lastSec = TIME[0];display_data(); //显示韶光 秒分时日月周年displaytemp(Ds18b20ReadTemp());//显示温度if(alarmswitch==ON && alarm_hour==TIME[2] && alarm_min==TIME[1]) //闹钟{mode = ALARMCLOCK; }} keypros(); //按键检测break;case MODIFYDATA: //韶光修正模式modify();break;case SETALARMCLOCK: //设置闹钟模式setalarmclock();break;case ALARMCLOCK: //闹钟模式alarmclock();break;}}}
一、仿真问题由于代码是基于实物设计的,部分功能不能完备仿真运行,不能运行的内容有EEPROM的存取,温度的读取1、闹钟、韶光不能调或者一起动?由于调节闹钟会设计EEPROM的存取,以是不能正常显示读取到EEPROM的内容,须要该功能须要删除掉电存储功能2、不日期显示非常,显示???,星期不显示的问题?由于日期显示是0-9,星期显示是1-7,当显示的数据超过这个值时就会显示不正常,仿真的话须要适当修正代码,实物须要重新设置韶光,就可以正常显示
完全代码可进群免费领取!
!
!
嵌入式物联网的学习之路非常漫长,不少人由于学习路线不对或者学习内容不足专业而错失落高薪offer。不过别担心,我为大家整理了一份150多G的学习资源,基本上涵盖了嵌入式物联网学习的所有内容。点击下方链接,0元领取学习资源,让你的学习之路更加顺畅!
记得点赞、关注、收藏、转发哦!
点击这里找小助理0元领取:扫码进群领资料