单片机99S倒计时课程设计.docx
《单片机99S倒计时课程设计.docx》由会员分享,可在线阅读,更多相关《单片机99S倒计时课程设计.docx(17页珍藏版)》请在冰点文库上搜索。
单片机99S倒计时课程设计
课程设计
课程名称:
__单片机课程设计
题目名称:
__倒计时器设计
学生学院:
_物理与光电工程学院
专业班级:
_光信息科学与技术10
(1)班
学号:
_XXXXXXX_
学生姓名:
_李超凡______________
指导教师:
_刘汉瑞
2012年12月3日
摘要······················································2
一、本设计任务、实现方法及完成的功能······················3
1、功能要求····················································3
2、实现方法····················································3
二、设计的实现过程······································3
1、矩阵电路····················································4
2、数码显示和驱动电路·······································4
3、复位电路···················································5
4、晶振电路····················································6
三、系统的软件设计·······································4
1、按键扫描函数ankey()·······································4
2、动态数码管显示函数·········································5
3、初始化函数设计·············································64、中断函数设计··············································6四、总体程序·············································7
五、结束语···············································12
倒计时课程设计
一:
课程设计的要求
1、功能要求:
实现最长99S的倒计时功能;利用数码管或液晶屏显示数字;利用按键可以设置倒计时时间;设置倒计时开始启动键;时间到,声(光)报警,示意倒计时时间到。
2、实现方法:
单片机采用51系列,分析功能要求,设计方案,编写程序(keilc51软件),利用Proteus进行仿真。
二:
设计的实现过程
1.proteus仿真下总原理框架图如下
接线:
(1)、XTAL1、XTAL2为晶振接入
(2)、RST为清零电路接入
(3)、P1口为键盘电路接入
(4)、P2口为数码管的段选
(5)、P3..7为LED的选通
(6)、P0.6、P0.7分别为数码管的十位、个位的选通
原件清单:
AT89C51单片机1个、1k电阻3个、12MHz晶振1个、33pF电容1个、1uF电容1个、10uf的电容一个、独立按键1个、4行3列矩阵按键1个、LED指示灯1个、两位动态共阴数码管1个、带9个引脚的上拉电阻1个、电源3个、地若2个
2.模块组成设计
(1)、矩阵键盘电路
矩阵键盘电路原理:
以上矩阵采用了4*3的结构,通过ankey()子函数不断逐行逐行地扫描矩阵键盘电路,一旦判断有按键按下立即反馈给倒计时时钟循环函数。
扫描电路子程序:
voidankey()//键盘扫描
{
uchartemp,key;
P1=0xef;//第1行
temp=P1;
temp=temp&0x0f;//temp高4位清0;
if(temp!
=0x0f)//判断是否有键按下
{
delayms(10);//延时,消除抖动
if(temp!
=0xf0)//判断是否有键按下
{
temp=P1;//重新读取P1口
switch(temp)//判断哪个键按下
{
case0xeb:
key=1;
break;
case0xed:
key=2;
break;
case0xee:
key=3;
break;
}
text(key);
while(temp!
=0x0f)//判断按键是否释放
{
temp=P1;
temp=temp&0x0f;
}
}
}
(2)、数码管显示和驱动电路
数码管显示电路原理:
通关P0.6和P0.7的位选通信号控制数码管十位个位的选通,然后通过P2口的段选信号控制数码管的显示数字。
驱动电路:
属于上拉电阻,起到增大P1口的输出电压。
数码管显示程序:
voiddisplay(ucharnumdis)//动态数码管显示子函数
{
ucharshi,ge;//分离两个分别要显示的数
shi=numdis/10;
ge=numdis%10;
sw=0;
P2=table[shi];//送十位段选数据
delayms(5);//延时
sw=1;
gw=0;
P2=table[ge];//送个位段选数据
delayms(5);
gw=1;
}
(3)、复位电路:
复位电路原理:
RST为高电平有效,电路中的按键一旦按下则RST端由低电平变为高电平,因而实现总电路的复位。
(4)晶振电路:
晶振电路为系统提供了合适的时钟信号。
(4)中断子函数:
voidT0_time()interrupt1//定时器0中断函数
{
TH0=(65536-50000)/256;//重装初值
TL0=(65536-50000)%256;
numt0++;//50ms中断一次
}
(5)初始函数:
voidinit()//初始化函数
{
TMOD=0x01;//设置定时器0为工作方式1(00000001)
TH0=(65536-50000)/256;//装初值50ms一次中断
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//开定时器0中断
TR0=0;
sw=1;//关数码管十位位选
gw=1;//关数码管个位位选
}
3.总程序
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitsw=P0^6;//十位位选
sbitgw=P0^7;//个位位选
sbitled=P3^7;//LED灯
ucharcodetable[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};//编码定义
ucharnumt0,num;
voiddelayms(uint);
voidtext(uchar);
voiddisplay(ucharnumdis)//动态数码管显示子函数
{
ucharshi,ge;//分离两个分别要显示的数
shi=numdis/10;
ge=numdis%10;
sw=0;
P2=table[shi];//送十位段选数据
delayms(5);//延时
sw=1;
gw=0;
P2=table[ge];//送个位段选数据
delayms(5);
gw=1;
}
voiddelayms(uintx)//延时xms
{
uinti,j;
for(i=x;i>0;i--)//i=x即延时约x毫秒
for(j=110;j>0;j--);
}
voidankey()//键盘扫描
{
uchartemp,key;
P1=0xef;//第1行
temp=P1;
temp=temp&0x0f;//temp高4位清0;
if(temp!
=0x0f)//判断是否有键按下
{
delayms(10);//延时,消除抖动
if(temp!
=0xf0)//判断是否有键按下
{
temp=P1;//重新读取P1口
switch(temp)//判断按键按下情况
{
case0xeb:
key=1;
break;
case0xed:
key=2;
break;
case0xee:
key=3;
break;
}
text(key);
while(temp!
=0x0f)//判断按键是否释放
{
temp=P1;
temp=temp&0x0f;
}
}
}
P1=0xdf;//第2行
temp=P1;
temp=temp&0x0f;
if(temp!
=0x0f)
{
delayms(10);
if(temp!
=0xf0)
{
temp=P1;
switch(temp)
{
case0xdb:
key=4;
break;
case0xdd:
key=5;
break;
case0xde:
key=6;
break;
}
text(key);
while(temp!
=0x0f)
{
temp=P1;
temp=temp&0x0f;
}
}
}
P1=0xbf;//第3行
temp=P1;
temp=temp&0x0f;
if(temp!
=0x0f)
{
delayms(10);
if(temp!
=0xf0)
{
temp=P1;
switch(temp)
{
case0xbb:
key=7;
break;
case0xbd:
key=8;
break;
case0xbe:
key=9;
break;
}
text(key);
while(temp!
=0x0f)
{
temp=P1;
temp=temp&0x0f;
}
}
}
P1=0x7f;//第4行
temp=P1;
temp=temp&0x0f;
if(temp!
=0x0f)
{
delayms(10);
if(temp!
=0xf0)
{
temp=P1;
switch(temp)
{
case0x7b:
key=10;
break;
case0x7d:
key=0;
break;
case0x7e:
key=11;
break;
}
text(key);
while(temp!
=0x0f)
{
temp=P1;
temp=temp&0x0f;
}
}
}
}
voidtext(ucharkey)//判断键盘扫描结果,并倒计时
{
staticucharn,bb,s,i;//静态局部变量
s=1;
if(key==0||key==1||key==2||key==3||key==4||key==5||key==6||key==7||key==8||key==9)
n++;//有数字键被按下,n加1
if(key==11)
n=3;
i++;
if(key==10)
n=4;//*和#被按下,n置3
switch(n)
{
case1:
bb=key;num=key;break;//第1次按下数字键
case2:
bb=bb*10+key;n=0;num=bb;break;//第2次按下数字键
case3:
{
if(i%2==0)
TR0=1;
else
TR0=0;
}
n=0;
break;
case4:
num=bb;//*被按下,开始倒计时
TR0=1;//启动定时器0中断
while(s==1)
{
ankey();
if(numt0==20)//如果到了20次,说明1秒时间到
{
numt0=0;//然后把numt0清0重新再计20次
num--;//num自减
if(num==0)//如果num等0
{
TR0=0;//关闭定时器0中断
s=0;//推出循环
led=0;//点亮LED灯
}
}
display(num);//显示num
}
break;
}
}
voidinit()//初始化函数
{
TMOD=0x01;//设置定时器0为工作方式1(00000001)
TH0=(65536-50000)/256;//装初值50ms一次中断
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//开定时器0中断
TR0=0;
sw=1;//关数码管十位位选
gw=1;//关数码管个位位选
}
voidmain()//主函数
{
init();//初始化函数
num=0;
while
(1)//循环
{
ankey();//键盘扫描
display(num);//动态数码管显示
}
}
voidT0_time()interrupt1//定时器0中断函数
{
TH0=(65536-50000)/256;//重装初值
TL0=(65536-50000)%256;
numt0++;//50ms中断一次
}
3.总结心得
课程设计由始至终都是将所学知识理论与动手实践相结合的试验田地,无疑,本次单片机课程不仅让我们重温了一次单片机的理论知识,使我对单片机的认识变得更加深刻,也无形地提高了我的实践设计能力。
设计过程中,在分析问题与解决问题的探索过程,对于我来说是一种享受,在面对一个又一个新问题的出现,自己一个又一个地攻破,那种喜悦真的无与伦比,我对单片机产生的浓厚兴趣也由此而生。
总的来说,今次的课程设计我收益良多,也坚定了我对实践出真知的不可磨灭的真理的认同。