搜索
您的当前位置:首页正文

单片机课程设计11

来源:榕意旅游网
目 录

摘要-----------------------------------------------------------------------------------------1 一. 课程设计目的和功能------------------------------------------------------1 二.

三.

四.

五.

六.

七.

课程设计题目描述和要求-----------------------------------------------1 数字电子时钟的意义和要求--------------------------------------------1 设计思路----------------------------------------------------------------------1 课程设计报告内容---------------------------------------------------------2 仿真电路图及结果和电路图--------------------------------------------5 系统时钟误差分析与软件调试问题及解决------------------------5

八. 总结----------------------------------------------------------------------------6

附加实物图--------------------------------------------------------------------------------7

附加程序-----------------------------------------------------------------------------------8

摘要

近年来随着计算机在社会领域的渗透和大规模集成电路的发展,单片机的应用正在不断地走向深入,本设计中以单片机的发展过程和发展方向为背景,中断的工作原理和操作方法,以单片机(AT89C52)为核心,结合相关的元器件数码显示器,再配以相应的软件,使它具有时,分,秒显示的功能,并且时,分,秒还可以调整。此次设计电子数字钟是为了解电子数字钟的原理,通过Keil C51编译软件,再利用Proteus仿真软件仿真原理图使我们掌握用单片机制作数字钟.

一、课程设计目的和实现功能

1、课程设计的目的

(1)巩固和加深对单片机原理知识的理解和运用。 (2)进一步提高学生综合运用所学知识的能力。

(3)培养学生综合分析问题、发现问题和解决问题的能力。 2、实现功能

(1)能够实现准确计时,以数字形式显示时、分、秒的时间。 (2)小时以24小时计时形式,能够调节时钟时间。

(3)闹钟功能,一旦走时到该时间,能以声或光的形式告警提示。 (4) 能够实现按键启动与停止功能。 3、设计背景

目前,单片机正朝着高性能和多品种方向发展趋势将是进一步向着CMOS化、低功耗、小体积、大容量、高性能、低价格和外围电路内装化等几个方面发展。下面是单片机的主要发展趋势。单片机应用的重要意义还在于,它从根本上改变了传统的控制系统设计思想和设计方法。从前必须由模拟电路或数字电路实现的大部分功能,现在已能用单片机通过软件方法来实现了。这种软件代替硬件的控制技术也称为微控制技术,是传统控制技术的一次革命。

单片机模块中最常见的是数字钟,数字钟是一种用数字电路技术实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有更更长的使用寿命,因此得到了广泛的使用。

二、课程设计题目描述和要求

1、方案论证,确定总体电路原理图。

2、元器件选择,设计PCB图(或用万能电路实验板搭线)。 3、绘制程序流程图,编写汇编语言源程序(或C语言源程序)。

4、安装调试,实现数字时钟的基本功能,即能正确显示时、分、并可调整时间。

三、数字电子时钟的意义和要求

1、数字电子钟的意义

数字钟是采用数字电路实现对.时,分,秒.数字显示的计时装置,广泛用于个人家庭,车站, 码头办公室等公共场所,成为人们日常生活中不可少的必需品,由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表, 钟表的数字化给

人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烘箱、通断动力设备、甚至各种定时电气的自动启用等,所有这些,都是以钟表数字化为基础的。因此,研究数字钟及扩大其应用,有着非常现实的意义。

2、数字电子钟的应用

数字钟已成为人们日常生活中:必不可少的必需品,广泛用于个人家庭以及车站、码头、剧场、办公室等公共场所,给人们的生活、学习、工作、娱乐带来极大的方便。由于数字集成电路技术的发展和采用了先进的石英技术,使数字钟具有走时准确、性能稳定、携带方便等优点,它还用于计时、自动报时及自动控制等各个领域。

四、课程设计报告内容

本课题整体设计方案分为硬件设计和软件设计。

硬件电路设计主要是用单片机和LED显示屏连接组成,另外加入按键,开关,蜂鸣器等;软件编程设计室用C编程,Keil C52调试。

1、设计原理

单片机编程,用单片机设计电路,由于使用软硬件结合的方式,所以电路结构简单、调试也相对方便。需要调节时间时,按动调节按钮,六位数码管显示实时时间。蜂鸣器整点报时和定时时间报时。

2、元器件选择 AT89S52;7407;LED(双位共阴);按键;电阻排;蜂鸣器;石英晶振12M;30pF;0.1uF;10uF电容。

