万年历实验报告-final

哈尔滨工程大学

实   验   报   告

实 验 名 称:­­________电子系统设计实验________

班       级:_________20090822_______________

学       号:_________2009082228_____________

姓       名:___________王嘉博_______________

实 验 时 间:________________________________

成       绩:________________________________

指 导 教 师:_________李北明_______________________

实验室名称:_____________________________

哈尔滨工程大学实验室与资产管理处


一、设计要求与方案论证

1.1 项目设计内容、功能、指标

(1)基本要求

①  具有年、月、日、时、分、秒等功能;

②  具有自动判别闰年闰月的功能

③  有一路闹钟

 ( 2 ) 创新要求

①        具有闹钟功能,时间到后蜂鸣器响,led灯亮。

②       设置的时间日期掉电不丢失

③       具有温度计功能;

1.2项目设计方案和比较

1.2.1单片机芯片的选择方案和论证:

方案一:

采用89C51芯片作为硬件核心,采用Flash ROM,内部具有4KB ROM 存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术, 当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的多次拔插会对芯片造成一定的损坏。

方案二:

   采用STC89C52,片内ROM全都采用Flash ROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全该芯片内部存储器为8KB ROM 存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯片造成损坏。

所以选择采用AT89S52作为主控制系统.

1.2.2显示模块选择方案和论证:

方案一:

    采用Lcd液晶显示屏,液晶显示屏的显示功能强大,可显示大量文字,图形,显示多样,清晰可见。

方案二:

     采用点阵式数码管显示,点阵式数码管是由八行八列的发光二极管组成,对于显示文字比较适合,如采用在显示数字显得太浪费,且价格也相对较高,所以也不用此种作为显示.

方案三:

采用LED数码管动态扫描,LED数码管价格适中,对于显示数字最合适,而且采用动态扫描法与单片机连接时,占用的单片机口线少。

由于显示的内容较多,采用led数码管不方便,所以采用了LCD液晶作为显示。

1.2.3时钟芯片的选择方案和论证:

方案一:

   直接采用单片机定时计数器提供秒信号,使用程序实现年、月、日、星期、时、分、秒计数。采用此种方案虽然减少芯片的使用,节约成本,但是,实现的时间误差较大。

方案二:

   采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、日、周、月、年以及闰年补偿的年进行计数,而且精度高,位的RAM做为数据暂存区,工作电压2.5V~5.5V范围内,2.5V时耗电小于300nA,但成本高。

 

最终确定采用方案一,直接用单片机定时器提供秒信号。

1.2.4温度传感器的选择方案与论证:

方案一:

使用热敏电阻作为传感器,用热敏电阻与一个相应阻值电阻相串联分压,利用热敏电阻阻值随温度变化而变化的特性,采集这两个电阻变化的分压值,并进行A/D转换。。此设计方案需用A/D转换电路,增加硬件成本而且热敏电阻的感温特性曲线并不是严格线性的,会产生较大的测量误差。

方案二:

采用数字式温度传感器DS18B20,此类传感器为数字式传感器而且仅需要一条数据线进行数据传输,易于与单片机连接,可以去除A/D模块,降低硬件成本,简化系统电路。另外,数字式温度传感器还具有测量精度高、测量范围广等优点。

最终采用DS18B20。

1.2.5 掉电不丢失

采用EEROM 24C02存储设定的时间日期,实现掉电不丢失。

1.3 电路设计最终方案决定

综上各方案所述,对此次作品的方案选定: 采用STC89C52作为主控制系统;单片机计数器提供时钟;数字式温度传感器18B20;LCD液晶屏作为显示;用独立按键控制时间的调整、闹钟的设定。

二.系统的硬件设计与实现

2.1 电路设计框图

 

 

 

2.2 系统硬件概述

