基于51单片机的万年历proteus仿真原理图方案设计

链接:https://pan.baidu.com/s/1PJ6Vc4R6mjLmKOG_VDYzZg
提取码:btlq

系统框图
在这里插入图片描述
原理图
在这里插入图片描述
仿真图
在这里插入图片描述
最小系统电路
STC89C52的最小系统如图3-3所示,整个最小系统由三个部分组成,晶振电路部分、复位电路部分、电源电路等三个部分组成。
晶振电路包括2个30pF的电容C2和C3,以及12M的晶振X1。电容的作用在这里是起振作用,帮助晶振更容易的起振,取值范围是15-33pF。晶振的取值也可以是24M,晶振的取值越高,单片机的执行速度越快。在进行电路设计的时候,晶振部分越靠近单片机越好。
单片机复位电路就好比电脑的重启部分,当电脑在使用中出现死机,按下重启按钮电脑内部的程序从头开始执行。单片机也一样,当单片机系统在运行中,受到环境干扰出现程序跑飞的时候,按下复位按钮内部的程序自动从头开始执行。
复位电路由10uF的极性电容C1和10K的电阻R4构成。利用电容电压不能突变的性质,可以知道,当系统一上电,RESET脚将会出现高电平,并且这个高电平持续的时间由电路的RC值来决定。典型的51单片机当RESET脚的高电平持续两个机器周期以上就将复位,所以适当组合RC的取值就可以保证可靠的复位。
最后一个是电源部分,采用5V的USB直接供电,可采用手机充电器、电脑USB口、移动电源等设备进行供电。
此外,除了单片机最小系统的3个部分之外,这里还多了一些外部电路。
由于STC89C52的P0口是漏极开路输出,因此在P0口接了一个10K的排阻R1,使得P0口可以作为普通的I/O口使用,本设计用P0口来做液晶的数据口。
特别注意的是,对于31脚(EA),当接高电平时,单片机在复位后从内部ROM的0000H开始执行;当接低电平时,复位后直接从外部ROM的0000H开始执行。由于我们的程序存储在了单片机内部,所以EA要接高电平,保证单片机是从内部读取程序去执行的

液晶显示电路

液晶显示器是一种显示器件,具有小体积、轻重量、低功耗等特色。由于其功耗低、显示的信息量大(例如,文本,图形,曲线等)、无电磁辐射、使用寿命长,它已被广泛应用在便携式电子产品。
本系统显示采用了工业字符型液晶模块1602,可显示2行16个字符,能方便显示英文字母大小写、阿拉伯数字、常用符号等。通过自定义还可显示简单的汉字。
本系统采用的1602是一款物美价廉的液晶显示屏,可以显示2行标准字符,每行共有16个字符。在通信系统,智能操作仪表和办公设备的自动化中被广泛的应用,主要功能是显示ASCII字符,因此被称为“字符型显示装置”。当在内部没有适合的汉字库的液晶类型显示器想要表达汉字的时候,第一步就是要获得想要的汉文或者图形的子模数据。子模块的软件不能直接提取的子模块的数据5×8点阵,可以从手工提取汉字的字体以模具。第二步,把取得的汉字子模数据保存在液晶存储器里面。

时钟模块
DS1302简介
DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。现在流行的串行时钟电路很多,如DS1302、 DS1307、PCF8485等。这些电路的接口简单、价格低廉、使用方便,被广泛地采用。
本文介绍的实时时钟电路DS1302是DALLAS公司的一种具有涓细电流充电能力的电路,主要特点是采用串行数据传输,可为掉电保护电源提供可编程的充电功能,并且可以关闭充电功能。采用普通32.768kHz晶振。是一种高性能、低功耗、带RAM的实时时钟芯片,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。