3、AT89C52是一个低电压,高性能CMOS 8位单片机,片内含4k bytes的

可反复擦写的Flash只读程序存储器和128 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-52指令系统,片内置通用8位中央处理器和Flash存储单元,内置功能强大的微型计算机的AT89C52提供了高性价比的解决方案。

AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,AT89C52可以按照常规方法进行编程,但不可以在线编程(S系列的才支持在线编程)。其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。 AT89C52主要功能特性:

· 兼容MCS51指令系统 · 8k可反复擦写(>1000次)Flash ROM · 32个双向I/O口 · 256x8bit内部RAM

· 3个16位可编程定时/计数器中断 · 时钟频率0-24MHz · 2个串行中断 · 可编程UART串行通道

· 2个外部中断源 · 共8个中断源 · 2个读写中断口线 · 3级加密位

· 低功耗空闲和掉电模式 · 软件设置睡眠和唤醒功能

4、共阴极数码管

数码管管脚图,可以忽略型号,基本通用。 数字对应数码管显示控制转换字节

显示--HGFE,DCBA--编码(共阴编码) 0 --0011,1111--0x3F; 1 --0000,0110--0x06; 2 --0101,1011--0x5B; 3 --0100,1111--0x4F; 4 --0110,0110--0x66; 5 --0110,1101--0x6D; 6 --0111,1101--0x7D; 7 --0000,0111--0x07; 8 --0111,1111--0x7F; 9 --0110,1111--0x6F;

5、单片机数字时钟参考电路原理。

五、设计思路

1、芯片介绍

STC89C51是采用8051核的ISP(In System Programming)在系统可编程芯片,最高工作时

钟频率为80MHz,片内含8K Bytes的可反复擦写1000次的Flash只读程序存储器,器

件兼容标准MCS-51指令系统及80C51引脚结构,芯单片机课程设计报告5片内集成了通用8

位中央处理器和ISP Flash存储单元,具有在系统可编程(ISP)特性,配合PC端的控制程序即可将用户的程序代码下载进单片机内部,省去了购买通用编程器,而且速度更快。

VCC:电源。

GND:接地。

P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。

P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。

P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信

号。P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。P3口也可作为AT89C51的一些特殊功能口,如下表所示:

口管脚备选功能P3.0 RXD(串行输入口) P3.1 TXD(串行输出口) P3.2 /INT0(外部中断0) P3.3 /INT1(外部中断1)

P3.4 T0(记时器0外部输入) P3.5 T1(记时器1外部输入)

P3.6 /WR(外部数据存储器写选通) P3.7 /RD(外部数据存储器读选通)

P3口同时为闪烁编程和编程校验接收一些控制信号。

RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期 的高电平时间。 ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在

FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE 端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而

要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在

SFR8EH地址上置0。此时,ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。

PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。

