基于AT89S51单片机的多功能电子万年历的设计.docx

上传人:b****3 文档编号:4145785 上传时间:2022-11-28 格式:DOCX 页数:39 大小:73.90KB
下载 相关 举报
基于AT89S51单片机的多功能电子万年历的设计.docx_第1页
第1页 / 共39页
基于AT89S51单片机的多功能电子万年历的设计.docx_第2页
第2页 / 共39页
基于AT89S51单片机的多功能电子万年历的设计.docx_第3页
第3页 / 共39页
基于AT89S51单片机的多功能电子万年历的设计.docx_第4页
第4页 / 共39页
基于AT89S51单片机的多功能电子万年历的设计.docx_第5页
第5页 / 共39页
点击查看更多>>
下载资源
资源描述

基于AT89S51单片机的多功能电子万年历的设计.docx

《基于AT89S51单片机的多功能电子万年历的设计.docx》由会员分享,可在线阅读,更多相关《基于AT89S51单片机的多功能电子万年历的设计.docx(39页珍藏版)》请在冰豆网上搜索。

基于AT89S51单片机的多功能电子万年历的设计.docx

基于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)

***

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1