DS18B20传感器电路
DS18B20简介
(1)概述
DS18B20(图3-10)是美国DALLAS半导体公司推出的第一片支持“一线总线”接口的温度传感器,它具有微型化,低功耗,高性能,抗干扰能力强,易配微处理器等优点,可直接将温度转化成数字信号处理器处理。测量的温度范围是-55125℃,测温误差0.5℃。可编程分辨率912位,对应的可分辨温度分别为0.5℃,0.25℃,0.125℃和0.0625℃。相较热电偶传感器而言可实现高精度测温。

部分程序:

#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char	// 以后unsigned char就可以用uchar代替
#define uint  unsigned int	// 以后unsigned int 就可以用uint 代替

sfr ISP_DATA  = 0xe2;				// 数据寄存器
sfr ISP_ADDRH = 0xe3;				// 地址寄存器高八位
sfr ISP_ADDRL = 0xe4;				// 地址寄存器低八位
sfr ISP_CMD   = 0xe5;				// 命令寄存器
sfr ISP_TRIG  = 0xe6;				// 命令触发寄存器
sfr ISP_CONTR = 0xe7;				// 命令寄存器

sbit LcdRs_P    = P2^7;       // 1602液晶的RS管脚       
sbit LcdRw_P    = P2^6;       // 1602液晶的RW管脚 
sbit LcdEn_P    = P2^5;       // 1602液晶的EN管脚
sbit RST_P      = P1^3;				// 时钟芯片DS1302的RST管脚
sbit SDA_P      = P1^2;				// 时钟芯片DS1302的SDA管脚
sbit SCK_P      = P1^1;				// 时钟芯片DS1302的SCK管脚
sbit KeySet_P   = P3^2;				// 设置时间按键
sbit KeyClock_P = P3^3;				// 设置闹钟按键
sbit KeyDown_P  = P3^4;				// 减按键
sbit KeyUp_P    = P3^5;				// 加按键
sbit Buzzer_P   = P2^0;				// 蜂鸣器
sbit DQ         = P1^0;				// DS18B20传感器的引脚定义


uchar TimeBuff[7]={17,9,1,6,18,30,40};				// 时间数组,默认2017年9月1日,星期五,18:30:40
// TimeBuff[0] 代表年份,范围00-99
// TimeBuff[1] 代表月份,范围1-12
// TimeBuff[2] 代表日期,范围1-31
// TimeBuff[3] 代表星期,范围1-7,1是星期天,2是星期一... ...
// TimeBuff[4] 代表小时,范围00-23
// TimeBuff[5] 代表分钟,范围00-59
// TimeBuff[6] 代表秒钟,范围00-59


uchar Clock_Hour;					// 闹钟的小时
uchar Clock_Minute;				// 闹钟的分钟
uchar Clock_Swt;					// 闹钟的开关
uchar Buzzer_Flag=0;			// 蜂鸣器工作标志



/*********************************************************/
// 单片机内部EEPROM不使能
/*********************************************************/
void ISP_Disable()
{
	ISP_CONTR = 0;
	ISP_ADDRH = 0;
	ISP_ADDRL = 0;
}


/*********************************************************/
// 从单片机内部EEPROM读一个字节,从0x2000地址开始
/*********************************************************/
unsigned char EEPROM_Read(unsigned int add)
{
	ISP_DATA  = 0x00;
	ISP_CONTR = 0x83;
	ISP_CMD   = 0x01;
	ISP_ADDRH = (unsigned char)(add>>8);
	ISP_ADDRL = (unsigned char)(add&0xff);
	// 对STC89C51系列来说,每次要写入0x46,再写入0xB9,ISP/IAP才会生效
	ISP_TRIG  = 0x46;	   
	ISP_TRIG  = 0xB9;
	_nop_();
	ISP_Disable();
	return (ISP_DATA);
}


/*********************************************************/
// 往单片机内部EEPROM写一个字节,从0x2000地址开始
/*********************************************************/

.

