基于AT89C51单片机的电子万年历PROTEUS仿真设计

article/2025/9/18 0:00:13

目录
前 言 1
第一章 工作原理 2
1.1设计目标 2
1.1.1基本功能 2
第二章 硬件设计与原理 3
2.1 总设计框图 3
2.2 硬件设计分析 3
2.2.1 电源的设计 3
2.2.2 单片机最小系统 4
2.2.3 显示系统 10
2.2.4 LCD1602的指令说明及时序 12
2.2.5 LCD1602的RAM地址映射及标准字库表 14
2.2.6 DS1302原理及说明 16
2.2.7 DS18B20工作原理及说明 19
2.2.8 按键电路 20
第三章 软件设计与分析 22
3.1 软件设计的组成 22
3.2 源程序 26
第四章 软件仿真 56
4.1 PROTEUS简介 56
4.2仿真图 58
4.3原理图 59
4.4 元件清单 60
总结 61
致 谢 63
参考文献 64
1.1.1基本功能
此万年历主要具有:年、月、日、星期、时、分、秒、温度显示。
主要功能:
1、万年历
2、时间
3、星期
4、温度显示
(以上四项内容同时显示)
5、四键调时(设置键、上调键、下调键、关音按键)
以AT89C51单片机为核心,起着控制作用。系统包括LCD1602液晶显示电路、复位电路、时钟电路、按键电路、温度传感器电路、时钟芯片电路。设计思路分为七个模块:复位电路、晶振电路模块、AT89C51、LCD1602液晶显示电路、按键电路、温度传感器电路、时钟芯片电路这七个模块。
2.2 硬件设计分析
2.2.1 电源的设计
系统电源使用直流5伏。
由电脑USB接口提供电源。
USB是通用串行总线(Universal Serial Bus)接口的简称。它是目前使用比较广泛的电脑接口之一,主要版本有1.0、1.1和最新的2.0三种版本。根据USB总线的工业标准,它可以提供额定功率为5V/500mA的电源供USB设备使用。
2.2.2 单片机最小系统
51单片机是对目前所有兼容intel 8031指令系统的单片机的统称。该系列单片机的始祖是intel的8031单片机,后来随着技术的发展,成为目前广泛应用的8为单片机之一。单片机是在一块芯片内集成了CPU、RAM、ROM、定时器/计数器和多功能I/O口等计算机所需要的基本功能部件的大规模集成电路,又称为MCU。51系列单片机内包含以下几个部件:
一个8位CPU;本文转载自http://www.biyezuopin.vip/onews.asp?id=14837一个片内振荡器及时钟电路;
4KB的ROM程序存储器;
一个128B的RAM数据存储器;
寻址64KB外部数据存储器和64KB外部程序存储空间的控制电路;
32条可编程的I/O口线;
两个16位定时/计数器;
一个可编程全双工串行口;
5个中断源、两个优先级嵌套中断结构。