EA/VPP:当/EA保持低电平时,则在此期间外部程序存储(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时, /EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。

2、显示电路

就时钟而言,通常可采用液晶显示或数码管显示。由于一般的段式液晶屏,需要专门的驱动电路,而且液晶显示作为一种被动显示,可视性相对较差;对于具有驱动电路和微处理器接口的液晶显示模块(字符或点阵),一般多采用并行接口,对微处理器的接口要求较高占用资源多。另外,89C2051本身无专门的液晶驱动接口,因此,本时钟采用数码管显示方式。数码管作为一种主动显示器件,具有亮度高、价格便宜等优点,而且市场上也有专门的时钟显示组合数码管。

对于实时时钟而言,显示显然是另一个重要的环节。通常LED显示有两种方式:动态显示和静态显示。静态显示的优点是程序简单、显示亮度有保证、单片机CPU的开销小,节约CPU的工作时间。但占有I/O口线多,每一个LED都要占有一个I/O口,硬件开销大,电路复杂需要几个LED就必须占有几个并行口,比较适用于LED数量较少的场合。当然当LED数量较多的时候,可以使用单片机的串行口通过移位寄存器的方式加以解决,但程序编写比较麻烦。

六、仿真电路图及结果和电路图

七、系统时钟误差分析与软件调试问题及解决

时间是一个基本物理量,具有连续、自动流逝、不重复等特性。我国时间基准来自国家授时中心,人们日常使用的时钟就是以一定的精度与该基准保持同步的。结合时间概念和误

差理论,可以定义电子钟的走时误差S=S1-S2,S1表示程序实际运行计算所得的秒;S2表示客观时间的标准秒。S>0时表示电子钟秒单元数值刷新滞后,即走时误差为“慢”;反之,S<0表示秒单元数值的刷新超前,即走时误差为“快”。

本次设计的单片机电子钟系统中,其误差主要来源包括晶体频率误差,定时器溢出误差,延迟误差。晶体频率产生震荡,容易产生走时误差;定时器溢出的时间误差,本应这一秒溢出,但却在下一秒溢出,造成走时误差;延迟时间过长或过短,都会造成与基准时间产生偏差,造成走时误差。

软件程序的调试一般可以将重点放在分模块调试上,统调是最后一环。软件调试可以采取离线调试和在线调试两种方式。前者不需要硬件仿真器,可借助于软件仿真器即可;后者一般需要仿真系统的支持。本次课题,Keil软件来调试程序,通过各个模块程序的单步或跟踪调试,使程序逐渐趋于正确,最后统调程序。

仿真部分采用protus 6 professional软件,此软件功能强大且操作较为简单,可以很容易的实现各种系统的仿真。

首先打开protus 6 professional软件,在元件库中找到要选用的所有元件,然后进行原理图的绘制;绘制好后再选择wave6000已经编译好的*.hex文件,选择运行,观察显示结果,根据显示的结果和课题的要求再修改程序,再运行查,直到满足要求。

八、总结

两个星期的单片机课程设计很快就结束了,在这两周当中,虽然开始有点困难,但是经过我们们分工合作,合理地进行设计安排,再加上老师的耐心指导,我们们终于顺利地完成了本次单片机课程设计,同时也学到了很多东西。

在本次课程设计中,我们通过动手实践操作,自己焊接电路,接线,进一步学习和掌握了单片机原理的有关知识,特别是程序的编程方面,加深了对单片机原理及应用技术的认识,进一步巩固了对单片机知识的理解,也掌握简单单片机应用系统的设计、制作、调试。在设计时根据课题要求,复习相关的知识,查询相关的资料。根据实验条件,找到适合的方案,然后购买需要的元器件及工具,然后进行制作和焊接。这次的单片机课程设计重点是通过实践操作和理论相结合,提高动手实践能力,提高科学的思维能力。在这两周的实践过程中,是我大学生活中一个难忘的经历,让我的生活也得到了充实。

单片机作为我们们的主要专业课之一,虽然在大三开学初我们对这门课并没有什么兴趣,觉得那些程序枯燥乏味,但在这次课程设计后我们发现自己在一点一滴的努力中对单片机的兴趣也在逐渐增加。我觉得做单片机课程设计是十分有意义的,而且是十分必要的。虽然过去从未独立应用过它们,但在学习的过程中带着问题去学我发现效率很高,这可能是我做这次课程设计的又一收获。要做好一个课程设计,就必须做到:在设计程序之前,对所用单片机的内部结构有一个系统的了解,知道该单片机内有哪些资源;要有一个清晰的思路和一个完整的的软件流程图;在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,在设计课程过程中遇到问题是很正常的,我们应该学会去解决问题,找到问题的根源,这是很重要的,我们还要学会把我们学到的课本知识运用但实际中,这才是我们学习的目的。

在完成单片机课程设计后,我发现我们还有许多不足,所学的知识也还远远不够,我们还需要去提升自己。但通过这两周的实践,不仅仅增强了我们们的动手能力,提高和巩固了单片机方面的知识,特别是软件方面。也让我明白了理论和实践的差距。

总之,在此次的课程设计中,我们不仅动手、动脑,也学会了不少东西,同时,谢谢老师给我们的设计带来建议、意见。

参考书目:

[1] 赵伟军,《Protel99se教程》,北京,人民邮电出版社,1996年 [2]蒋辉平周国雄,《单片机原理与应用设计》,北京,北京航空航天大学出版社,2007年

[3] 单片机原理及应用技术,西安电子科技大学出版社

附加程序图及实物图

附加程序

#include unsigned char led[12]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x00,0xFF}; //用一维数组定义0-9

unsigned char a[4];

unsigned char second=0,minute=0,hour=12; unsigned char minute1=0,hour1=0,zdbs=0;

unsigned char b[4]={0xFE,0xFB,0xEF,0xBF}; //扫描 unsigned char k=0;

unsigned int temp; // 记录1000毫秒为1秒的变量

unsigned char M,S_flag,md=0; //M是模式,更新时间的4种模式加上正常模式 S_flag闪烁标志

sbit K1=P3^0; //设置键 sbit K2=P3^1; //增加键 sbit K3=P3^2; //减少键

sbit BEEP=P1^3; //蜂鸣器报警

void delay(unsigned n) //0.2毫秒 { int x,y;

for(x=0;xvoid init() //定时器初始化 { M=0;

S_flag=0; //闪烁标志位

TMOD=0x10; //定时器1以方式1定时

TH1=0xfc; TL1=0x18;

EA=1; //打开总中断

ET1=1; //允许定时器1中断

TR1=1; //开启定时器1 (开始定时计数) }

void time1() interrupt 3 //定时器1中断函数 {

TH1=0xfc; //定时1ms TL1=0x18; temp++;

if(temp==1000) //配合定时器定时1s { temp=0;

second++; }

if(temp==950) {

md=~md; }

if(second==60) {

second=0; if(minute<59) { minute++; }

else {

minute=0; hour++;

hour%=24; } }

if((hour1==hour&&minute1==minute&&second<30)||(zdbs==minute&&second<1)) //闹钟时间到

{

BEEP=~BEEP; }

else { BEEP=1; }

if(temp%250==0) //每250ms

S_flag=!S_flag; //闪烁标志位取反 if(k==4) k=0; P0=a[k];

P2=b[k++]; delay(3);

P2=0xff; }

