实训报告.docx
- 文档编号:8810882
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:23
- 大小:137.16KB
实训报告.docx
《实训报告.docx》由会员分享,可在线阅读,更多相关《实训报告.docx(23页珍藏版)》请在冰豆网上搜索。
实训报告
北京联合大学
实训报告
课程(项目)名称:
综合实训
学院:
师范学院专业:
电子信息工程
班级:
xx本科学号:
xxxxx
姓名:
xx成绩:
2012年12月27日
电子时钟设计
项目负责人:
xx
一、设计目的及意义
在日常生活中,大家见到的都是数码管制作的电子钟,它的价格低廉,而且设计系统方案比较成熟,由于客户没有特殊要求,所以我打算用液晶来实现电子时钟的设计,既可以满足客户的要求,还可以使我组成员多接触不同的现实器件,为以后的学习打下基础。
二、系统的功能描述
通过单片机及其外围少量扩展电路,利用软件与硬件结合完成了电子时钟的设计。
此系统的功能如下所示
1、能够显示时、分、秒。
2、计时误差不超过2秒/小时。
3、时、分、秒能够分别通过按键进行设置。
三、方案论证及思路。
(一)、编程语言
汇编语言是一种用文字助记符来表示机器指令的符号语言,是最接近机器码的一种语言。
其主要优点是占用资源少、程序执行效率高。
但是不同的CPU,其汇编语言可能有所差异,所以不易移植。
C语言是一种编译型程序设计语言,它兼顾了多种高级语言的特点,并具备汇编语言的功能。
C语言有功能丰富的库函数、运算速度快、编译效率高、有良好的可移植性,而且可以直接实现对系统硬件的控制。
C语言是一种结构化程序设计语言,它支持当前程序设计中广泛采用的由顶向下结构化程序设计技术。
此外,C语言程序具有完善的模块程序结构,从而为软件开发中采用模块化程序设计方法提供了有力的保障。
因此,使用C语言进行程序设计已成为软件开发的一个主流。
用C语言来编写目标系统软件,会大大缩短开发周期,
且明显地增加软件的可读性,便于改进和扩充,从而研制出规模更大、性能更完备的系统。
综上所述,用C语言进行单片机程序设计是单片机开发与应用的必然趋势。
所以我们在本次单片机电子时钟设计中应用C语言实现软件程序。
(二)、显示方案
方案一、使用数码管显示
数码管自身的优点是价格比较低廉,而且目前使用数码管的实现电子时钟设计比较成熟,实现起来比较方便,但是,由于单片机的实验板资源有限,只有六个数码管,虽然可以实现时分秒的显示,但是并不能满足我们的要求,同时显示时分秒和年月日。
方案二、使用液晶显示
液晶显示更加人性化,给用户更友好的感觉,并且可以同时显示时分秒和年月日,在用键盘调节的时候也比较方便,让用户可以清楚的看到,键盘如何调节实现时间的校准。
但液晶显示的费用相对会高些。
我们采用液晶显示方案。
(三)、时钟的年、月、日、时、分、秒的调节采用独立键盘。
四、具体实现
项目组人数2,两人共同负责硬件和软件
在项目中我们两个人通过商议沟通,一起了解单片机的功能并完成程序所要实现的功能。
程序要求设置、连接单片机各个管脚,以及单片机外扩晶振电路,复位电路扩展电路;单片机各个引脚的置位情况
(一)硬件设计(原理图、工作原理);
本项目采用89c52单片机芯片,在单片机外围扩展复位电路、晶振电路;采用1602液晶显示屏;使用有源蜂鸣器器件。
单片机管脚及原理图
40个引脚按引脚功能大致可分为4个种类:
电源、时钟、控制和I/O引脚。
⒈电源:
⑴VCC-芯片电源,接+5V;
⑵VSS-接地端;
⒉时钟:
XTAL1、XTAL2-晶体振荡电路反相输入端和输出端。
⒊控制线:
控制线共有4根,
⑴ALE/PROG:
地址锁存允许/片内EPROM编程脉冲
①ALE功能:
用来锁存P0口送出的低8位地址
②PROG功能:
片内有EPROM的芯片,在EPROM编程期间,此引脚输入编程脉冲。
⑵PSEN:
外ROM读选通信号。
⑶RST/VPD:
复位/备用电源。
①RST(Reset)功能:
复位信号输入端。
②VPD功能:
在Vcc掉电情况下,接备用电源。
⑷EA/Vpp:
内外ROM选择/片内EPROM编程电源。
①EA功能:
内外ROM选择端。
②Vpp功能:
片内有EPROM的芯片,在EPROM编程期间,施加编程电源Vpp。
⒋I/O线
80C51共有4个8位并行I/O端口:
P0、P1、P2、P3口,共32个引脚。
P3口还具有第二功能,用于特殊信号输入输出和控制信号(属控制总线)。
单片机复位电路—如下图所示:
因为单片机RST管脚给单片机复位的条件是:
给这个管脚两个机械周期的高电平,所以取c17=22u,R22=100,所以时间常数=RC,可以保证给RST管脚两个机械周期以上的高电平,便可以达到单片机复位要求。
此外,R22与R23组成分压电路,R22也作为RST管脚的限流电阻,保护RST管脚电流过大。
1602液晶显示原理图如下所示:
管脚设计及扩展:
第1脚:
VSS为地电源。
第2脚:
VDD接5V正电源。
第3脚:
VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:
RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:
R/W为读写信号线,高电平时进行读操作,低电平时进行写操作第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:
D0~D7为8位双向数据线。
第15脚:
背光源正极。
第16脚:
背光源负极。
蜂鸣器的电路如下图所示:
本项目中是用有源晶振,因为U6的内置电阻较小,所以串联R21=100欧做为限流电阻,保护U6。
采用有源晶振的好处是不需要外接起振电路,只要到达U6的电压,电流要求即可蜂鸣。
若是无源蜂鸣器,因其内部无振荡源,必须通过外部电路输入一个2KHZ~5KHZ的方波信号。
,增加了外围电路。
单片机外围晶振电路如下图所示:
为了达到正确的串行口波特率,使单片机与计算机可以正常工作,就必须用11.0952MHZ的晶振频率,这样计算出来的波特率才刚好匹配。
C18、C19两个负载电容的值是根据晶振频率而定的,因为晶振频率10MHZ,所以电容相对选择30P;一般单片机的晶振工作于并联谐振状态,也可以理解为谐振电容的一部分,晶振的频率就是在它提供的负载电容下测得的,能最大限度的保证频率值的误差。
也能保证温漂等误差。
两个电容的取值都是相同的,或者说相差不大,如果相差太大,容易造成谐振的不平衡,容易造成停振或者干脆不起振。
单片机液晶显示部分是由项目组另一个硬件成员完成的,这里我只是简单介绍
(二)、软件设计(程序及流程图)
程序流程图
程序如下:
#include
#defineucharunsignedchar//无符号字符型
#defineuintunsignedint//无符号整型
sbitdula=P2^6;//段选
sbitwela=P2^7;//位选
sbitrs=P3^5;//数据命令选择端
sbitlcden=P3^4;//使能端
sbits1=P3^0;//键盘按键
sbits2=P3^1;
sbits3=P3^2;
sbitrd=P3^7;//读写选择端
sbitbeep=P2^3;
ucharcount,s1num;
charmiao,shi,fen,nian,yue,ri;
ucharcodetable[]="2012-12-21";//年月日数组
ucharcodetable1[]="12:
12:
21";//时间数组
voiddelay(uintz)//延时子程序
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(ucharcom)//写地址
{
rs=0;//定义写指令函数
lcden=0;
P0=com;//给数据口赋值
delay(5);//延时5ms
lcden=1;
delay(5);//延时5ms
lcden=0;
}
voidwrite_date(uchardate)//写数据
{
rs=1;//定义写数据函数
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_sfm(ucharadd,uchardate)//写时分秒
{
ucharshi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
voidwrite_nyr(ucharadd,uchardate)//写年月日
{
charshi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x00+add);//设置显示位
write_date(0x30+shi);//送去液晶显示十位
write_date(0x30+ge);//耸起液晶显示个位
}
voidinit()//初始化
{
ucharnum;
dula=0;//关闭锁存端
wela=0;
lcden=0;
beep=0;
miao=21;
fen=12;
shi=12;
write_sfm(4,shi);
write_sfm(7,fen);
write_sfm(10,miao);
nian=12;
yue=12;
ri=21;
write_nyr(10,ri);
write_nyr(7,yue);
write_nyr(4,nian);
write_com(0x38);
write_com(0x0c);//不显示光标
write_com(0x06);//光标加一
write_com(0x01);//清零
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);//将数据写入第一行和第二行
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
write_com(0x80+0x00);
TMOD=0x01;//定时器函数假设是12mhz
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//开定时器0
TR0=1;//启动定时器
}
voidkeyscan()//键盘扫描
{
rd=0;//将矩阵键盘用作独立键盘
if(s1==0)
{
delay(5);
if(s1==0)
{s1num++;
while(!
s1);
if(s1num==1)
{
TR0=0;//时间停止
write_com(0x80+0x40+10);
write_com(0x0f);
}
}
if(s1num==2)
{
write_com(0x80+0x40+7);
}
if(s1num==3)
{
write_com(0x80+0x40+4);
}
if(s1num==4)
{
write_com(0x80+0x00+10);
}
if(s1num==5)
{
write_com(0x80+0x00+7);
}
if(s1num==6)
{
write_com(0x80+0x00+4);
}
if(s1num==7)
{
s1num=0;//清零
write_com(0x0c);
TR0=1;//开始计时
}
}
if(s1num!
=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!
s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);//指针移回
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
if(s1num==4)
{
ri++;
if(ri==30)
ri=0;
write_nyr(10,ri);
write_com(0x80+0x00+10);
}
if(s1num==5)
{
yue++;
if(yue==12)
yue=0;
write_nyr(7,yue);
write_com(0x80+0x00+7);
}
if(s1num==6)
{
nian++;
if(nian==2300)
nian=0;
write_nyr(4,nian);
write_com(0x80+0x00+4);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!
s3);
if(s1num==1)
{
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
if(s1num==4)
{
ri--;
if(ri==-1)
ri=29;
write_nyr(10,ri);
write_com(0x80+0x00+10);
}
if(s1num==5)
{
yue--;
if(yue==-1)
yue=11;
write_nyr(7,yue);
write_com(0x80+0x00+7);
}
if(s1num==6)
{
nian--;
if(nian==-1)
nian=99;
write_nyr(4,nian);
write_com(0x80+0x00+4);
}
}
}
}
}
voidmain()//主函数
{
init();
while
(1)
{
beep=0;
keyscan();
if(count==18)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
//beep=1;
delay(200);
ri++;
if(ri==30)
{
ri=1;
yue++;
if(yue==12)
{
yue=1;
nian++;
if(nian==2300)
{
nian=0;
}
write_nyr(4,nian);
}
write_nyr(7,yue);
}
write_nyr(10,ri);
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);
if(miao==10)
{
if(fen==01)
{
if(shi==00)
{
beep=1;
}
}
delay(200);
}
}
}
}
voidtimer0()interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
}
结论:
可以根据要求需显示出时、分、秒,计时误差不超过2秒/小时,时、分、秒能够分别通过按键进行设置调节,具有显示年、月、日的功能,并且同样可以对年、月、日通过键盘进行调节
成果:
这次设计对我们的知识要求较为综合,我们用到了单片机、数字电路、模拟电路、protel/proteuse、keil-c51等知识,以后应加强这方面的训练。
感受及体会
通过这几天的单片机的实训,我在理论的基础上更深刻的掌握了单片机的深层内容及实际生活中的应用,实训锻炼了自己动手能力和思维能力,还有在软件方面的编程能力,让我受益匪浅,同时也暴露出一些平时学习上的问题,让我深刻反思。
这些问题的发现将为我以后的学习和工作找明道路,查漏补缺为进一步学习作好准备。
通过实训,让我懂得了如何编写一些简单的程序,学会了如何制作单片机应用程序,并且可以在今后的日常生活中灵活运用。
实训中我知道了项目组成员之间互相帮助、合作的重要性。
我学到了更多解决问题的技巧,遇到困难时运用学过的相关知识和恰当的方法尽力去解决各个难题,通过自己不懈的努力与搭档的配合来完成这项团队任务。
在实训中我们用到了液晶显示屏,但当程序都没错误和问题的情问题的情况下显示屏不能显示任何东西,我们向老师求救才找到原因,最后还是老师帮助我们调节可调电阻的阻值才成功的显示了数字。
在这个过程中我深刻的感觉到自己对于单片机的了解太过浅薄,同时深刻的认识到理论与实际的差别。
这次实训不仅学到了更多专业知识,还训练了与别人协作、沟通的能力,从中找到了自己的缺点和不足并丰富了自己的知识开阔得视野,很高兴能有这样的实训经历,希望在今后可以多接触多学习。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)