课程设计83287.docx
《课程设计83287.docx》由会员分享,可在线阅读,更多相关《课程设计83287.docx(21页珍藏版)》请在冰豆网上搜索。
课程设计83287
天津职业技术师范大学电子工程学院
电子信息工程
课程设计报告
同组学生姓名(学号):
石富友(09900100106)
卢志锋(0990*******)
王震(0990*******)
班级:
电信1001班
任务分工:
卢志锋负责电路焊接及调试、石富友和王震负责查找资料、编程序和撰写报告总结
设计时间:
2013年1月7日——2013年1月18日
指导教师:
薛召军、丁学文
题目:
基于单片机的电子万年历设计
二、方案论证选择3
三、原理设计(或基本原理)3
四、电路仿真5
五、方案实现与测试(或调试)7
六、课程设计小结
七、参考文献
一课程设计的目的和要求(含设计指标)
1、显示年月日时分秒及星期信息。
2、具有可调整日期和时间功能
3、增加闰年计算功能
二方案论证和选择
(1)单片机芯片的选择方案和论证
方案一:
采用STC89C52,片内ROM全都采用FlashROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全该芯片内部存储器为8KBROM存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯片造成损坏。
所以选择采用STC89C52作为主控制系统.
方案二:
采用89C51芯片作为硬件核心,采用FlashROM,内部具有4KBROM存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的多次拔插会对芯片造成一定的损坏。
(2)时钟芯片的选择方案和论证
方案一:
直接采用单片机定时计数器提供秒信号,使用程序实现年、月、日、星期、时、分、秒计数。
采用此种方案虽然减少芯片的使用,节约成本,但是,实现的时间误差较大。
所以不采用此方案。
方案二:
采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、日、周、月、年以及闰年补偿的年进行计数,而且精度高,位的RAM做为数据暂存区,工作电压2.5V~5.5V范围内,2.5V时耗电小于300nA.,但找不到这种芯片,所以本设计不采用这种芯片。
三原理设计(或基本原理)
(1)微处理器
在设计过程中我使用12MHZ晶振与单片机8052相连接,通过软件编程的方法实现了以24小时为一个周期同时显示小时,分钟和秒的要求,该定时闹钟设有九个按键,使之具备了校时、定时功能。
利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据。
同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。
在PROTEUS软件环境下的8052芯片如图1所示:
图1PROTEUS软件环境下的8052芯片
(2)按键电路
由于我设计的是电子万年历,需要实现多种功能的显示,并要能够切换显示和调节年月日,因此,在设计过程中按键的设计就显得尤为重要。
在设计过程中我一共采用了4个按键,尽量在小的空间里实现最多的功能。
其中K1键是年月日与时间显示切换键,按下一次就能够更换一次显示位。
在调整显示环境下K2和K3键是显示调整位的的加1减1键,K4键实现清零,并提高万年历显示的精确性。
按键电路如图2所示:
图2按键电路
(3)电路框图
四方案实现
(1)程序流程框图
图-A主程序流程图
图-B计算阳历程序流程
图-C时间调整程序流程图
图-D阴历程序流程图
五调试
(1)硬件调试
电子万年历的电路系统较大,对于焊接方面更是不可轻视,庞大的电路系统中只要出于一处的错误,则会对检测造成很大的不便,而且电路的交线较多,对于各种锋利的引脚要注意处理,否则会刺被带有包皮的导线,则会对电路造成短路现象。
在本成电子万年历的设计调试中遇到了很多的问题。
回想这些问题只要认真多思考都是可以避免的,以下为主要的问题:
对万年历修改时间或日期时,有时LED数码管被屏蔽掉,造成不亮现象。
解决:
根据仪器的测试,发现电路的驱动能力不足,最后在DS1302时钟芯片的/CS、SCLK、RET端接入5.1K的上拉电阻后,电路的驱动能力才能满足,即可解决不亮现象。
(3)软件测试
电子成年历是多功能的数字型,可以看当前日期(阴、阳历),时间,还有温度的仪器。
电子成年历功能很多,所以对于它的程序也较为复杂,所以在编写程序和调试时出现了相对较多的问题。
最后经过多次的模块子程序的修改,一步一步的完成,最终解决了软件。
在软件的调试过程中主要遇到的问题如下:
1.烧入程序后,LED数码管显示闪动,而且亮度不均匀。
解决:
首先对调用的延时进行逐渐修改,可以解决显示闪动问题。
其次,由于本作品使作动态扫描方式显示的数字,动态扫描很快,人的肉眼是无法看出,但是调用的显示程序时,如果不在反回时屏蔽掉最后的附值,则会出现很亮的现象,所以在显示的后面加了屏蔽子令,最后解决了此问题。
2.修改时间、日期时没有农历没有自动对应上。
解决:
把不相关的程序暂时屏蔽,地农历的子程序独立调试,发现在调用农历自动更新时,对十进制和十六进制处理不好,所以会造成错乱。
最后把相应的十进制进行修改,使得可以与十六进制对应,最后解决了此问题.
(4)测试结果分析与结论
1测试结果分析
1.在测试中遇到发光二极管、LED数码管为不显示时,首先使用试测仪对电路进行测试,观察是否存在漏焊,虚焊,或者元件损坏.
2.LED数码管显示不正常,还有亮度不够,首先使用试测仪对电路进行测试,观察电路是否存在短路现象。
查看烧写的程序是否正确无误,对程序进行认真修改。
2测试结论
经过多次的反复测试与分析,可以对电路的原理及功能更加熟悉,同时提高了设计能力与及对电路的分析能力.同时在软件的编程方面得到更到的提高,对编程能力得到加强.同时对所学的知识得到很大的提高与巩固.
(5)程序
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
ucharcodescan_cursor[4]={0xf7,0xfb,0xfd,0xfe};
uchardatadisplay[4]={0x3f,0x3f,0x3f,0x3f};
ucharcodeSeg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xffb};
ucharcodeSegbit[]={~(1<<0),~(1<<1),~(1<<2),~(1<<3)};
uchardatams50=0x00,con=0x00,con1=0x00,con2=0x00,con3=0x00;
sbitK1=P1^7;
sbitK2=P1^6;
sbitK3=P1^5;
sbitK4=P1^4;
ucharflag;
uintmsec;
uintsec;
uintmin=41;
uinthour=21;
uintday=15;
uintmonth=7;
uintyearl=11;
uintyearh=20;
uinttcnt;
uintcursor=0;
uchara=0xff;
voiddelay1ms(uintt)
{
uinti;
while(t--)
{for(i=0;i<125;i++);}
}
voidKscan()
{
uchari,j;
for(i=248;i>0;i--);
for(j=248;j>0;j--);
}
voidtemp(ucharL1,ucharL2,ucharL3,ucharL4)
{
if(cursor==2&&(flag))
{
P2=Segbit[3]|a;
P0=L1;
delay1ms
(1);
}
else
{
P2=Segbit[3];
P0=L1;
delay1ms
(1);
}
if(cursor==1&&(flag))
{
P2=Segbit[1]|a;
P0=L3;
delay1ms
(1);
}
else
{
P2=Segbit[1];
P0=L3;
delay1ms
(1);
}
if(cursor==2&&(flag))
{
P2=Segbit[2]|a;
P0=L2;
delay1ms
(1);
}
else
{
P2=Segbit[2];
P0=L2;
delay1ms
(1);
}
if(cursor==1&&(flag))
{
P2=Segbit[0]|a;
P0=L4;
delay1ms
(1);
}
else
{
P2=Segbit[0];
P0=L4;
delay1ms
(1);
}
}
main()
{
TMOD=0x02;
TH0=0x06;
TL0=0x06;
TR0=1;
ET0=1;
EA=1;
while
(1)
{
if(K1==0){
Kscan();
if(K1==0)
{
while(!
K1);
Kscan();
cursor++;
if(cursor>2)
{
cursor=0;
}
}
}
if(cursor){
if(K2==0)
{
Kscan();
if(K2==0)
{
if(1==flag)
{
if(cursor==1)
{
if(K2==0)
{
while(!
K2);
Kscan();
min++;
if(min==60)min=0;
}
}
if(cursor==2)
{
while(!
K2);
Kscan();
hour++;
if(hour==24)hour=0;
}
}
elseif(2==flag)
{
if(cursor==1)
{
while(!
K2);
Kscan();
day++;
if(day==32)day=1;
}
if(cursor==2)
{
while(!
K2);
Kscan();
month++;
if(month==13)
month=1;
}
}
elseif(3==flag)
if(cursor==1)
{
while(!
K2);
Kscan();
yearl++;