本电路是由STC89C52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;时钟电路由单片机内部计数器构成,每计1秒,产生一个终断,提供秒信号;采用E2ROM 1602存储,掉电不丢失;温度的采集由DS18B20构成;显示部份由液晶显示屏1602构成。

2.3 主要单元电路的设计

2.3.1单片机主控制模块的设计

    stc89c52单片机为40引脚双列直插芯片,有四个I/O口P0,P1,P2,P3, MCS-51单片机共有4个8位的I/O口(P0、P1、P2、P3),每一条I/O线都能独立地作输出或输入。

单片机的最小系统如下图所示,18引脚和19引脚接时钟电路,XTAL1接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出.第9引脚为复位输入端,接上电容,电阻及开关后够上电复位电路,20引脚为接地端,40引脚为电源端.  如图-1 所示

          

图-1 主控制系统

2.3.2温度采集模块设计

如图-3所示。采用数字式温度传感器DS18B20,它是数字式温度传感器,具有测量精度高,电路连接简单特点,此类传感器仅需要一条数据线进行数据传输,使用P2.7与DS18B20的I/O口连接加一个上拉电阻,Vcc接电源,1管脚接地。

          

                    图-3 DS18B20温度采集

2.3.3内部计数器

用计数器的工作方式一,采用16位加一计数器, THx8位和TLx8位组成16位加1计数器,计数外部脉冲个数:1~65536(216),计数的最大值为65536,定时时间(若T=1ms):1ms~(65536×T=65.54ms)。

计数器工作原理框图如下

 


2.3.4 显示模块的设计

      显示模块通过一块16脚的LCD1602组成。其中1、2脚接地,7、9、11分别接一个I/O口用于控制液晶的显示,13--28接P0的8个I/O口用于数据传输,29、31用于控制液晶的背光。如下图所示

基本操作时序表

读写操作时序如图所示:

图 读操作时序

图  写操作时序

2.3.5  按键模块的设计

采用独立按键控制,上拉电阻接Vcc,按键为低电平有效。

2.3.6  蜂鸣器模块的设计

                        蜂鸣器需要用三极管驱动才能工作,高电平有效。

2.3.6  rom模块

                                            采用E2ROM 24C02,存储时间设置,     可以起到掉电不丢失的作用。

2.3.7  串口下载模块

 

采用芯片max232,在pcb板上设计串口,接单片机的txd和rxd,用于下载程序。

三、系统的软件设计

实验程序流程图如下所示:

 


 

四、调试过程和测试方法

调试过程:

1、首先在一块单片机开发板上调用相应的模块,调试程序,这主要是软件调试,软件调试正确后,按照原理图将所需模块用DXP软件画pcb板并完成腐蚀和焊接。

2、检测串口是否能够下程序

3、 检测晶振工作频率是否正常

4、检测按键按下前后输出端点评是否正常

5、正确下进程序之后,发现液晶显示屏始终无法显示字符,这是调节液晶1602 的5管脚相连的滑动变阻器,直至能够显示字符。

6、在设定时间的时候,光标闪烁显示正在设置的是哪一位,但加上温度显示后,由于温度随时在采样并显示,所以出现了温度与时间抢光标的情况,而更加糟糕的是,由于不同模块间的相互干扰,加上温度后,时间经常会终止,这是用单片机内部计数器定时的弊端,如果用时钟芯片,应该可以避免这种现象。最终只能去掉温度显示模块。

结果测试:

最终可以实现年、月、日、时、分、秒的显示和闹钟功能,可以判断闰年闰月,时间可以设定。按下s1进入时间设定模式,此时再按键s1可以切换要设置的是哪一位,多次按s1,依次可以设定秒、分、时、日、月、年的低2位、年的高2位、时钟的分、时钟的时,按键s2使被设置位的数值增加,按键s3使被设置位的数值减小,按键s4使液晶显示从时间设定模式转换为正常走时模式。闹钟所设定的时间到后,蜂鸣器响,led灯亮,这里的led灯代表一个驱动,比如家里的电饭煲,当时间到的时候,可以自动启动,此时按下按键s5,蜂鸣器停止鸣叫,led灯灭。掉电后,设定的时间不会丢失,再次开机,仍未原关机前的时间。此外,串口工作正常。