.

  • 25
    点赞
  • 148
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
**********************************************/ #include<reg52.h> #define uchar unsigned char #define uint unsigned int uchar code table[]=" 2013-07-30 WED "; uchar code table1[]=" 21:14:55"; uchar code table2[]=" 579259 "; uchar code table3[]="Made by Lisongze"; uchar code table4[]="MONTUEWEDTHUFRISATSUN"; uchar count,s1num; char miao,fen,shi,ri,yue; uint nian; sbit lcd_rs = P0^5; sbit lcd_rw = P0^6; sbit lcd_en = P0^7; sbit s1=P3^7; sbit s2=P3^6; sbit s3=P3^5; sbit g=P3^0; void delay(uint z)//延时子函数 { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void write_com(uchar com)//写命令函数 { lcd_rs = 0; P2= com; delay(5); lcd_en=1; delay(5); lcd_en=0; } void write_date(uchar date)//写数据函数 { lcd_rs = 1; P2= date; delay(5); lcd_en=1; delay(5); lcd_en=0; } void init()//初始化函数 { int num; shi=21; fen=14; miao=55; ri=30; yue=7; nian=2013; lcd_en=0; lcd_rw=0; write_com(0x38);//显示设置模式 write_com(0x0c);//00001100开显示,不显示光标,光标不闪烁 write_com(0x06);//00000110地址指针加一,整屏不移动 write_com(0x01);//清屏 write_com(0x80); for(num=0;num<16;num++)//显示数字579259 { write_date(table2[num]); delay(300); } write_com(0x80+0x40); for(num=0;num<16;num++)//显示made by lisongze { write_date(table3[num]); delay(300); } delay(5000); write_com(0x01); write_com(0x80); for(num=0;num<16;num++)//显示日期 { write_date(table[num]); delay(5); } write_com(0x80+0x40); for(num=0;num<12;num++)//显示时间 { write_date(table1[num]); delay(5); } TMOD=0x01;//启动定时器中断 TH0=(65535-50000)/256; TL0=(65535-50000)%256; EA=1; ET0=1; TR0=1;//打开定时器 } void write_sfm(uchar add,uchar date)//写时分秒函数 { uchar shi,ge; shi=date/10; ge=date; write_com(0x80+0x40+add); write_date(0x30+shi); write_date(0x30+ge); } void write_nyr(uint add,uint date)//写年月日函数,此处若用uchar范围只有0-255 { //不够,改用uint(0-65535) uint qian,bai,shi,ge; qian=date/1000; bai=date00/100; shi=date0/10; ge=date; write_com(0x80+add); write_date(0x30+qian); write_date(0x30+bai); write_date(0x30+shi); write_date(0x30+ge); } void write_yr(uchar add,uchar date)//写月日函数 { uchar shi,ge; shi=date/10; ge=date; write_com(0x80+add); write_date(0x30+shi); write_date(0x30+ge); } void keyscan()//按键扫描函数 { int m,n; g=0;//将矩阵键盘当做独立键盘使用 if(s1==0) { delay(5); if(s1==0)//按键1光标移位扫描 { s1num++; if(s1num==1) { while(!s1);//等待按键松手 write_com(0x80+0x40+10); TR0=0;//关闭定时器 write_com(0x0f); } if(s1num==2) { while(!s1); write_com(0x80+0x40+7); } if(s1num==3) { while(!s1); write_com(0x80+0x40+4); } if(s1num==4) { while(!s1); write_com(0x80+3); } if(s1num==5) { while(!s1); write_com(0x80+6); } if(s1num==6) { while(!s1); write_com(0x80+9); } if(s1num==7) { while(!s1) write_com(0x80+13); } if(s1num==8) { while(!s1); s1num=0; write_com(0x0c); TR0=1;//开定时器 } } } if(s1num!=0) { if(s2==0)//按键2加功能 { delay(5); if(s2==0) { while(!s2); if(s1num==1)//秒加 { miao++; if(miao==60) { miao=0; } write_sfm(10,miao); write_com(0x80+0x40+10); } if(s1num==2)//分加 { fen++; if(fen==60) { fen=0; } write_sfm(7,fen); write_com(0x80+0x40+7); } if(s1num==3)//时加 { shi++; if(shi==24) { shi=0; } write_sfm(4,shi); write_com(0x80+0x40+4); } if(s1num==4)//年加 { nian++; if(nian==10000) { nian=2000; } write_nyr(1,nian); write_com(0x80+3); } if(s1num==5)//月份加 { yue++; if(yue==13) { yue=1; } write_yr(6,yue); write_com(0x80+6); } if(s1num==6)//日期加 { ri++; if(ri==29&&yue==2&&!((nian%4==0&&nian0!=0)||nian%400==0)) { ri=1;//平年 } if(ri==30&&yue==2&&((nian%4==0&&nian0!=0||nian%400==0))) { ri=1;//闰年 } if(ri==31&&(yue==4||yue==6||yue==9||yue==11)) { ri=1; } if(ri==32) { ri=1; } write_yr(9,ri); write_com(0x80+9); } if(s1num==7)//星期加 { m=m+3; if(m==21) m=0; write_com(0x80+12); for(n=m;n<m+3;n++) { write_date(table4[n]); delay(5); } write_com(0x80+13); } } } if(s3==0)//按键3减功能 { delay(5); if(s3==0) { while(!s3); if(s1num==1)//秒减 { miao--; if(miao==-1) { miao=59; } write_sfm(10,miao); write_com(0x80+0x40+10); } if(s1num==2)//分减 { fen--; if(fen==-1) fen=59; write_sfm(7,fen); write_com(0x80+0x40+7); } if(s1num==3)//时减 { shi--; if(shi==-1) shi=23; write_sfm(4,shi); write_com(0x80+0x40+4); } if(s1num==4)//年减 { nian--; if(nian==1999) nian=2000; write_nyr(1,nian); write_com(0x80+3); } if(s1num==5)//月份减 { yue--; if(yue==0) yue=12; write_yr(6,yue); write_com(0x80+6); } if(s1num==6)//日减 { ri--; if(ri==0) { if(yue==2&&!((nian%4==0&&nian0!=0)||nian%400==0)) { ri=28;//平年 } if(yue==2&&((nian%4==0&&nian0!=0||nian%400==0))) { ri=29;//闰年 } if(yue==4||yue==6||yue==9||yue==11) { ri=30; } if(yue==1||yue==3||yue==5||yue==7||yue==9||yue==11) ri=31; } write_yr(9,ri); write_com(0x80+9); } if(s1num==7)//星期减 { m=m-3; if(m==0) m=21; write_com(0x80+12); for(n=m;n-3<m;n++) { write_date(table4[n-3]); delay(5); } write_com(0x80+13); } } } } } void main() { int i,j; init(); while(1) { keyscan(); if(count==18) { count=0; miao++; if(miao==60) { miao=0; fen++; if(fen==60) { fen=0; shi++; if(shi==24) { shi=0; ri++; j=j+3; if(j==21) j=0; write_com(0x80+12); for(i=j;i<j+3;i++) { write_date(table4[i]); delay(5); } if(ri==29&&yue==2&&!((nian%4==0&&nian0!=0)||nian%400==0)) { ri=1;yue++;//平年 } if(ri==30&&yue==2&&((nian%4==0&&nian0!=0||nian%400==0))) { ri=1;yue++;//闰年 } if(ri==31&&(yue==4||yue==6||yue==9||yue==11)) { ri=1;yue++; } if(ri==32) { ri=1;yue++; } if(yue==13) { yue=1; nian++; if(nian==10000) { nian=2000; } write_nyr(1,nian); } write_yr(6,yue); } write_yr(9,ri); write_sfm(4,shi); } write_sfm(7,fen); } write_sfm(10,miao); } } } void timer() interrupt 1 { TH0=(65535-50000)/256; TL0=(65535-50000)%256; count++; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值