基于51单片机的实时时钟设计8255扩展io口讲解.docx
《基于51单片机的实时时钟设计8255扩展io口讲解.docx》由会员分享,可在线阅读,更多相关《基于51单片机的实时时钟设计8255扩展io口讲解.docx(17页珍藏版)》请在冰豆网上搜索。
基于51单片机的实时时钟设计8255扩展io口讲解
摘要
单片计算机即单片微型计算机。
由RAM,ROM,CPU构成,定时,计数和多种接口于一体的微控制器。
它体积小,成本低,功能强,广泛应用于智能产业和工业自动化上。
而51系列单片机是各单片机中最为典型和最有代表性的一种。
通过本子课程设计掌握单片机的基本原理,加深对课堂知识的理解,从而达到学习、设计、开发单片机软硬的能力。
本设计主要设计了一个基于AT89C52单片机的电子时钟,由定时器定时并在数码管上显示相应的时间,通过中断和按键扫描实现对时间的停止、启动和设置调整。
应用Proteus软件实现了单片机电子时钟系统的设计与仿真。
该方法仿真效果真实、准确,节省了硬件资源。
关键字:
单片机;子时钟;键盘控制。
第一章51单片机简介
单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。
概括的讲:
一块芯片就成了一台计算机。
它的体积小、质量轻、价格便宜、为学习、应用和开发提供了便利条件。
同时,学习使用单片机是了解计算机原理与结构的最佳选择。
这种单片机的使用领域已十分广泛,如智能仪表、实时工控、通讯设备、导航系统、家用电器等,比方说用来控制路口红绿灯的亮灭公交车报站。
各种产品一旦用上了单片机,就能起到使产品升级换代的功效,常在产品名称前冠以形容词——“智能型”,如智能型洗衣机等。
1.151系列单片机每部结构
51系列单片机中主要有8031、8051、8751三种机型,它们的指令系统和芯片引脚完全兼容,只是片内程序存储器(ROM)有所不同,其中8031片内没有ROM,8051片内有4k的掩膜ROM,8751片内有4k的紫外线可擦除ROM。
其主要资源有:
8位CPU、片内带震荡器及时钟电路、128B片内数据存储器、4K片内程序存储器(8031无)、21B特殊功能寄存器、4个8位的IO口、一个全双工串行接口、两个16位定时器、中断系统有5个中断源、111条指令。
其内部结构如图1.1所示。
图1.1单片机内部结构
1.251单片机的封装及引脚
在封装上,51单片机有常用的三种封装:
PQFP-44、DIP-40和PLCC-44。
我们学习中最常见的封装为DIP-40型的封装,其封装图如图1.2所示。
该封装的单片机共有40个引脚,其中可分为端口线电源线和控制线三类。
端口线有32条,为4个并行的8为IO端口,由于地址或数据的传送,其中P0口为开漏输出,在作为通用IO使用时需要加上上拉电阻。
在外部扩展时分时提
供系统的数据总线和地址总线;P2口可作为通用IO接口和外部扩展时的地址总线;P1口只作为通用IO口使用;P3口作为通用IO口外,还附有第二功能,如表1.1所示。
表1.1
P3口的位
第二功能
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(片外数据存储器读允许)
电源线有两根:
VCC为+5V电源线,GND为接地。
控制线有6根,其中EA为片外存储器访问选择线;PSEN为片外ROM选通线;RST为复位线;XTAL1和XTAL2为片内震荡电路输入线;ALE为地址锁存允许线。
图1.2单片机引脚图
第二章实时时钟的设计方案
本课设制作的实时时钟由单片机外扩一片8255A芯片,用8255A的PA口和PB口控制6位8段共阳数码管显示时钟,并由定时器控制时钟精准的计时,中断和按键扫描共同完成对时间的初始化、启停和调整。
整体完成实时时钟的设计,精准的计时。
整体仿真原理图见附录1。
2.1单片机最先系统
单片机最小系统就是能使单片机工作的最少的器件构成的系统。
对于本课设所使用的AT89C52来讲,其最小系统为AT89C52单片机芯片、时钟电路和复位电路,器仿真原理图如图2.1所示。
图2.1单片机最小系统
2.28255A模块
8255A是一种可编程的I/O接口芯片,可以与MCS-51系统单片机以及外设直接相连,广泛用作外部并行I/O扩展接口。
8255A内部由PA、PB、PC三个8位可编程双向I/O口,A组控制器和B组控制器,数据缓冲器及读写控制逻辑四部分电路组成。
数据总线(8条):
D0~D7,用于传送CPU和8255A间的数据、命令和状态字。
控制总线(6条):
RESET:
复位线,高电平有效。
/CS:
片选线,低电平有效。
/RD、/WR:
/RD为读命令线,/WR为写命令线,皆为低电平有效。
A0、A1:
地址输入线:
用于选中PA、PB、PC口和控制寄存器中哪一个工作。
本次课设中8255A的设计如图2.2。
图2.28255A连接图
其中DO~D7连接在单片机的外扩数据总线P0口上,WR和RD分别接在单片机的WR和RD口,RESET接在单片机RST上,CS、A1和A0分别接在P2.7、P2.6和P2.5上,从而8255A的A口地址可为0000H,B口地址可为2000H,C口地址可为4000H控制口地址可为6000H。
2.3数码管显示模块
本课设采用8段共阳数码管,其中abcdefg七段构成日字形dp段位小数点位,当阳极那端为高电平时相应的段为低电平则该段点亮,从而显示不同的数字和符号。
本次利用8255A控制数码管,其连接图如图2.3所示。
图2.3数码管显示原理图
2.4时间调节模块
时间调节时利用中断和按键扫描来实现的,其连接图如图2.4所示。
图2.4按键连接图
其中,定时器启停有外部中断0控制,设置时分秒由外部中断1控制,而调时间时的加减是由按键连接P1.0和P1.1口。
2.5整点报时
利用蜂鸣器实现整点报时,仿真原理图如图2.5所示。
图2.5蜂鸣器控制
第三章实时时钟的程序设计
程序设计中主要包括初始化,定时器0的控制,中断和按键扫描,蜂鸣器控制等。
程序清单见附录2。
3.1时间调节程序流程图
时间调节程序流程图如图3.1所示。
图3.1时间调节程序流程图
3.2主程序流程图
主程序流程图如图3.2所示。
图3.2主程序流程图
第四章小结
本次我和本组另外一名同学完成了这次单片机课程设计课题中的实时时钟设计,通过这次的设计使我认识到本人对单片机方面的知识知道的太少了,对于书本上的很多知识还不能灵活运用,尤其是对程序设计语句的理解和运用,不能够充分理解每个语句的具体含义,导致编程的程序过于复杂,使得需要的存储空间增大。
损耗了过多的内存资源。
本次的设计使我从中学到了一些很重要的东西,那就是如何从理论到实践的转化,怎样将我所学到的知识运用到我以后的工作中去。
在大学的课堂的学习只是在给我们灌输专业知识,而我们应把所学的用到我们现实的生活中去,此次的实时时钟设计给我奠定了一个实践基础,我会在以后的学习、生活中磨练自己,使自己适应于以后的竞争,同时在查找资料的过程中我也学到了许多新的知识,在和同学协作过程中增进同学间的友谊,使我对团队精神的积极性和重要性有了更加充分的理解。
最后,感谢老师一个学期来对我们的教育,正是由于老师的精彩的课程和对我们严格的要求,使得我的课程设计能够顺利的完成,同时在课程设计过程中,我们巩固和学习了我们的单片机知识。
相信这对我以后的课程设计和毕业设计乃至今后的工作将会有很大的帮助!
参考文献
(1)张齐.《单片机原理与嵌入式系统设计》电子工业出版社
(2)周润景.《PROTUES入门实用教程》机械工业出版社
(3)任向民.《微机接口技术实用教程》清华大学出版社
(4)
附录1
附录2
#include
#include
#definePAXBYTE[0x0000]
#definePBXBYTE[0x2000]
#definePCXBYTE[0x4000]
#defineCMDXBYTE[0x6000]
sbitup=P1^0;
sbitdown=P1^1;
sbitFMQ=P1^3;
bitflag_TR=0;
unsignedcharflag_SET=0,shi=0,fen=0,miao=0,temp=0,i;
unsignedcharshu[10]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90
};
voidinit()
{
IE=0x87;
TMOD=0x01;
TH0=0x4c;
TL0=0X00;
TCON=0x05;
CMD=0x80;
}
voiddelay(unsignedintm)
{
unsignedcharcount;
while(m!
=0)
{
for(count=0;count<239;count++){}
m--;
}
}
voiddisplay(unsignedcharshi,unsignedcharfen,unsignedcharmiao)
{
unsignedcharshi0,shi1,fen0,fen1,miao0,miao1;
shi0=shi/10;shi1=shi%10;
fen0=fen/10;fen1=fen%10;
miao0=miao/10;miao1=miao%10;
PA=0x80;
PB=shu[shi0];
delay(5);
PA=0x40;
if(flag_SET==3&&!
flag_TR)
PB=shu[shi1]&0x7f;
else
PB=shu[shi1];
delay(5);
PA=0x20;
PB=shu[fen0];
delay(5);
PA=0x10;
if(flag_SET==2&&!
flag_TR)
PB=shu[fen1]&0x7f;
else
PB=shu[fen1];
delay(5);
PA=0x08;
PB=shu[miao0];
delay(5);
PA=0x04;
if(flag_SET==1&&!
flag_TR)
PB=shu[miao1]&0x7f;
else
PB=shu[miao1];
delay(5);
}
voidmain()
{
init();
while
(1)
{
display(shi,fen,miao);
if(flag_SET)
{
TR0=0;
if(flag_SET==1&&up==0)
{
while(up==0);
miao++;
if(miao==60)miao=0;
}
if(flag_SET==1&&down==0)
{
while(down==0);
miao--;
if(miao>60)miao=59;
}
if(flag_SET==2&&up==0)
{
while(up==0);
fen++;
if(fen==60)fen=0;
}
if(flag_SET==2&&down==0)
{
while(down==0);
fen--;
if(fen>60)fen=59;
}
if(flag_SET==3&&up==0)
{
while(up==0);
shi++;
if(shi==24)shi=0;
}
if(flag_SET==3&&down==0)
{
while(down==0);
shi--;
if(shi>24)shi=23;
}
}
if(flag_TR==1)
TR0=1;
else
TR0=0;
if(flag_TR==1&&fen==0&&miao==0)
{
for(i=0;i{
display(shi,fen,miao);
FMQ=0;
delay(300);
FMQ=1;
delay(300);
}
while(miao==0);
}
}
}
voidtimer0()interrupt1
{
EA=0;
TH0=0x4c;
TL0=0x00;
flag_SET=0;
temp++;
if(temp==20)
{
temp=0;
miao++;
}
if(miao==60)
{
miao=0;
fen++;
}
if(fen==60)
{
fen=0;
shi++;
}
if(shi==24)
{
shi=0;
}
EA=1;
}
voidtimer_run()interrupt0
{
EA=0;
flag_TR=!
flag_TR;
EA=1;
}
voidset_time()interrupt2
{
EA=0;
if(!
flag_TR)
flag_SET++;
flag_SET%=4;
EA=1;
}