基于AT89S51单片机的多功能电子万年历的设计.docx
- 文档编号:4145785
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:39
- 大小:73.90KB
基于AT89S51单片机的多功能电子万年历的设计.docx
《基于AT89S51单片机的多功能电子万年历的设计.docx》由会员分享,可在线阅读,更多相关《基于AT89S51单片机的多功能电子万年历的设计.docx(39页珍藏版)》请在冰豆网上搜索。
基于AT89S51单片机的多功能电子万年历的设计
单片机应用系统设计
课
题:
姓
名:
班
级:
学
号:
指导老师:
日
期:
电子万年历的设计
基于AT89S51单片机的多功能
一、绪论:
现在是一个知识爆炸的新时代,新产品、新技术层出不穷,电子技术的发展更是日新月异。
可以毫不夸张的说,电子技术的应用无处不在,电子技术正在不断地改变我们的生活,改变着我们的世界。
近些年,随着科技的发展和社会的进步,人们对电子万年历的要求也越
来越高,传统的电子万年历已不能满足人们的需求。
人们对多功能电子万年历的功能及工作
顺序都非常熟悉,但是却很少知道它的内部结构以及工作原理。
由于单片机具有灵活性强、成本低、功耗低、保密性好等特点,还有,单片机是微型计算机的一个重要分枝,单片机是把中央处理器、随机存储器、只读存储器、定时器/计数器、并行接口接口、串行接口、A/D
转换器等主要计算机部件,集中在一块集成电路芯片上。
虽然只是一个芯片,但从功能上它
就相当于一台完整的微机。
随着科学技术的迅猛发展,单片计集成度高、体积小、运算速度
快、功耗低、运行可靠、价格低廉等诸多优点,越来越显现出来。
在日常生活方面,我们使用彩电、录放机、VCD照相机、手机等等可以说举不胜举。
所以多功能电子万年历一般都以单片机为核心,外加一些外围设备来实现。
由单片机作为多功能电子万年历的核心控制器,通过按键可以进行定时、校时功能。
输出设备显示器可以用液晶显示技术和数码管显示技术。
意义:
电子万年历作为电子类小设计不仅是市场上的宠儿,也是是单片机实验中一个很
常用的题目。
因为它的有很好的开放性和可发挥性,因此对作者的要求比较高,不仅考察了
对单片机的掌握能力更加强调了对神农百草膏单片机扩展的应用。
而且在操作的设计上要力求简洁,功能上尽量齐全,显示界面也要出色。
所以,电子万年历无论作为比赛题目还是练习题目都是很有价值。
二、系统总体方案设计:
1、共具备两个功能:
(1)显示年月日及分秒信息
(2)具有可调整日期和时间功能。
2、硬件电路的总体框图:
图1总体硬件框图
3、所用芯片
U1
AXTAL1
YTAIo
P0.0/AD0P0.1/AD1P0.2/AD2
P0.3/AD3
P0.4/AD4
XIAL2
P0.5/AD5
P0.6/AD6
RST
P0.7/AD7
P2.0/A8
P2.1/A9
PSEN
P2.2/A10
P2.3/A11
ALE
P2.4/A12
EA
P2.5/A13
P2.6/A14
P2.7/A15
P1.0/T2
P3.0/RXD
P1.1/T2EX
P3.1/TXD
P1.2
P3.2/INT0
P3.3/INT1
P1.3
P1.4
P3.4/T0
P1.5
P3.5/T1
P1.6
P3.6/WR
P1.7
P3.7/RD
AT89C52
19
18
9
4
6
8
1
2
29_
30
31_
_11
_12
233
J5
17
三、硬件系统设计:
1、硬件原理图:
DNG
LM016L
X2
22pF
X1
+5V
A
n*
I0—1
U2
2
+5V
X1
VCC1
VCC2
RST
SCLK
X2
I/O
5
3
6
123
U1
19
XTAL1
P0.0/AD0
P0.1/AD1
P0.2/AD2
XTAL2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
RST
P0.7/AD7
P2.0/A8
P2.1/A9
P2.2/A10
PSEN
P2.3/A11
ALE
P2.4/A12
EA
P2.5/A13
P2.6/A14
P2.7/A15
P1.0
P3.0/RXD
P1.1
P3.1/TXD
P1.2
P3.2/rNT0
P1.3
P3.3/rNTT
P1.4
P3.4/T0
P1.5
P3.5/T1
P1.6
P3.6/WR
P1.7
P3.7/RD
18
9
29
30—k
21—22--23n
~25F
—27
-28
10
07
36
35
-34
32
39
V5+
flo—上工»flo—
R-
DNG
U3
VCC
DQ
GND••
DS18B20
P0口作为6位液晶显示电路的驱动接口,这是由于P0口
它的驱动能力强,故只需外接上拉电阻便可以把LED数码
,在单片机进行动态扫描的时候不会8位LED数码管的,由一个8位的I/O口
图3硬件原理
2、硬件原理:
在硬件电路中采用输出驱动电路工作处于开漏状态管点亮。
因为共阴的LED数码管它的驱动电流是分开的影响彼此的电流,故该电路中的8位LED数码管均用共阳阴极的数码管。
位选线分别由相应的P2.0〜P2.5控制,而将其相应的段选线并联在一起控制,即P0口。
P3口与八个校时按键相连,以成功实现万年历校时的功能。
四、系统软件设计:
1、程序流程框图:
2、年调整程序流程图,
图4程序流程框图
月、日调整程序流程图类似。
图5年调整程序流程图
3、源程序代码:
#include
温度传送数据IO口
0//
#include
Command
//#include"LCD1602.h"
voidshow_time();//液晶
#defineLCD_DATA
//#include"DS1302.h"
显示程序
1//Data
#defineuintunsignedint
/***********1602液晶显
#define
#defineucharunsignedchar
示部分子程序
LCD_CLEAR_SCREEN
char
****************/
0x01//清屏
hide_sec,hide_min,hide_hour
#defineLCD_HOMING
hide_day,hide_week,hide_m
0x02//光
onth,hide_year;//秒,分,时
//Port
标返回原点
到日,月,年位闪的计数
Definitions**************
voidLCD_Write(bitstyle,
char
***********************
unsignedcharinput)
done,count,temp,flag,Up_Ke
*********************
{
y_flag,down_flag;
sbitLcdRs=P2人5;
LcdEn=0;
uchartemp_value;//
sbitLcdRw=P2人6;
LcdRs=style;
温度值
sbitLcdEn=P2人7;
LcdRw=0;
uchar
sfrDBPort=0x80;
_nop_();
TempBuffer[5],week_value[
//P0=0x80,P1=0x90,P2
DBPort=input;
2];
=0xA0,P3=0xB0.数据端口
_nop_();//注意顺序
内部等待函数
LcdEn=1;
***********************
_nop_();//注意顺序
sbitDS1302_CLK=PIT;
***********************
LcdEn=0;
//实时时钟时钟线引脚
***********************
_nop_();
sbitDS1302_IO=P1人6;
*****
LCD_Wait();
//实时时钟数据线引脚
unsignedchar
}
sbitDS1302_RST=P1^5;
LCD_Wait(void)
//实时时钟复位线引脚
{
//设置显示模式
sbitportOI=P3人0;
LcdRs=0;
***********************
sbitport02=P3人1;
LcdRw=1;
***********************
sbitport03=P3人2;
_nop_();//延时一个时
**************
sbitport04=P3人3;
钟周期
#defineLCD_SHOW
sbitACC0=ACCS;
LcdEn=1;_nop_();
0x04//显示开
sbitACC7=ACC^7;
#defineLCD_HIDE
sbitSet_Key=P2人0;
0x00//显示关
//模式切换键
LcdEn=0;
sbitUp_Key=P2";
returnDBPort;
//加法按钮
}
#defineLCD_CURSOR
sbitDown_Key=P2人2;
//向LCD写入命令或数据
0x02//显示光
//减法按钮
***********************
标
sbitout_Key_Key=P2人3;
***********************
#defineLCD_NO_CURSOR
//立刻跳出调整模式按钮
**************
0x00//无光标
sbitDQ=P19//
#defineLCD_COMMAND
#defineLCD_FLASH
0x01//光标闪
闪动voidvoidLCD_Initial()
{
LcdEn=0;
LCD_Write(LCD_CO
MMAND,0x38);
//8位数据端口,2行显示,5*7点阵
while(*str!
='\0')
{
LCD_Write(LCD_DAT
A,*str);
str++;
}
LCD_Set_KeyDisplay(unsignedcharDisplayMode){
LCD_Write(LCD_COMMAND,0x08|DisplayMode);
}
LCD_Write(LCD_COMMAND,0x38);
LCD_Set_KeyDisplay(LCD_SHOW|LCD_NO_CURSOR);//开启显示,无光标
//设置输入模
幵**卄*卄**卄*卄*卄*卄*
**************
#define
LCD_AC_UP_KEY
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);//清屏
LCD_Set_KeyInput(LCD_AC_UP_KEY|LCD_NO_MOVE);//AC递增,画面不动
/***********DS1302
部分子
******************/
typedef
__SYSTEMTIME
#define
0x02
LCD_AC_DOWN
0x00
//
default
//液晶字符输入的位置
***********************
时钟
序
struct
unsignedcharSecond;unsignedcharMinute;unsignedcharHour;unsignedcharWeek;unsignedcharDay;unsignedcharMonth;
#defineLCD_MOVE
voidGotoXY(unsignedchar
unsignedchar
Year;
0x01//画
x,unsignedchary)
unsigned
char
面可平移
{
DateString[11];
#defineLCD_NO_MOVE
if(y==0)
unsigned
char
0x00
TimeString[9];
//default
LCD_Write(LCD_CO
}SYSTEMTIME;
//定义的
MMAND,0x80|x);
时间类型
void
if(y==1)
SYSTEMTIME
LCD_Set_KeyInput(unsigne
CurrentTime;
dcharInputMode)
LCD_Write(LCD_CO
{
MMAND,0x80|(x-0x40));
LCD_Write(LCD_CO
}
#defineAM(X)
X
MMAND,0x04|InputMode);
#definePM(X)
(X+12)
}
//将字符输出到液晶显示
//转成24小时制
void
#defineDS1302_
SECOND
//初始化
Print(unsighttp:
//www.shenn
0x80
//时钟
LCD*******************
nedchar*str)
芯片的寄存器位置
存放时
//相
char
#defineDS1302_MINUTE
0x82
#defineDS1302_HOUR
0x84
#defineDS1302_WEEK
0x8A
#defineDS1302_DAY
0x86
#defineDS1302_MONTH0x88
#defineDS1302_YEAR
0x8Cvoid
DS1302InputByte(unsignedchard)//实时时钟写入一字节(内部函数){
unsignedchari;
ACC=d;for(i=8;i>0;i--){
DS1302_IO
ACC0;当于汇编中的RRC
DS1302_CLK=1;
DS1302_CLK=0;
ACC=ACC>>1;
unsignedchar
DS1302OutputByte(void)//实时时钟读取一字节(内部函数)
{
unsignedchari;
for(i=8;i>0;i--)
{
ACC=ACC>>1;//相当于汇编中的RRC
ACC7
DS1302_IO;
DS1302_CLK=1;
DS1302_CLK=0;}return(ACC);
voidWrite1302(unsignedcharucAddr,unsignedcharucDa)//ucAddr:
DS1302地址,ucData:
要写的数据{
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr);
//地址,命令
DS1302InputByte(ucDa);//写1Byte数据DS1302_CLK=1;DS1302_RST=0;
}
unsigned
Read1302(unsigneducAddr)//读取DS1302某地址的数据
unsignedcharucData;DS1302_RST=0;DS1302_CLK=0;DS1302_RST=1;
DS1302InputByte(ucAddr|0x
01);//地址,命令ucData
DS1302OutputByte();
//读1Byte数据DS1302_CLK=1;DS1302_RST=0;return(ucData);
voidDS1302_GetTime(SYSTEMTIME*Time)//获取时钟芯片的时钟数据到自定义的结构型数组{
unsigned
ReadValue;
ReadValueRead1302(DS1302_SECOND);
Time->Second((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValueRead1302(DS1302_MINUTE);
Time->Minute((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue
Read1302(DS1302_HOUR);
Time->Hour((ReadValue&0x70)>>4)*10
+(ReadValue&0x0F);
ReadValue
Read1302(DS1302_DAY);
Time->Day((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue
Read1302(DS1302_WEEK);
Time->Week((ReadValue&0x70)>>4)*10
+(ReadValue&0x0F);
ReadValueRead1302(DS1302_MONTH);
Time->Month((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue
Read1302(DS1302_YEAR);
Time->Year((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);}
Time->DateString[5]=Time->Month/10+'0';
Time->DateString[6]
=Time->Month%10+'0';
}
else
Time->DateString[10]='\0';//字符串末尾加'\0',判断结束字符}
void
DateToStr(SYSTEMTIME*Time)//将时间年,月,
日,星期数据转换成液晶显示字符串,放到数组里DateString[]
{if(hide_year<2)//这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为2007/07/22
{
Time->DateString[0]
='2';
Time->DateString[1]
='0';
Time->DateString[5]='';
Time->DateString[6]='';
}
Time->DateString[7]
if(hide_day<2)
{
Time->DateString[8]=Time->Day/10+'0';
Time->DateString[9]=Time->Day%10+'0';
}
else
{voidTimeToStr(SYSTEMTIME*Time)//将时,分,秒数据转换成液晶显示字符放到数组TimeString[];
{if(hide_hour<2)
{
Time->TimeString[0]=Time->Hour/10+'0';
Time->TimeString[1]
=Time->Hour%10+'0';
}
else
Time->TimeString[0]='';
Time->DateString[2]=Time->Year/10+'0';
Time->DateString[3]=Time->Year%10+'0';
}
else
Time->DateString[0]='';
Time->DateString[1]='';
Time->DateString[2]='';
Time->DateString[3]='';
}
Time->DateString[4]
Time->DateString[8]='';
Time->DateString[9]
}if(hide_week<2){
week_value[0]=Time->Week%10+'0';//星期的数据另外放到week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示
}
else
{
week_value[0]Time->TimeString[1]='';
}
Time->TimeString[2]
if(hide_min<2)
{
Time->TimeString[3]=Time->Minute/10+'0';
Time->TimeString[4]=Time->Minute%10+'0';
}
else
{
Time->TimeString[3]='';
Time->TimeString[4]='';
}
Time->TimeString[5]
if(hide_month<2)
{
}
week_value[1]='\0';
if(hide_sec<2)
{
Time->TimeString[6]=Time->Second/10+'0';
Time->TimeString[7]=Time->Second%10+'0';
}
else
{
/***********ds18b20
序
**/
子程
unsigned
ReadOneChar(void)
{
char
Time->TimeString[6]='';
Time->TimeString[7]='';
}
Time->DateString[8]
'\0';
}
void
//时钟芯片初始化
{
unsignedcharSecond=Read1302(DS1302_SECOND);
if(Second&0x80)//判断时钟芯片是否关闭
Initial_DS1302(void)
{
Write1302(0x8e,0x00);
//写入允许
Write1302(0x8c,0x07);
//以下写入初始化时间日
期:
07/07/25.星期:
3.时间:
23:
59:
55
Write1302(0x88,0x07);
Write1302(0x86,0x25);
Write1302(0x8a,0x07);
Write1302(0x84,0x23);
Write1302(0x82,0x59);
Write1302(0x80,0x55);
Write1302(0x8e,0x80);//禁止写入
}
/***********ds18b20子函数(晶振12MHz)
***
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 AT89S51 单片机 多功能 电子 万年历 设计