五、参考文献

[1] 郭天翔.新概念51单片机C语言教程 入门、提高、开发、拓展全.北京.电子工业出版社 2009.1

[2] 罗杰 .电子线路设计实验测试. 电子工业出版社 20##年4月

[3] 江志红 51单片机技术与应用系统开发 案例精选  清华大学出版社 2008.12

[3] 杨居义 单片机课程设计指导  清华大学出版社 2009.9

[3] 宋戈 51单片机应用开发范例大全  人民邮电出版社 2008.12

附录一、原理图与PCB图

 

附录二、试验程序

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
bit write=0;

sbit sda=P2^3;
sbit scl=P2^4;
sbit p1=P1;
sbit rs=P2^2;
sbit rw=P2^1;
sbit lcden=P2^0;
sbit s1=P1^0;
sbit s2=P1^1;
sbit s3=P1^2;
sbit s4=P1^3;
sbit s5=P1^4;
sbit rd=P3^7;
sbit beep=P2^3;
sbit guanjiao=P3^4;
sbit deng=P1^5;
uchar count,s1num;
uint shi1,shi2,shi3,shi4,shi5,shi6;
char miao,shi,fen;
uint setshi,setfen;
uint ri,yue,nian,nian1;
uchar code table[]="20##-04-20";
uint shi1=0;
uint fen1=0;
uchar flag;
/**************************************AT24C02C芯片*****************************************************/
void flash()
{;;}

void start() //开始信号
{sda=1;
flash();
scl=1;
flash();
sda=0;
flash(); }
void stop() //停止
{sda=0;
flash();
scl=1;
flash();
sda=1;
flash(); }
void respons() //应答
{uchar i;
scl=1;
flash();
while((sda==1)&&(i<250)) i++;
scl=0;
flash();}
void init()
{sda=1;
flash();
scl=1;
flash();}
void write_byte(uchar date)
{uchar i,t;
t=date;
for(i=0;i<8;i++)
{t=t<<1;
scl=0;
flash();
sda=CY;
flash();
scl=1;
flash();}
scl=0;
flash();
sda=1;
flash();}
uchar read_byte()
{uchar i,k;
scl=0;
flash();
sda=1;
flash();
for(i=0;i<8;i++)
{scl=1;
flash();
k=(k<<1)|sda;
scl=0;
flash();}
return k;}
void write_add(uchar address,uchar date)
{start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();}
uchar read_add(uchar address)
{uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;}

void delay(uint z)
{uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);}
void di()
{beep=0;
delay(100);
beep=1;}
void write_com(uchar com)
{rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;}
void write_date(uchar date)
{rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;}
void write_sfm(uchar add,uchar date)
{uchar sh,ge;
sh=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+sh);
write_date(0x30+ge);}
void write_sfm1(uchar add,uchar date)
{uchar sh,ge;
sh=date/10;
ge=date%10;
write_com(0x80+add);
write_date(0x30+sh);
write_date(0x30+ge);}
void init0()
{uchar num;
// P1=0x0f;
rd=0;
rw=0;
lcden=0;
count=0;
s1num=0;
guanjiao=0;
init();
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);

write_com(0x80+4);
write_date('-');
delay(5);
write_com(0x80+0x40+2);
write_date(':');
write_com(0x80+7);
write_date('-');
delay(5);
delay(5);
write_com(0x80+0x40+5);
write_date(':');
delay(5);
write_com(0x80+0x40+12);
write_date(':');
delay(5);
miao=read_add(1);
fen=read_add(2);
shi=read_add(3);
ri=read_add(4);
yue=read_add(5);
nian=read_add(6);
nian1=read_add(7);
fen1=read_add(8);
shi1=read_add(9);
write_sfm(6,miao);
write_sfm(3,fen);
write_sfm(0,shi);
write_sfm1(8,ri);
write_sfm1(5,yue);
write_sfm1(2,nian);
write_sfm1(0,nian1);
write_sfm(13,fen1);
write_sfm(10,shi1);
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;}

