电子万年历实验报告.docx
《电子万年历实验报告.docx》由会员分享,可在线阅读,更多相关《电子万年历实验报告.docx(28页珍藏版)》请在冰豆网上搜索。
电子万年历实验报告
重庆电力高等专科学校
计算机科学系
实训报告
课程名称
单片机应用技术
实验名称
电子万年历
班级
信息0911
姓名
廖林
学号
200903020243
教师
任照富
日期
2010-12-28
地点
一教七机房
实验成绩评定:
一、实训任务:
1、看实训要求,计划出自己实训所要用元件,在网上查找资料。
2、思考仿真原理图,然后画出来(具体I/O口暂时不确定)。
3、在网上找一些程序,然后自己改一些,进行编译。
4、编译无误之后,跟原理图相联系,完成最终的仿真图。
5、进行最后的改写,把程序和仿真原理图确定下来。
6、根据仿真图形,制作出实物图。
7、在实物制作过程中,进行电路检查和最后的调试。
二、实训要求:
要求:
能显示阳历的年、月、日、星期、时、分、秒;
能显示阴历的年、月、日;
能进行日期、时间的调整。
扩展:
能显示当前温度;
有闹钟功能(至少2个)
选择DS1302时钟芯片,温度传感器采用DS18B20数字温度传感器。
三、实训环境(软件、硬件):
软件:
keilprotues7.5
硬件:
计算机2单片机的应用
四、实训意义:
在这快速发展的年代,时间对人们来说是越来越宝贵,在快节奏的生活时,人们往往忘记了时间,一旦遇到重要的事情而忘记了时间,这将会带来很大的损失。
因此我们需要一个定时系统来提醒这些忙碌的人,而数字化的钟表给人们带来了极大的方便。
由于单片机具有灵活性强、成本低、功耗低、保密性好等特点,所以电子日历时钟一般都以单片机为核心,外加一些外围设备来实现。
电子万年历作为电子类小设计不仅是市场上的宠儿,也是是单片机实验中一个很常用的题目。
因为它的有很好的开放性和可发挥性,因此对作者的要求比较高,不仅考察了对单片机的掌握能力更加强调了对单片机扩展的应用。
而且在操作的设计上要力求简洁,功能上尽量齐全,显示界面也要出色。
所以,电子万年历无论作为竞赛题目还是毕业设计题目都是很有价值。
对于这个实验项目,我们还要有一些其他的基本知识掌握和意义:
(1)在学习了《数字电子技术》和《单片机原理及接口技术》课程后,为了加深对理论知识的理解,学习理论知识在实际中的运用,为了培养动手能力和解决实际问题的经验,了解专用时钟芯片DS1302,并会用DS1302芯片开发时钟模块,应用到其他系统中去。
熟悉keil和protues软件调试程序和仿真.
(2)通过实验提高对单片机的认识;
(3)通过实验提高焊接、布局、电路检查能力;
(4)通过实验提高软件调试能力;
(5)进一步熟悉和掌握单片机的结构及工作原理。
(6)通过课程设计,掌握以单片机核心的电路设计的基本方法和技术。
(7)通过实际程序设计和调试,逐步掌握模块化程序设计方法和调试技术。
(8)通过完成一个包括电路设计和程序开发的完整过程,了解开发一单片机应用系统的全过程,为今后从事相应工作打下基础。
五、实训工作:
由于自己是组长,所以在实训期间要多注意一下,实训期间我的主要工作有:
1、看实训要求,计划出自己实训所要用元件,在网上查找资料,同时要求组员也做同样的工作,最后再综合起来。
2、思考仿真原理图,然后画出来(具体I/O口暂时不确定)。
3、在网上找一些程序,然后自己改一些,进行编译。
4、编译无误之后,跟原理图相联系,完成最终的仿真图。
5、进行最后的改写,把程序和仿真原理图确定下来。
6、根据仿真图形,制作出实物图,并进行电路的检查。
六、实训功能:
实训成品暂时还没有成功,所以只能够写出计划实现功能:
1、能够显示公历的年、月、日,还有时、分、秒和温度。
2、能够进行时间的调整。
七、硬件设计:
仿真电路运用的是总线类型的52单片机,单片机部分如上图。
此实训的显示部分用的是数码管,并且是共阴极数码管,其中段选接在P0口,在P0口用了一个上拉电阻,拉高P0口的电压,以使数码管正常工作。
公历的年、月、日的位选接在的是P2口,从左到右分别是P2.7。
P2.6。
P2.5。
P2.4。
P2.3。
P2.2。
P2.1。
P2.0。
时间与温度的位选接在P1口上面,从左到右分别,从上到下分别是P1.7。
P1.6。
P1.5。
P1.4。
P1.3。
P1.2。
P1.1。
P1.0。
上图为按键设置,最上面一个为设置,下面分别是调高与调低。
DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C。
可选更小的封装方式,更宽的电压适用范围。
分辨率设定,及用户设定的报警温度存储在EEPROM中,掉电后依然保存。
DS18B20的性能是新一代产品中最好的!
性能价格比也非常出色!
DS1822与DS18B20软件兼容,是DS18B20的简化版本。
省略了存储用户定义报警温度、分辨率参数的EEPROM,精度降低为±2°C,适用于对性能要求不高,成本控制严格的应用,是经济型产品。
继"一线总线"的早期产品后,DS1820开辟了温度传感器技术的新概念。
DS18B20和DS1822使电压、特性及封装有更多的选择,让我们可以构建适合自己的经济的测温系统。
DQ接在P3.7上面。
上图为DS1302时钟部分,上图接有晶振和电容,但实物当中没有电容,所以有些功能不能够实现。
DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式。
此外,DS1302还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。
时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。
DS1302与RAM相关的寄存器分为两类:
一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。
最后上总图:
八、程序流程:
九、源程序:
Wannianli.c
/**包含头文件**/
#include
#include"config.h"
#include"ds1302.h"
#include"ds18b20.h"
#defineduanxuanP0
sbitdian=P3^3;
sbitkey1=P3^0;
sbitkey2=P3^1;
sbitkey3=P3^2;//#include"key.h"
#defineuintunsignedint
#defineucharunsignedchar
#defineseg_time2
charReadValue,nian,yue,ri,shi,fen,miao,xingqi,key1n;
uinttemperature;
ucharcount,count1;
bitmode_flag;
bitset_mode=0;
charset_shi=0,set_fen=0;
uchar
codeSeg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极数码管显示0到9
uchartime=10;
voidkeyscan();
voiddelay_ms(uintz)
{uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);}
voidflash()
{ReadValue=ReadSet1302(0x81);//从秒寄存器读数据
miao=change(ReadValue);//数据转化
ReadValue=ReadSet1302(0x83);//从分寄存器读数据
fen=change(ReadValue);//数据转化
ReadValue=ReadSet1302(0x85);//从时寄存器读数据
shi=change(ReadValue);//数据转化
ReadValue=ReadSet1302(0x87);//从日寄存器读数据
ri=change(ReadValue);//数据转化
ReadValue=ReadSet1302(0x89);//从月寄存器读数据
yue=change(ReadValue);//数据转化
ReadValue=ReadSet1302(0x8d);//从年寄存器读数据
nian=change(ReadValue);//数据转化
temperature=ReadTemperature();
nian1;
duanxuan=Seg[2];
delay_ms(seg_time);
nian2;
duanxuan=Seg[0];
delay_ms(seg_time);
nian3;
duanxuan=Seg[nian/10];
delay_ms(seg_time);
nian4;
duanxuan=Seg[nian%10];
delay_ms(seg_time);
yue1;
duanxuan=Seg[yue/10];
delay_ms(seg_time);
yue2;
duanxuan=Seg[yue%10];
delay_ms(seg_time);
ri1;
duanxuan=Seg[ri/10];
delay_ms(seg_time);
ri2;
duanxuan=Seg[ri%10];
delay_ms(seg_time);
shi1;
duanxuan=Seg[shi/10];
delay_ms(seg_time);
shi2;
duanxuan=Seg[shi%10];
delay_ms(seg_time);
fen1;
duanxuan=Seg[fen/10];
delay_ms(seg_time);
fen2;
duanxuan=Seg[fen%10];
delay_ms(seg_time);
miao1;
duanxuan=Seg[miao/10];
delay_ms(seg_time);
miao2;
duanxuan=Seg[miao%10];
delay_ms(seg_time);
wendu1;
duanxuan=Seg[temperature%1000/100];
delay_ms(seg_time);
wendu2;
duanxuan=Seg[temperature%100/10];
delay_ms(seg_time);
}
unsignedcharWeekDay20(unsignedchary,unsignedcharm,unsignedchard)
{unsignedcharweek,day;
week=day>>5;//月星期数
day&=0x1f;//月天数
if((m<3)&&(y&0x03)){//平年
if(m==2)day--;//平年月天数
week++;//平年月表+1}
y=y+(y>>2);//年+年/4
week=(week+y+d+2)%7;//(星期=年+年/4+月表+2日)%7
return(week<<5)|day;//返回星期和月天数
}
voidflash_set()
{temperature=ReadTemperature();
shi1;
duanxuan=Seg[set_shi/10];
delay_ms(seg_time);
shi2;
duanxuan=Seg[set_shi%10];
delay_ms(seg_time);
fen1;
duanxuan=Seg[set_fen/10];
delay_ms(seg_time);
fen2;
duanxuan=Seg[set_fen%10];
delay_ms(seg_time);
wendu1;
duanxuan=Seg[temperature%1000/100];
delay_ms(seg_time);
wendu2;
duanxuan=Seg[temperature%100/10];
delay_ms(seg_time);}
voidINT_Init()
{//IP=0x05;//外部中断0和外部中断1设置为高优先级//IT0=1;//外部中断0为下降沿触发
//IT1=1;//外部中断1为下降沿触发
//EX0=1;//开外部中断0
//EX1=1;//开外部中断1
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
TR0=1;
EA=1;}
voidALL_Init()
{INT_Init();
P0=0xff;
P1=0xff;
P2=0xff;
mode_flag=0;}
/**函数功能:
主程序入口参数:
出口参数:
***/
voidmain(void)
{ALL_Init();
while
(1)
{if(set_mode==0)
{flash();}
else
{flash_set();}
keyscan();}}
voidkeyscan()
{/*key1n:
1:
调整闹钟分钟2:
调整闹钟小时3:
调整分钟
4:
调整小时5:
退出*/
if(key1==0)//---------------key1为功能键(设置键)
{delay_ms(5);//延时,用于消抖动
if(key1==0)//延时后再次确认按键按下
{while(!
key1);
key1n++;
if(key1n==6)
key1n=1;//设置按键共有秒、分、时、返回,4个功能循环
if(key1n<3)
{set_mode=1;}
if(key1n>2)
{set_mode=0;}}}/*-------加键key2-----*/
if(key1n!
=0&&(key1n!
=5))//当key1按下一下。
再按一下键才有效(按键次数不等于零)
{if(key2==0)//上调键
{delay_ms(5);
if(key2==0)
{while(!
key2);
switch(key1n)
{case1:
set_fen++;
if(set_fen==60)
set_fen=0;
break;
case2:
set_shi++;
if(set_shi==24)
set_shi=0;
break;
case3:
fen++;
if(fen==60)
fen=0;
WriteSet1302(0x82,((fen/10)<<4|(fen%10)));
break;
case4:
shi++;
if(shi==24)
shi=0;
WriteSet1302(0x84,((shi/10)<<4|(shi%10)));
break;}}}}/*--------加键key2-------*/
if(key1n!
=0&&(key1n!
=5))//当key1按下以下。
再按以下键才有效(按键次数不等于零)
{if(key3==0)//上调键
{delay_ms(5);
if(key3==0)
{while(!
key3);
switch(key1n)
{case1:
set_fen--;
if(set_fen<0)
set_fen=59;
break;
case2:
set_shi--;
if(set_shi<0)
set_shi=23;
break;
case3:
fen--;
if(fen<0)
fen=59;
WriteSet1302(0x82,((fen/10)<<4|(fen%10)));
break;
case4:
shi--;
if(shi<0)
shi=23;
WriteSet1302(0x84,((shi/10)<<4|(shi%10)));
break;}}}}}
config.h
#definenian1P2=0x7f;P1=0xff
#definenian2P2=0xbf;P1=0xff
#definenian3P2=0xdf;P1=0xff
#definenian4P2=0xef;P1=0xff
#defineyue1P2=0xf7;P1=0xff
#defineyue2P2=0xfb;P1=0xff
#defineri1P2=0xfd;P1=0xff
#defineri2P2=0xfe;P1=0xff
#defineshi1P1=0x7f;P2=0xff
#defineshi2P1=0xbf;P2=0xff
#definefen1P1=0xdf;P2=0xff
#definefen2P1=0xef;P2=0xff
#definemiao1P1=0xf7;P2=0xff
#definemiao2P1=0xfb;P2=0xff
#definewendu1P1=0xfd;P2=0xff
#definewendu2P1=0xfe;P2=0xff
Reg52.h
sfrP0=0x80;
sfrP1=0x90;
sfrP2=0xA0;
sfrP3=0xB0;
sfrPSW=0xD0;
sfrACC=0xE0;
sfrB=0xF0;
sfrSP=0x81;
sfrDPL=0x82;
sfrDPH=0x83;
sfrPCON=0x87;
sfrTCON=0x88;
sfrTMOD=0x89;
sfrTL0=0x8A;
sfrTL1=0x8B;
sfrTH0=0x8C;
sfrTH1=0x8D;
sfrIE=0xA8;
sfrIP=0xB8;
sfrSCON=0x98;
sfrSBUF=0x99;/*8052Extensions*/
sfrT2CON=0xC8;
sfrRCAP2L=0xCA;
sfrRCAP2H=0xCB;
sfrTL2=0xCC;
sfrTH2=0xCD;/*BITRegisters*//*PSW*/
sbitCY=PSW^7;
sbitAC=PSW^6;
sbitF0=PSW^5;
sbitRS1=PSW^4;
sbitRS0=PSW^3;
sbitOV=PSW^2;
sbitP=PSW^0;//8052only/*TCON*/
sbitTF1=TCON^7;
sbitTR1=TCON^6;
sbitTF0=TCON^5;
sbitTR0=TCON^4;
sbitIE1=TCON^3;
sbitIT1=TCON^2;
sbitIE0=TCON^1;
sbitIT0=TCON^0;/*IE*/
sbitEA=IE^7;
sbitET2=IE^5;//8052only
sbitES=IE^4;
sbitET1=IE^3;
sbitEX1=IE^2;
sbitET0=IE^1;
sbitEX0=IE^0;/*IP*/
sbitPT2=IP^5;
sbitPS=IP^4;
sbitPT1=IP^3;
sbitPX1=IP^2;
sbitPT0=IP^1;
sbitPX0=IP^0;/*P3*/
sbitRD=P3^7;
sbitWR=P3^6;
sbitT1=P3^5;
sbitT0=P3^4;
sbitINT1=P3^3;
sbitINT0=P3^2;
sbitTXD=P3^1;
sbitRXD=P3^0;/*SCON*/
sbitSM0=SCON^7;
sbitSM1=SCON^6;
sbitSM2=SCON^5;
sbitREN=SCON^4;
sbitTB8=SCON^3;
sbitRB8=SCON^2;
sbitTI=SCON^1;
sbitRI=SCON^0;/*P1*/
sbitT2EX=P1^1;//8052only
sbitT2=P1^0;//8052only/*T2CON*/
sbitTF2=T2CON^7;
sbitEXF2=T2CON^6;
sbitRCLK=T2CON^5;
sbitTCLK=T2CON^4;
sbitEXEN2=T2CON^3;
sbitTR2=T2CON^2;
sbitC_T2=T2CON^1;
sbitCP_RL2=T2CON^0;
#endif
Ds1302.h
#ifndefuint
#defineuintunsignedint
#endif
#ifndefuchar
#defineucharunsignedchar
#endif
sbitDATA=P3^6;//位定义1302芯片的接口,数据输出
sbitRST=P3^4;//位定义1302芯片的接口,复位端口
sbitSCLK=P3^5;//位定义1302芯片的接口,时钟输出端口
/**函数功能:
延时若干微秒*****/
voiddelaynus(ucharn)
{uchari;
for(i=0;i向1302写一个字节数据入口参数:
x**/
voidWrite1302(uchardat)
{uchari;
SCLK=0;//拉低SCLK,为脉冲上升沿写入数据做好准备//
delaynus
(2);//稍微等待,使硬件做好准备
for(i=0;i<8;i++)//连续写8个二进制位数据
{DATA=dat&0x01;//取出dat的第0位数据写入1302//delaynus
(2);//稍微等待,使硬件做好准备
SCLK=1;//上升沿写入数据//
delaynus
(2);//稍微等