课程设计Word格式文档下载.docx
《课程设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《课程设计Word格式文档下载.docx(28页珍藏版)》请在冰豆网上搜索。
128×
8位内部RAM;
32位双向输入输出线;
两个十六位定时器/计数器
五个中断源,两级中断优先级;
一个全双工的异步串行口;
间歇和掉电两种工作方式
超强抗干扰:
高抗静电(ESD保护),轻松过2KV/4KV快速脉冲干扰;
宽电压,不怕电源抖动;
宽温度范围,-40℃~85℃;
禁止ALE输出;
;
超低功耗:
1、掉电模式:
典型功耗<
0.1μA;
2、空闲模式:
典型功耗2mA;
3、正常工作模式:
典型功耗4mA-7mA;
4、掉电模式可由外部中断唤醒,适用于电池供电系统,如水表、气表、便携设备等。
(2)STC89C52RC引脚功能
1电源:
1VCC-芯片电源,接+5V;
2VSS-接地端;
2.时钟:
XTAL1、XTAL2-晶体振荡电路反相输入端和输出端。
3.控制线:
控制线共有4根:
ALE/PROG:
地址锁存允许/片内EPROM编程脉冲
1ALE功能:
用来锁存P0口送出的低8位地址
2PROG功能:
片内有EPROM的芯片,在EPROM编程期间,此引脚输入编程脉冲。
PSEN:
外ROM读选通信号。
RST/VPD:
复位/备用电源。
1RST(Reset)功能:
复位信号输入端。
2VPD功能:
在Vcc掉电情况下,接备用电源。
EA/Vpp:
内外ROM选择/片内EPROM编程电源。
①EA功能:
内外ROM选择端。
②Vpp功能:
片内有EPROM的芯片,在EPROM编程期间,施加编程电源Vpp。
4.I/O口线:
P0、P1、P2、P3共四个八位口。
P0口是三态双向口,通称数据总线口,因为只有该口能直接用于对外部存储器的读/写操作。
P0口也用以输出外部存储器的低8位地图1址。
由于是分时输出,故应在外部加锁存器将此地址数据锁存,地址锁存,信号用ALE。
P1口是专门供用户使用的I/O口,是准双向口。
P2口是从系统扩展时作高8位地址线用。
不扩展外部存储器时,P2口也可以作为用户I/O口线使用,P2口也是准双向口。
P3口是双功能口,该口的每一位均可独立地定义为第一I/O功能或第二I/O功能。
作为第一功能使用时操作同P1口。
(1)电源及时钟引脚——VCC,VSS,XTAL1,XTAL2
(2)控制引脚——非PSEN,ALE/非PROG,非EA/VPP,RST
I/O引脚——P0,P1,P2,P3,为4个8位I/O口的外部引脚。
(二)设计要求(按照自己的认识详细阐述)
任务:
10-99S计时可设置
2显示数值永远向上
3A组倒计时B组正计时
4翻转后计时沙漏式反正
5水平放置停止计时
6计时溢出蜂鸣报警
7LED水滴效果
8设定数据掉电可保持*
9可设定加减模式、分钟模式*
10设计电子钟功能*
此次任务的了解:
(1)0-99S计时可设置:
编写单片机程序,单片机的P0所对应的8个I/O口接了四个数码管的八个管脚。
两位的数码管共用一个P0口,一共有两个数码管,为了让两个两位的数码管直观上同时亮显示个位和十位的数字,进行倒计时功能,我们让它分顺序以1s速度转换每个位的的亮灭,不断循环就能看到两个个数码管同时显示。
(2)先制作每个数字显示时相应的数码管对应的LED断码,成两个表,以方便赋值查表在数码管显示相应的数字,把个位十位分开。
(3)显示数值永远向上:
下面的数码管查的表按重新设置,设置水银开关,使正放反放程序查的表正确,保证显示数值永远向上。
(3)A组倒计时B组正计时:
电子沙漏,正放时沙漏往下流,上面一个两位数码管A组进行倒计时,下面一个两位数码管B组进行正计时。
(4)翻转后计时沙漏式反正:
设置水银开关,P3.2为1,P3.1为0时,A组正计时,B组倒计时。
P3.2为0,P3.1为1时,A组倒计时,B组正计时。
显示永远向上。
(5)水平放置停止计时:
当水银开关P3.2和P3.1同时为1时,就是水平放置事,停止计时,数字不变。
此时平放时可以长按按键,可以切换模式,当为1时,模式为2,此时为时钟模式,当为0时,模式为1,此时为沙漏模式。
(6)计时溢出蜂鸣报警:
当A组或者B组数码管其中一个计时到00时,计时溢出,调用蜂鸣器,此时使蜂鸣器对应芯片管脚P3.5置0,响起。
(7)LED水滴效果:
在倒计时的同时设定LED灯显示,当AB记时
LED灯有流动的效果,效果如沙漏一般。
(8)设定数据掉电可保持:
当单片机设置好各项功能知道,进行倒计时,当计时没有结束就断电之后设置掉电保持模式,使数据不丢失,不至于重新设置数值。
(三)本次课程设计已实现的功能
本次课程设计实现了以下七个功能:
(四)系统框图、设计思路、系统概述
(1)系统框图:
(五)电路原理图、技术路线、实现方案细节描述
实物图:
(六)本次设计的收获心得
在此次的课程设计中,主要是设计基于51构架单片机的电子沙漏设计,说明51单片机对于现在电子行业来说非常重要。
在这次课程设计中,我们各组员之间都有互相交流,互相分享自己的想法,以达到课程设计的丰满度,让我们学到更多,这是课程设计的根本目的。
在设计过程中,最困难的步骤就是程序设计,这次极大的考验我们的功底,能设计出来,说明自己已经已经达到了学习的要求,没有设计出来的话,也可以在反复设计中,查找资料,从中也能学习到许多,这是课程设计的最终目的。
程序设计过程中,刚开始是一头雾水,组员之间都感到失望,原因是我们对程序设计接触较少,功底不扎实,但是后来,通过看书本上的资料,然后通过一个一个模块的实现,以达到全部模块的实现。
通过一个一个模块的实现,这样才能让我们增强信心,才有继续学习和开拓的动力,这是非常重要的。
在设计过程中,我们已经知道自己的短板,所以每一次课程设计都是自我学习,自我成长的好机会,千万不能掉以轻心,这对我们以后的毕业设计有个好的开头。
这次课程设计遇到的问题远远大于大一,大二时候的课程设计,还好老师的细心教导,让我们才能加快进度,才能学到更多。
(七)主要程序及注释
#include<
reg52.h>
intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitdig1=P1^0;
sbitdig2=P1^1;
sbitdig3=P3^6;
sbitdig4=P3^7;
sbitkey=P1^2;
sbitled=P2^0;
sbitint0=P3^2;
sbitint1=P3^3;
sbitbell=P3^5;
sbitled1=P1^5;
sbitled2=P1^6;
sbitled3=P1^7;
chari;
ucharshi,fen,miao;
ucharcount,num1,num2,shu,moshi;
ucharflag,jian_flag,sfm_flag,zf_flag;
ucharcodetabledu1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//正
ucharcodetabledu2[]={0xc0,0xcf,0xa4,0x86,0x8b,0x92,0x90,0xc7,0x80,0x82};
ucharcodeledd[]={0x3f,0x1f,0x27,0x38};
ucharcodeledd1[]={0xc0,0x20,0xe0};
voidfenz();
voidjian();
voidshal();
voidinit();
//EEPROM操作命令定义
#defineRdCommand0x01//定义ISP的操作命令
#definePrgCommand0x02
#defineEraseCommand0x03
#defineError1
#defineOk0
#defineWaitTime0x01//定义CPU的等待时间
sfrISP_DATA=0xe2;
//寄存器申明
sfrISP_ADDRH=0xe3;
sfrISP_ADDRL=0xe4;
sfrISP_CMD=0xe5;
sfrISP_TRIG=0xe6;
sfrISP_CONTR=0xe7;
//EEPROM相关函数声明
voidISP_IAP_enable(void);
voidISP_IAP_disable(void);
voidISPgoon(void);
unsignedcharbyte_read(unsignedintbyte_addr);
voidSectorErase(unsignedintsector_addr);
voidbyte_write(unsignedintbyte_addr,unsignedcharoriginal_data);
voiddelay(ucharx)
{
uchara,b;
for(a=100;
a>
0;
a--)
for(b=x;
b>
b--);
}
voiddisplay1(ucharshi,ucharge)//display1(num2/10,num2%10);
dig4=0;
P0=tabledu2[shi];
delay(5);
dig4=1;
dig3=0;
P0=tabledu2[ge];
dig3=1;
voiddisplay2(ucharshi,ucharge)//display2(num1/10,num1%10);
dig1=0;
P0=tabledu1[shi];
dig1=1;
dig2=0;
P0=tabledu1[ge];
dig2=1;
voiddisplay3(ucharshi,ucharge)//display3(num2%10,num2/10);
voiddisplay4(ucharshi,ucharge)//display4(num1/10,num1%10);
voidmain()
init();
num2=byte_read(0x2200);
num1=99-num2;
num2=99;
num1=0;
while
(1)
{
if((int0==1)&
&
(int1==1))
{
while(key==0)
{
TR0=0;
shu++;
if(shu==2)
shu=0;
for(i=50;
i>
i--)
{
delay(10);
display4(shu/10,shu%10);
}
}
TR0=1;
if(shu==0)
moshi=1;
if(shu==1)
moshi=2;
while(moshi==1)
shal();
while(moshi==2)
fenz();
}
}
voidtime0()interrupt1
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
voidshal()
//**********************************
//zheng面沙漏
TR0=1;
if(int0==0)
if(key==0)
delay
(1);
if(key==0)
{
//关键语句
SectorErase(0x2200);
//擦除扇区
byte_write(0x2200,num2);
//重新写入数据;
}
jian_flag=0;
if(count==20)
count=0;
if(flag==2)
bell=1;
if(num2==0)
{num2=1;
TR0=0;
bell=0;
flag=1;
num2--;
if(num1==100)
{num1=98;
}
num1++;
//************************************
//正面流水灯
if((num2)&
(int1))
{led1=0;
led2=0;
led3=0;
i++;
if((i>
0)&
(i<
4))
{led1=0;
P2=ledd[i];
}
if(i>
=4)
{i=0;
P2=0x3f;
led1=0;
if(num2==0){P2=0xc0;
led1=1;
led2=1;
led3=1;
}
display2(num2/10,num2%10);
display1(num1/10,num1%10);
//***********************************
//fang面沙漏
if(int1==0)
if(flag==1)
if(num1==0)
{num1=1;
}
num1--;
num2++;
if(num2==100)
{num2=99;
flag=2;
//fang面流水灯
if((num1)&
(int0))
{P2=0xe0;
led1=1;
if(i<
3)
{
P2=ledd1[i];
=3)
{i=-1;
P2=0xe0;
if(num1==0){P2=0x3f;
//***********************************
jian();
//按键选择
display3(num1/10,num1%10);
display4(num2%10,num2/10);
//*****************************************
//水平
TR0=0;
bell=1;
shu++;
if(shu==2)
shu=0;
for(i=50;
{
delay(10);
display4(shu/10,shu%10);
//************************************
voidjian()
if(key==0)
delay
(1);
if(key==0)
while(!
key);
delay
(1);
while(jian_flag==0)
if(int0==0)
jian_flag=1;
//倒过来不用按键
delay
(1);
while(key==0)
//if(int0==0)
//jian_flag=1;
//倒过来要用按键
num1++;
if(num1==100)
num1=0;
if(num2==0)
num2=100;
num2--;
for(i=10;
{delay
(1);
display3(num2/10,num2%10);
display4(num1%10,num1/10);
display3(num2/10,num2%10);
display4(num1%10,num1/10);
voidfenz()
TR0=1;
while(((int0==0)||(int1==0)||key)&
(moshi==2))
if(count==20)
count=0;
miao++;
if(miao==60)
miao=0;
fen++;
if(fen==60)
fen=0;
shi++;
if(shi==24)shi=0;
//*********************************************************
//跟下面反面设置一样的
if(int1==0)//zheng
zf_flag=1;
//如果没加标志位,当sfm_flag=4;
时,倒立过去再正面时sfm_flag还是为4,则会跳过下面第一条语句,只有一直显示时分
if((sfm_flag!
=4)&
(sfm_flag!
=5))
{
sfm_flag=6;
display3(miao%10,miao/10);
display4(miao/10,miao%10);
if(sfm_flag==4||sfm_flag==5)
display4(shi/10,shi%10);
display3(fen%10,fen/10);
for(i=7;
i--)
delay(100);
if(key==1)
if(sfm_flag==4)
{
if(shi==0)
shi=24;
shi--;
}
if(sfm_flag==6)
if(miao==0)
miao=60;
miao--;
if(sfm_flag==5)
if(fen==0)
fen=60;
fen--;
}
for(i=20;
{delay(50);
sfm_flag=4;