void keyscan()
{if(s1==0)
{delay(5);
if(s1==0)
{s1num++;
while(!s1);
di();
if(s1num==1)
{TR0=0;
write_com(0x80+0x40+6);
write_com(0x0f);}
if(s1num==2)
{write_com(0x80+0x40+3);}
if(s1num==3)
{write_com(0x80+0x40+0);}
if(s1num==4)
{write_com(0x80+8);}
if(s1num==5)
{write_com(0x80+5);}
if(s1num==6)
{write_com(0x80+2);}
if(s1num==7)
{write_com(0x80);}
if(s1num==8)
{write_com(0x80+0x40+13);}
if(s1num==9)
{write_com(0x80+0x40+10);}
if(s1num==10)
{s1num=0;
TR0=1;
write_com(0x0c);}}}
if(s1num!=0)
{if(s2==0)
{delay(5);
if(s2==0)
{while(!s2);
di();
if(s1num==1)
{miao++;
if(miao==60)
miao=0;
write_sfm(6,miao);
write_com(0x80+0x40+6);
write_add(1,miao);}
if(s1num==2)
{fen++;
if(fen==60)
fen=0;
write_sfm(3,fen);
write_com(0x80+0x40+3);
write_add(2,fen);}
if(s1num==3)
{shi++;
if(shi==24)
shi=0;
write_sfm(0,shi);
write_com(0x80+0x40+0);
write_add(3,shi);}
if(s1num==4)
{if(((nian1*100+nian)%4==0&&(nian1*100+nian)%100!=0)||(nian1*100+nian)%400==0)
{goto ll1;}
if(yue==2)
{ri++;
if(ri==29)
ri=1;
write_sfm1(8,ri);
write_com(0x80+8);
write_add(4,ri);
goto ll2;}
ll1: if(yue==2)
{ri++;
if(ri==30)
ri=1;
write_sfm1(8,ri);
write_com(0x80+8);
write_add(4,ri);}

ll2: if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
{ri++;
if(ri==32)
ri=1;
write_sfm1(8,ri);
write_com(0x80+8);
write_add(4,ri);}
if(yue==4||yue==6||yue==9||yue==11)
{ri++;
if(ri==31)
ri=1;
write_sfm1(8,ri);
write_com(0x80+8);
write_add(4,ri);}}
if(s1num==5)
{yue++;
if(yue==13)
yue=1;
write_sfm1(5,yue);
write_com(0x80+5);
write_add(5,yue);}
if(s1num==6)
{nian++;
if(nian==100)
nian=0;
write_sfm1(2,nian);
write_com(0x80+2);
write_add(6,nian);}
if(s1num==7)
{nian1++;
if(nian1==100)
nian1=0;
write_sfm1(0,nian1);
write_com(0x80);
write_add(7,nian1);}
if(s1num==8)
{fen1++;
if(fen1==60)
fen1=0;
write_sfm(13,fen1);
write_com(0x80+0x40+13);
write_add(8,fen1);}
if(s1num==9)
{shi1++;
if(shi1==24)
shi1=0;
write_sfm(10,shi1);
write_com(0x80+0x40+10);
write_add(9,shi1);}}}
if(s3==0)
{delay(5);
if(s3==0)
{while(!s3);
di();
if(s1num==1)
{miao--;
if(miao==-1)
miao=59;
write_sfm(6,miao);
write_com(0x80+0x40+6);
write_add(1,miao);}
if(s1num==2)
{fen--;
if(fen==-1)
fen=59;
write_sfm(3,fen);
write_com(0x80+0x40+3);
write_add(2,fen);}
if(s1num==3)
{shi--;
if(shi==-1)
shi=23;
write_sfm(0,shi);
write_com(0x80+0x40+0);
write_add(3,shi);}
if(s1num==4)
{if(((nian1*100+nian)%4==0&&(nian1*100+nian)%100!=0)||(nian1*100+nian)%400==0)
{goto lll1;}
if(yue==2)
{ri--;
if(ri==-1)
ri=28;
write_sfm1(8,ri);
write_com(0x80+8);
write_add(4,ri);
goto lll2;}
lll1: if(yue==2)
{ri--;
if(ri==-1)
ri=29;
write_sfm1(8,ri);
write_com(0x80+8);
write_add(4,ri);}

lll2: if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
{ri--;
if(ri==-1)
ri=31;
write_sfm1(8,ri);
write_com(0x80+8);
write_add(4,ri);}
if(yue==4||yue==6||yue==9||yue==11)
{ri--;
if(ri==-1)
ri=30;
write_sfm1(8,ri);
write_com(0x80+8);
write_add(4,ri);}}
if(s1num==5)
{yue--;
if(yue==-1)
yue=12;
write_sfm1(5,yue);
write_com(0x80+5);
write_add(5,yue);}
if(s1num==6)
{nian--;
if(nian==-1)
nian=99;
write_sfm1(2,nian);
write_com(0x80+2);
write_add(6,nian);}
if(s1num==7)
{nian1--;
if(nian1==-1)
nian1=99;
write_sfm1(0,nian1);
write_com(0x80+0x40+8);
write_add(7,nian1);}
if(s1num==8)
{fen1--;
if(fen1==-1)
fen1=59;
write_sfm(13,fen1);
write_com(0x80+0x40+13);
write_add(8,fen1);}
if(s1num==9)
{shi1--;
if(shi1==-1)
shi1=23;
write_sfm(10,shi1);
write_com(0x80+0x40+10);
write_add(9,shi1);}}}

if(s4==0)
{delay(5);
if(s4==0)
{while(!s4);
TR0=1;
s1num=0;
write_com(0x0c);
setshi=read_add(8);
setfen=read_add(9);}}}
if(s5==0)
{delay(5);
if(s5==0)
{while(!s5);
guanjiao=0;
flag=0;
deng=1;}}}
void main()
{ init0();
while(1)
{ keyscan();
if((shi==shi1)&&(fen==fen1)&&flag)
{guanjiao=1;deng=0;}
if((shi!=shi1)||(fen!=fen1))
{flag=1;}
if(count==20)
{ count=0;
miao++;
if(miao>59)
{ miao=0;
fen++;
if(fen>59)
{fen=0;
shi++;
if(shi>23)
{shi=0;
ri++;

{
if(((nian1*100+nian)%4==0&&(nian1*100+nian)%100!=0)||(nian1*100+nian)%400==0)
{goto loop1;}
if(yue==2)
{if(ri>28)
{ri=1;yue++;goto loop2;}}
loop1: if(yue==2)
{if(ri>29)
{ri=1;yue++;}}

loop2: if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
{if(ri>31)
{ri=1;yue++;}}
if(yue==4||yue==6||yue==9||yue==11)
{if(ri>30)
{ri=1;yue++;}}


if(yue>12)
{yue=1;
nian++;
if(nian>99)
{nian=0;
nian1++;
write_sfm1(0,nian1);
write_add(7,nian1); }
write_sfm1(2,nian);
write_add(6,nian); }
write_sfm1(5,yue);
write_add(5,yue);}
write_sfm1(8,ri);
write_add(4,ri);}
write_sfm(0,shi);
write_add(3,shi);}
write_sfm(3,fen);
write_add(2,fen);}
write_sfm(6,miao);
write_add(1,miao);}} }

void timer0() interrupt 1
{TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;}

相关推荐