void display() //显示函数 {

switch(M) {

case 0: {

a[0]=led[hour/10]; //秒 if(md==0) {

a[1]=led[hour%10]&0x7f; } else {

a[1]=led[hour%10]; }

a[2]=led[minute/10]; //分 a[3]=led[minute%10]; }break; case 1: {

if(S_flag==1) {

a[0]=led[hour/10]; a[1]=led[hour%10]; } else {

a[0]=led[11]; a[1]=led[11]; }

a[2]=led[minute/10]; a[3]=led[minute%10]; }break; case 2: {

a[0]=led[hour/10]; a[1]=led[hour%10]; if(S_flag==1)

{

a[2]=led[minute/10]; a[3]=led[minute%10]; } else {

a[2]=led[11]; a[3]=led[11]; } }break; case 3: {

if(S_flag==1) {

a[0]=led[hour1/10]; a[1]=led[hour1%10]; } else {

a[0]=led[11]; a[1]=led[11]; }

a[2]=led[minute1/10]; a[3]=led[minute1%10]; }break; case 4: {

a[0]=led[hour1/10]; a[1]=led[hour1%10]; if(S_flag==1) {

a[2]=led[minute1/10]; a[3]=led[minute1%10]; } else {

a[2]=led[11]; a[3]=led[11]; } }

} }

void key_prc() //按键

{

if(K1==0) {

delay(10); //延时去抖 if(K1==0) //按K1进行模式切换 { M++;

if(M==5) M=0; }

while(!K1);//等待按键释放 } if(M!=0) {

switch(M) {

case 1: //模式1——调时 {

if(K2==0) {

delay(10); //延时去抖 if(K2==0) //加键按下 {

if(hour<23) hour++; else hour=0; }

while(!K2); //等待按键释放 }

if(K3==0) {

delay(10); if(K3==0) {

if(hour> 0) hour--; else hour=23; }

while(!K3); }

} break;

case 2: //模式2——调分 { if(K2==0) {

delay(10); if(K2==0) {

if(minute<59) minute++; else minute=0; }

while(!K2); }

if(K3==0) {

delay(10); if(K3==0) {

if(minute>0) minute--; else minute=59; }

while(!K3); } } break;

case 3: //模式3——闹钟调时 { if(K2==0) {

delay(10); if(K2==0) {

if(hour1<23) hour1++; else hour1=0; }

while(!K2); }

if(K3==0) {

delay(10); if(K3==0) {

if(hour1>0) hour1--; else hour1=23; }

while(!K3); } } break;

case 4: //模式4——闹钟调分 {

if(K2==0) {

delay(10);

minute1--; }

} }

} }

void main() {

BEEP=1; init(); while(1) {

key_prc(); display(); } }

if(K2==0) {

if(minute1<59) minute1++; else minute1=0; } while(!K2); } if(K3==0) {

delay(10); //延时去抖 if(K3==0) //减键按下 { if(minute1>0) else minute1=59; while(!K3); } break;

因篇幅问题不能全部显示,请点此查看更多更全内容

Top