#include<reg51.h>
#include"DS18B20.h"
uchar a,b,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp,miao1,shi1=12,fen1=1,miao1=0,clock=0 ;
//flag用于读取头文件中的温度值,和显示温度值
#define yh 0x80 //LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1(100000000=80)
#define er 0x80+0x40 //LCD第二行初始位置(因为第二行第一个字符位置地址是0x40)
//液晶屏的与C51之间的引脚连接定义(显示数据线接C51的P0口)
sbit rs=P2^0;
sbit en=P2^2;
sbit rw=P2^1; //如果硬件上rw接地,就不用写这句和后面的rw=0了
sbit led=P2^6; //LCD背光开关
//DS1302时钟芯片与C51之间的引脚连接定义
sbit IO=P1^1;
sbit SCLK=P1^0;
sbit RST=P1^2;
sbit CLO=P1^4;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
/************************************************************
ACC累加器=A
ACC.0=E0H ACC.0就是ACC的第0位。Acc可以位寻址。累加器ACC是一个8位的存储单元,是用来放数据的。但是,这个存储单元有其特殊的地位,
是单片机中一个非常关键的单元,很多运算都要通过ACC来进行。以后在学习指令时,
常用A来表示累加器。但有一些地方例外,比如在PUSH指令中,就必须用ACC这样的名字。
一般的说法,A代表了累加器中的内容、而ACC代表的是累加器的地址。 
***************************************************************/
//校时按键与C51的引脚连接定义
sbit key1=P1^5;  //设置键
sbit key2=P1^6;  //加键
sbit key3=P1^7;  //减键
sbit buzzer=P1^3;//蜂鸣器,通过三极管9012驱动,端口低电平响
/**************************************************************/
uchar code tab1[]={"20  -  -   "}; //年显示的固定字符
uchar code tab2[]={"  :  :  "};//时间显示的固定字符
uchar code tab3[]={"    HELLO WELCOME"};//开机动画
//延时函数,后面经常调用
void delay(uint xms)//延时函数,有参函数
{uint x,y;for(x=xms;x>0;x--)for(y=110;y>0;y--);
}
/********液晶写入指令函数与写入数据函数,以后可调用**************//*在这个程序中,液晶写入有关函数会在DS1302的函数中调用,所以液晶程序要放在前面*/void write_1602com(uchar com)//****液晶写入指令函数****
{rs=0;//数据/指令选择置为指令rw=0; //读写选择置为写P0=com;//送入数据delay(1);en=1;//拉高使能端,为制造有效的下降沿做准备delay(1);en=0;//en由高变低,产生下降沿,液晶执行命令
}
void write_1602dat(uchar dat)//***液晶写入数据函数****
{rs=1;//数据/指令选择置为数据rw=0; //读写选择置为写P0=dat;//送入数据delay(1);en=1; //en置高电平,为制造下降沿做准备delay(1);en=0; //en由高变低,产生下降沿,液晶执行命令
}
void lcd_init()//***液晶初始化函数****
{uchar j;write_1602com(0x0f|0x08);for(a=0;a<17;a++)write_1602dat(tab3[a]);j=17;while(j--){write_1602com(0x1c);//循环左移delay(700);} write_1602com(0x01);delay(10);write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据write_1602com(0x0c);//开显示不显示光标write_1602com(0x06);//整屏不移动,光标自动右移write_1602com(0x01);//清显示/***开机动画显示hello welcome dianzizhong****/write_1602com(yh+1);//日历显示固定符号从第一行第1个位置之后开始显示for(a=0;a<14;a++){write_1602dat(tab1[a]);//向液晶屏写日历显示的固定符号部分//delay(3);}write_1602com(er+2);//时间显示固定符号写入位置,从第2个位置后开始显示	for(a=0;a<8;a++){write_1602dat(tab2[a]);//写显示时间固定符号,两个冒号//delay(3);}write_1602com(er+0);write_1602dat(0x24);write_1602com(er+1);write_1602dat(0x20);
}
/***************DS1302有关子函数********************/
void write_byte(uchar dat)//写一个字节
{ACC=dat;RST=1;for(a=8;a>0;a--){IO=ACC0;SCLK=0;SCLK=1;ACC=ACC>>1;}
}
uchar read_byte()//读一个字节
{RST=1;for(a=8;a>0;a--){ACC7=IO;SCLK=1;SCLK=0;ACC=ACC>>1;}return(ACC);
}
//----------------------------------------
void write_1302(uchar add,uchar dat)//向1302芯片写函数,指定写入地址,数据
{RST=0;SCLK=0;RST=1;write_byte(add);write_byte(dat);SCLK=1;RST=0;
}
uchar read_1302(uchar add)//从1302读数据函数,指定读取数据来源地址
{uchar temp;RST=0;SCLK=0;RST=1;write_byte(add);temp=read_byte();SCLK=1;RST=0;return(temp);
}
uchar BCD_Decimal(uchar bcd)//BCD码转十进制函数,输入BCD,返回十进制
{uchar Decimal;Decimal=bcd>>4;return(Decimal=Decimal*10+(bcd&=0x0F));
}
//--------------------------------------
void ds1302_init() //1302芯片初始化子函数(2010-01-07,12:00:00,week4)
{RST=0;SCLK=0;write_1302(0x8e,0x00); //允许写,禁止写保护 miao=BCD_Decimal(read_1302(0x81));fen=BCD_Decimal(read_1302(0x83));shi=BCD_Decimal(read_1302(0x85));ri=BCD_Decimal(read_1302(0x87));yue=BCD_Decimal(read_1302(0x89));nian=BCD_Decimal(read_1302(0x8d));week=BCD_Decimal(read_1302(0x8b));//写入初始年份数据10write_1302(0x8e,0x80); //打开写保护
}
//------------------------------------
//温度显示子函数
void write_temp(uchar add,uchar dat)//向LCD写温度数据,并指定显示位置
{uchar gw,sw,bw;if(dat>=0&&dat<=128){gw=dat%10;//取得个位数字sw=dat%100/10;//取得十位数字bw=dat/100	;//取得百位数字	}else{dat=256-dat;gw=dat%10;//取得个位数字sw=dat%100/10;//取得十位数字bw=-3;		 //0x30-3表示为负号}write_1602com(er+add);//er是头文件规定的值0x80+0x40write_1602dat(0x30+bw);//数字+30得到该数字的LCD1602显示码write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码write_1602dat(0xdf);//显示温度的小圆圈符号,0xdf是液晶屏字符库的该符号地址码write_1602dat(0x43);	//显示"C"符号,0x43是液晶屏字符库里大写C的地址码		
}
//------------------------------------
//时分秒显示子函数
void write_sfm(uchar add,uchar dat)//向LCD写时分秒,有显示位置加、现示数据,两个参数
{uchar gw,sw;gw=dat%10;//取得个位数字sw=dat/10;//取得十位数字write_1602com(er+add);//er是头文件规定的值0x80+0x40write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码				
}
//-------------------------------------
//年月日显示子函数
void write_nyr(uchar add,uchar dat)//向LCD写年月日,有显示位置加数、显示数据,两个参数
{uchar gw,sw;gw=dat%10;//取得个位数字sw=dat/10;//取得十位数字write_1602com(yh+add);//设定显示位置为第一个位置+addwrite_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码	
}
//-------------------------------------------
void write_week(uchar week)//写星期函数
{write_1602com(yh+0x0c);//星期字符的显示位置switch(week){case 1:	write_1602dat('M');//星期数为1时,显示write_1602dat('O');write_1602dat('N');break;case 2:	write_1602dat('T');//星期数据为2时显示write_1602dat('U');write_1602dat('E');break;case 3:	write_1602dat('W');//星期数据为3时显示write_1602dat('E');write_1602dat('D');break;case 4:	write_1602dat('T');//星期数据为4是显示write_1602dat('H');write_1602dat('U');break;case 5:	write_1602dat('F');//星期数据为5时显示write_1602dat('R');write_1602dat('I');break;case 6:	write_1602dat('S');//星期数据为6时显示write_1602dat('T');write_1602dat('A');break;case 7:	write_1602dat('S');//星期数据为7时显示write_1602dat('U');write_1602dat('N');break;}
}
//****************键盘扫描有关函数**********************
void keyscan()
{if(key1==0)//---------------key1为功能键(设置键)--------------------{delay(9);//延时,用于消抖动if(key1==0)//延时后再次确认按键按下{buzzer=0;//蜂鸣器短响一次delay(20);buzzer=1;while(!key1);key1n++;if(key1n==12)key1n=1;//设置按键共有秒、分、时、星期、日、月、年、返回,8个功能循环switch(key1n){		case 1: TR0=0;//关闭定时器//TR1=0;write_1602com(er+0x09);//设置按键按动一次,秒位置显示光标write_1602com(0x0f);//设置光标为闪烁temp=(miao)/10*16+(miao)%10;//秒数据写入DS1302write_1302(0x8e,0x00);write_1302(0x80,0x80|temp);//miaowrite_1302(0x8e,0x80);break;case 2: write_1602com(er+6);//按2次fen位置显示光标						//write_1602com(0x0f);break;case 3: write_1602com(er+3);//按动3次,shi//write_1602com(0x0f);break;case 4: write_1602com(yh+0x0e);//按动4次,week//write_1602com(0x0f);break;case 5: write_1602com(yh+0x0a);//按动5次,ri//write_1602com(0x0f);break;case 6: write_1602com(yh+0x07);//按动6次,yue//write_1602com(0x0f);break;case 7: write_1602com(yh+0x04);//按动7次,nian//write_1602com(0x0f);break;case 8: write_1602com(er+1);write_1602dat(0x4d);write_1602com(er+1);break;case 9: write_1602com(er+1);write_1602dat(0x46);write_1602com(er+1);break;case 10:write_1602com(er+1);write_1602dat(0x53);write_1602com(er+1);break;case 11:write_1602com(er+1);write_1602dat(0x20);write_1602com(0x0c);//按动到第8次,设置光标不闪烁TR0=1;//打开定时器temp=(miao)/10*16+(miao)%10;write_1302(0x8e,0x00);write_1302(0x80,0x00|temp);//miao数据写入DS1302write_1302(0x8e,0x80);break;																		}} }//------------------------------加键key2----------------------------		if(key1n!=0)//当key1按下以下。再按以下键才有效(按键次数不等于零){if(key2==0)  //上调键{delay(10);if(key2==0){buzzer=0;//蜂鸣器短响一次delay(20);buzzer=1;while(!key2);switch(key1n){case 1:	miao++;//设置键按动1次,调秒if(miao==60)miao=0;//秒超过59,再加1,就归零write_sfm(0x08,miao);//令LCD在正确位置显示"加"设定好的秒数temp=(miao)/10*16+(miao)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00); //允许写,禁止写保护 write_1302(0x80,temp); //向DS1302内写秒寄存器80H写入调整后的秒数据BCD码write_1302(0x8e,0x80); //打开写保护write_1602com(er+0x09);//因为设置液晶的模式是写入数据后,光标自动右移,所以要指定返回//write_1602com(0x0b);break;case 2:	fen++;if(fen==60)fen=0;write_sfm(0x05,fen);//令LCD在正确位置显示"加"设定好的分数据temp=(fen)/10*16+(fen)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x82,temp);//向DS1302内写分寄存器82H写入调整后的分数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置break;case 3:	shi++;if(shi==24)shi=0;write_sfm(2,shi);//令LCD在正确的位置显示"加"设定好的小时数据temp=(shi)/10*16+(shi)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x84,temp);//向DS1302内写小时寄存器84H写入调整后的小时数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 4:	week++;if(week==8)week=1;write_1602com(yh+0x0C);//指定'加'后的周数据显示位置write_week(week);//指定周数据显示内容temp=(week)/10*16+(week)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x8a,temp);//向DS1302内写周寄存器8aH写入调整后的周数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(yh+0x0e);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 5:	ri++;switch(yue){case 1:case 3:case 5:case 7:case 8:case 10:case 12:if(ri>31) ri=1;break;case 2: if(nian%4==0||nian%400==0){ if(ri>29) ri=1;}	else					  	{					    if(ri>28) ri=1;}break;case 4:case 6:case 9:case 11:ri++;if(ri>30) ri=1;break;}		 write_nyr(9,ri);//令LCD在正确的位置显示"加"设定好的日期数据temp=(ri)/10*16+(ri)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护write_1302(0x86,temp);//向DS1302内写日期寄存器86H写入调整后的日期数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(yh+10);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 6:	yue++;if(yue==13)yue=1;write_nyr(6,yue);//令LCD在正确的位置显示"加"设定好的月份数据temp=(yue)/10*16+(yue)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护write_1302(0x88,temp);//向DS1302内写月份寄存器88H写入调整后的月份数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(yh+7);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 7:	nian++;if(nian==100)nian=0;write_nyr(3,nian);//令LCD在正确的位置显示"加"设定好的年份数据temp=(nian)/10*16+(nian)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护write_1302(0x8c,temp);//向DS1302内写年份寄存器8cH写入调整后的年份数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(yh+4);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 8:	write_1602com(er+9); //设置闹钟的秒定时miao1++;if(miao1==60)miao1=0;write_sfm(0x08,miao1);//令LCD在正确位置显示"加"设定好秒的数据write_1602com(er+9);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置break;case 9:	write_1602com(er+6); //设置闹钟的分钟定时fen1++;if(fen1==60)fen1=0;write_sfm(0x05,fen1);//令LCD在正确位置显示"加"设定好的分数据write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置break;case 10:write_1602com(er+3); //设置闹钟的小时定时shi1++;if(shi1==24)shi1=0;write_sfm(0x02,shi1);//令LCD在正确的位置显示"加"设定好的小时数据write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;}}}//------------------减键key3,各句功能参照'加键'注释---------------if(key3==0){delay(10);//调延时,消抖动if(key3==0){buzzer=0;//蜂鸣器短响一次delay(20);buzzer=1;while(!key3);switch(key1n){case 1:	miao--;if(miao==-1)miao=59;//秒数据减到-1时自动变成59write_sfm(0x08,miao);//在LCD的正确位置显示改变后新的秒数temp=(miao)/10*16+(miao)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00); //允许写,禁止写保护 write_1302(0x80,temp); //向DS1302内写秒寄存器80H写入调整后的秒数据BCD码write_1302(0x8e,0x80); //打开写保护write_1602com(er+0x09);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置//write_1602com(0x0b);break;case 2:	fen--;if(fen==-1)fen=59;write_sfm(5,fen);temp=(fen)/10*16+(fen)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x82,temp);//向DS1302内写分寄存器82H写入调整后的分数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置break;case 3:	shi--;if(shi==-1)shi=23;write_sfm(2,shi);temp=(shi)/10*16+(shi)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x84,temp);//向DS1302内写小时寄存器84H写入调整后的小时数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 4:	week--;if(week==0)week=7;						 write_1602com(yh+0x0C);//指定'加'后的周数据显示位置write_week(week);//指定周数据显示内容temp=(week)/10*16+(week)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护 write_1302(0x8a,temp);//向DS1302内写周寄存器8aH写入调整后的周数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(yh+0x0e);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 5:	ri--;switch(yue){ case 1:case 3:case 5:case 7:case 8:case 10:case 12: if(ri==0) ri=31;break;case 2: if(nian%4==0||nian%400==0){ if(ri==0) ri=29;}			else	{if(ri==0) ri=28;}break;case 4:case 6:case 9:case 11:if(ri==0) ri=30;break;}write_nyr(9,ri);temp=(ri)/10*16+(ri)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护write_1302(0x86,temp);//向DS1302内写日期寄存器86H写入调整后的日期数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(yh+10);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 6:	yue--;if(yue==0)yue=12;write_nyr(6,yue);temp=(yue)/10*16+(yue)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护write_1302(0x88,temp);//向DS1302内写月份寄存器88H写入调整后的月份数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(yh+7);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;	case 7:	nian--;if(nian==-1)nian=99;write_nyr(3,nian);temp=(nian)/10*16+(nian)%10;//十进制转换成DS1302要求的DCB码write_1302(0x8e,0x00);//允许写,禁止写保护write_1302(0x8c,temp);//向DS1302内写年份寄存器8cH写入调整后的年份数据BCD码write_1302(0x8e,0x80);//打开写保护write_1602com(yh+4);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 8:	write_1602com(er+9); //设置闹钟的秒定时miao1--;if(miao1==-1)miao1=59;write_sfm(0x08,miao1);//令LCD在正确位置显示"加"设定好秒的数据write_1602com(er+9);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置break;case 9:	write_1602com(er+6); //设置闹钟的分钟定时fen1--;if(fen1==-1)fen1=59;write_sfm(0x05,fen1);//令LCD在正确位置显示"加"设定好的分数据write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置break;case 10:write_1602com(er+3); //设置闹钟的小时定时shi1--;if(shi1==-1)shi1=23;write_sfm(0x02,shi1);//令LCD在正确的位置显示"加"设定好的小时数据write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;			}}}}
}
//定时器0初始化程序
void init() //定时器、计数器设置函数
{TMOD=0x11; //指定定时/计数器的工作方式为1TH0=0;  //定时器T0的高四位=0TL0=0;  //定时器T0的低四位=0EA=1;  //系统允许有开放的中断ET0=1; //允许T0中断TR0=1; //开启中断,启动定时器
}
//*******************主函数**************************
//***************************************************
void main()
{	lcd_init();      //调用液晶屏初始化子函数ds1302_init();   //调用DS1302时钟的初始化子函数init();          //调用定时计数器的设置子函数led=0;           //打开LCD的背光电源buzzer=0;//蜂鸣器长响一次delay(80);buzzer=1; while(1)  //无限循环下面的语句:{		keyscan();      //调用键盘扫描子函数}
}
/*************通过定时中断实现定是独处并显示数据******************/
void t0() interrupt 1  //取得并显示日历和时间
{	//Init_DS18B20();//温度传感器DS18b2初始化子函数,在头文件中flag=ReadTemperature();//将18b2头文件运行返回的函数结果送到变量FLAG中,用于显示//读取秒时分周日月年七个数据(DS1302的读寄存器与写寄存器不一样):miao=BCD_Decimal(read_1302(0x81));fen=BCD_Decimal(read_1302(0x83));shi=BCD_Decimal(read_1302(0x85));ri=BCD_Decimal(read_1302(0x87));yue=BCD_Decimal(read_1302(0x89));nian=BCD_Decimal(read_1302(0x8d));week=BCD_Decimal(read_1302(0x8b));//显示温度、秒、时、分数据:write_temp(12,flag);//显示温度,从第二行第12个字符后开始显示write_sfm(8,miao);//秒,从第二行第8个字后开始显示(调用时分秒显示子函数)write_sfm(5,fen);//分,从第二行第5个字符后开始显示write_sfm(2,shi);//小时,从第二行第2个字符后开始显示//显示日、月、年数据:write_nyr(9,ri);//日期,从第二行第9个字符后开始显示write_nyr(6,yue);//月份,从第二行第6个字符后开始显示write_nyr(3,nian);//年,从第二行第3个字符后开始显示write_week(week-1);/***********整点报时程序************/if(fen==0&&miao==0)if(shi<22&&shi>6 ){buzzer=0;//蜂鸣器短响一次delay(20);buzzer=1;}/**************闹钟程序: 将暂停键按下停止蜂鸣********************/if(shi1==shi&&fen1==fen&&miao==0){		clock=1; }	if(clock==1){buzzer=0;//蜂鸣器短响一次delay(20);buzzer=1;}if(CLO==0)	/*按下p1.4停止蜂鸣*/clock=0;	
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://chatgpt.dhexx.cn/article/1xEOYyWY.shtml

相关文章

基于at89c51单片机的交通灯控制设计

** 单片机自主学习项目*设计分析 —模拟LED交通灯 ** 一、开发背景与需求 1 开发背景 交通事业蓬勃发展&#xff0c;交通流量年年增长&#xff0c;道路交通繁忙&#xff0c;经常有严重堵车现象&#xff0c;特别是在交叉口&#xff0c;为了在叉口的各条干道实现合理的科学分…

以梦为马之89c51单片机驱动lcd

路有千万条&#xff0c;我要选择那条最难的走&#xff0c;这才是我该走的路 控制LCD实际上就是控制两个牛屎芯片 观察lcd1602&#xff0c;它有16个引脚&#xff0c;其含义如下图所示 查看数据手册看到如下时序图 再看说明书看到时序图介绍&#xff1a; 芯片手册混合写的&a…

AT89C51单片机的C语言代码和仿真模拟学习

单片机定时器学习 一、代码图片与仿真模拟图 #include <reg51.h>/*定义KEY*/ sbit KEY1 P1^0; sbit KEY2 P1^1;void Delay100ms() //12.000MHz延时100ms {unsigned char i, j;i 195;j 138;do{while (--j);} while (--i); }//判断KEY值并执行程序 void Judgefunctio…

AT89C51单片机制作简易密码锁

51单片机课程设计—制作密码锁 文章目录 51单片机课程设计---制作密码锁1.设计要求2.设计流程图3.重要代码解释4.仿真电路设计5.完整代码设计6.仿真结果图7.工程源码及protues仿真下载 1.设计要求 1.1能设定一组4位的数字开启密码&#xff08;设定密码功能&#xff09; 1.2用L…

AT89C51单片机万年历仿真图+代码

首先申明&#xff0c;这篇博客是用作记录本人实训内容的&#xff0c;代码我个人一字一字码的&#xff0c;就上网查了下数字温度传感器DS18B20的处理方法&#xff0c;基本都是个人完成的。 在这里吐槽下&#xff0c;本人辛辛苦苦码的代码&#xff0c;最后实训分数还没那些抄的人…

基于AT89C51单片机的电子万年历系统

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/87708258 源码获取 主要内容&#xff1a; 电子万年历系统以实时时钟芯片DS1302和AT89C52单片机为主要研究对象&#xff0c;着重进行51单片机控制系统的设计研究和如…

c51单片机时钟c语言程序设计,AT89C51单片机为核心的时钟电路的程序设计

当前位置:电工之家 > 电工知识 > 单片机 > 正文 AT89C51单片机为核心的时钟电路的程序设计 时间:2018-06-05 08:38 来源:电工之家 AT89C51单片机为核心的时钟电路的程序设计 1.主程序设计及系统主流程图 设计中采用定时器T0中断完成,其余状态循环调用显示子程序。系…

AT89C51单片机

目录 一、AT89S51单片机的I/O端口二、AT89S51单片机的中断系统  1、中断处理过程  2、AT89S51单片机的中断源&#xff08;2&#xff09;AT89S51单片机的中断控制&#xff08;3&#xff09;AT89S51单片机的中断优先级&#xff08;4&#xff09;AT89S51单片机中断系统的结构&…

89c51c语言程序,AT89C51单片机流水灯c语言程序及详解

许多朋友不知道怎么用C语言编程实现AT89C51单片机流水灯&#xff0c;这里给大家讲解一下。 首先将单片机的头函数导入。 #include"reg51.h" 定义单片机P1口的8个管脚&#xff0c;使其分别代表流水灯的8个led。 sbit p0P1^0; sbit p1P1^1; sbit p2P1^2; sbit p3P1^3; …

keil ISIS AT89C51单片机

突然想起大学时候学习的知识&#xff0c;最近空余时间较多&#xff0c;想回顾一下&#xff0c;然后发现连最简单的编辑器的名字都快忘记了&#xff0c;于是赶紧抓紧时间复习一遍&#xff0c;在此记录一下这个过程遇到的问题。 首先是对于keil的安装&#xff0c;我是直接从网上…

AT89C51单片机性能介绍

AT89C51是一种带4K字节闪烁可编程可擦除只读存储器&#xff08;FPEROM—Falsh Programmable and Erasable Read Only Memory&#xff09;的低电压&#xff0c;高性能CMOS8位微处理器&#xff0c;俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造&#xff0c;与工业标…

微机基础与89C51单片机部分知识

1&#xff0c;微机基础知识 微机: 具有完整运算及控制能力的计算机。包括微处理器&#xff0c;储存器&#xff0c;接口适配器&#xff0c;输入输出设备。 微处理器&#xff1a; 控制器&#xff1a;由程序计数器&#xff0c;指令寄存器&#xff0c;指令译码器&#xff0c;时序发…

基于AT89C51单片机的计算器设计

点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87772564 源码获取 主要内容: 本设计是基于51系列的单片机进行的设计,可以完成计算器的键盘输入,进行加、减、3位无符号数字的简单运算,并在LED上相应的显示结果。设计过…

基于 AT89C51 单片机的数字时钟设计

目录 1.设计目的、作用 2.设计要求 3.设计的具体实现 3.1 设计原理 3.2 硬件系统设计 3.2.1 AT89C51 单片机原理 3.2.2 晶振电路设计 3.2.3 复位电路设计 3.2.4 LED 数码管显示 3.3 系统实现 3.3.1 系统仿真与调试 3.3.2 演示结果 4.总结 附录 附录 1 附录 2 1.…

89C51单片机之寄存器

文章目录 片内RAM中的寄存器内容介绍 低128字节片内RAM4组工作寄存器 高128字节片内RAM&#xff08;SFR区&#xff09;部分特殊功能寄存器累加器 ACC寄存器 B程序状态寄存器 PSW栈指针 SP数据指针 DPTRI/O端口 P0~P3 中断系统中的特殊寄存器定时器控制寄存器 TCON 之中断定时器…

【89c51汇编语言】51单片机结构及其原理

单片机结构及其原理 51单片机的内部结构单片机CPU控制器控制器&#xff1a;程序计数器&#xff1a;PC 控制器&#xff1a;数据指针寄存器&#xff1a;DPTR运算器累加器APSW程序状态字CY&#xff08;PSW.7&#xff09;进位标志AC&#xff08;PSW.6&#xff09;辅助进位标志RS1和…

89c51单片机

89c51是一款很大众化的入门级单片机&#xff0c;ATMEL、NXP、STC、和SST等公司生产的与80c51兼容低功耗、高性能8位89c51/s51单片机具有比80c31更丰富的外设资源。 89c51/s51单片机芯片内包括&#xff1a; ①一个8位的80c51微处理器&#xff08;CPU&#xff09; ②片内256字…

关于会话(session),你应该了解这些

一、什么是会话 会话Session代表的是客户端与服务器的一次交互过程&#xff0c;这个过程可以是连续也可以是时断时续的。在Servlet中&#xff08;jsp&#xff09;&#xff0c;一旦用户与服务端交互&#xff0c;服务器tomcat就会为用户创建一个session&#xff0c;同时前端会有…

ZooKeeper客户端源码(一)——向服务端建立连接+会话建立+心跳保持长连接

首发CSDN&#xff1a;徐同学呀&#xff0c;原创不易&#xff0c;转载请注明源链接。我是徐同学&#xff0c;用心输出高质量文章&#xff0c;希望对你有所帮助。 一、从ZooKeeper实例初始化开始 ZooKeeper 提供了原生的客户端库&#xff0c;虽然不好用&#xff0c;但是能够更好…

会话劫持安全攻击

什么是会话劫持&#xff1f; TCP 会话劫持是对受保护网络上的用户会话的安全攻击。会话劫持最常见的方法称为 IP 欺骗&#xff0c;攻击者使用源路由 IP 数据包将命令插入网络上两个节点之间的活动通信中&#xff0c;并将自己伪装成经过身份验证的用户之一。这种类型的攻击是可能…