单片机四路抢答器课设说明书.docx
《单片机四路抢答器课设说明书.docx》由会员分享,可在线阅读,更多相关《单片机四路抢答器课设说明书.docx(24页珍藏版)》请在冰豆网上搜索。
单片机四路抢答器课设说明书
信息与电气工程学院
课程设计说书
(2010/2011学年第二学期)
课程名称:
单片机课程设计
题目:
四路抢答器
设计成绩:
2013年6月23日
目 录
第一节课程设计目的…………………………………………………………2
1.1概述………………………………………………………………………2
1.2设计要求…………………………………………………………………2
第二节四路抢答器设计正文…………………………………………………2
2.1总体设计…………………………………………………………………2
2.1.1抢答器的工作原理……………………………………………………2
2.1.2抢答器的总体设计……………………………………………………3
2.2硬件电路详细设计………………………………………………………3
2.2.180c51芯片………………………………………………………………3
2.2.2芯片的选择……………………………………………………………6
2.2.3复位电路的设计………………………………………………………6
2.2.4晶振电路的设计………………………………………………………7
2.2.5数码显示电路的设计…………………………………………………8
2.2.6报警电路的设计………………………………………………………8
2.2.7总电路的设计…………………………………………………………9
2.2.8PCB版图的绘制………………………………………………………9
2.3软件详细设计……………………………………………………………10
2.3.1主程序的设计…………………………………………………………10
2.3.2显示子程序的设计……………………………………………………10
2.3.3定时器T0、T1中断服务程序的设计………………………………11
2.3.4抢答处理程序的设计…………………………………………………11
2.3.5总程序…………………………………………………………………11
第三节实验结果及结论………………………………………………………14
第四节参考文献………………………………………………………………15
第一节课程设计目的
1.1概述
单片机原理及应用课程设计是学生综合运用所学知识,全面掌握单片微型计算机及其接口的工作原理、编程和使用方法的重要实践环节。
通过独立或协作提出并论证设计方案,进行软、硬件调试,最后获得正确的运行结果,可以加深和巩固对理论教学和实验教学内容的掌握,进一步建立计算机应用系统整体概念,初步掌握单片机软、硬件开发方法,为以后进行实际单片机软、硬件应用开发奠定良好的基础。
课程设计的主要内容:
根据单片机原理及应用课程的要求,主要进行两个方面的设计,即单片机最小系统和接口技术应用设计。
其中,单片机最小系统主要要求学生熟悉单片机的内部结构和引脚功能、引脚的使用、复位电路、时钟电路、4个并行接口和一个串行接口的实际应用,从而可构成最小应用系统,并编程进行简单使用。
接口技术应用设计主要要求学生能综合运用单片机、存储器、常用接口芯片构成单片机应用系统,有针对性地进行软、硬件设计与开发。
1.2设计要求:
1、设置4个抢答台和四个抢答成功指示灯,1个比赛主持人开始按键和1个抢答指示灯以及1个LED显示器。
2、采用中断和查询结合的方法确定按键动作。
3、主持人按下“开始”键后,若有人抢答,则对应选手的指示灯点亮,并用7段LED显示抢答者的号码(1-4),同时蜂鸣器发出3声间隔一秒的警告音;若9秒内无人抢答,则发出超时报警声,此题作废,主持人可按下“开始”键开始下一题的抢答。
第二节四路抢答器设计正文
2.1总体设计
2.1.1抢答器的工作原理
抢答器的工作原理是利用单片机的定时器T0、T1中断完成,其余状态循环调用显示子程序,用2个共阴极LED数码管来显示,用P2.0、P2.1、P2.2、P2.3口作为CD4511译码器的数据输入口,P1.0、P1.1、P1.2、P1.3口接4个选手按键,提供选手抢答,P1.4、P1.5、P1.6、P1.7接四个发光二极管作为抢答成功指示灯;P0.0接蜂鸣器,超时报警,和提示抢答。
2.1.2抢答器的总体设计
倒计时方案方面利用MCS-51的内部的定时/计时器进行中断计时,配合软件延时实现倒计时。
该方案节省硬件成本,并且能够在定时器/计数器的使用、中断及程序设计方案方面得到锻炼与提高,显示方面采用穿行传输实现动态显示,该方案的硬件连接简单,但动态扫描的显示方式需占用CPU较多的时间,适用于单片机没有太多实时测控的任务场合。
抢答功能:
通过四路按键配合程序来实现抢答功能。
当主持人按下抢答键开始抢答后,此时任一路按下按钮均闭锁其它各路,由程序对键盘译码并显示最先按下抢答键的选手号。
并亮起主持人台和对应选手台上的抢答成功指示灯。
抢答限时:
主持人按下抢答键后,设置9秒为抢答时间。
若9秒内无人抢答,倒计时为0时发出报警,说明该抢答题目作废。
此时闭锁所有抢答按键,只有当主持人再次按下抢答键开始下一次抢答方可抢答。
2.2硬件电路详细设计
2.2.180C52芯片
80C52系列中,用CHMOS工艺制造的单片机都采用双列直插式(DIP)40脚封装,引脚信号完全相同。
1、为一般控制应用的8位单片机
2、晶片内部具有时钟振荡器(传统最高工作频率可至33MHz)
3、内部程式存储器(ROM)为8KB
4、内部数据存储器(RAM)为256B
5、外部程序存储器可扩充至64KB
6、外部数据存储器可扩充至64KB
7、32条双向输入输出线,且每条均可以单独做I/O的控制
8、5个中断向量源
9、3组独立的16位定时器
10、1个全双工串行通信端口
各引脚功能介绍:
1.电源
VCC(引脚号40):
电源正端输入,接+5V。
VSS(引脚号20):
电源地端。
2.时钟
XTAL1(引脚号18)内部振荡电路反相放大器的输入端,是外接晶振的一个引脚。
当采用外部振荡器时,此引脚接地。
XTAL2(引脚号19)内部振荡器的反相放大器输出端,是外接晶振的另一端。
当采用外部振荡器时,此引脚接外部振荡源。
3.控制总线
(1)ALE/
(引脚号30):
正常操作时为ALE功能(允许地址锁存),用来把地址的低字节锁存到外部锁存器。
ALE引脚以不变的频率(振荡器频率的1/6)周期性地发出正脉冲信号。
因此,它可用作对外输出的时钟信号或用于定时。
但要注意,每当访问外部数据存储器时,将跳过一个ALE脉冲。
ALE端可以驱动(吸收或输出电流)8个LSTTL电路。
在8751单片机EPROM编程期间,此引脚接编程脉冲(
功能)。
(2)
(引脚号29):
外部程序存储器读选通信号。
在从外部程序存储器取指令(或数据)期间,
在每个机器周期内两次有效。
可以驱动8个LSTTL电路。
(3)RST/VPD(引脚号9):
复位信号输入端。
振荡器工作时,该引脚上持续2个机器周期的高电平可实现复位操作。
此引脚还可接上备用电源。
在Vcc掉电期间,由
向内部RAM提供电源,以保持内部RAM中的数据。
(4)
/Vpp(引脚号31):
为内部程序存储器和外部程序存储器的选择端。
当
为高电平时,访问内部程序存储器(PC值小于4K);当
为低电平时,访问外部程序存储器。
对于87C51单片机,在EPROM编程期间,此端为21V编程电源输入端。
4.I/O线
(1)P0口(引脚号32~39):
单片机的双向数据总线和低8位地址总线。
在访问外部存储器时实现分时操作,先用作地址总线,在ALE信号的下降沿,地址被锁存;然后用作为数据总线。
它也可以用作双向输入/输出口。
P0口能驱动8个LSTTL负载。
(2)P1口(引脚号1~8):
准双向输入/输出口,它能驱动4个LSTTL负载。
(3)P2口(引脚号21~28):
准双向输入/输出口。
在访问外部存储器时,用作高8位地址总线。
P2口能驱动4个LSTTL负载。
(4)P3口(引脚号10~17):
准双向输入/输出口,它能驱动4个LSTTL负载。
P3口的每一引脚还有另外一种功能:
P3.0——RXD:
串行口输入端
P3.1——TXD:
串行口输出端
P3.2——
:
外部中断0中断请求输入端
P3.3——
:
外部中断1中断请求输入端
P3.4——T0:
定时器/计数器0外部输入端
P3.5——T1:
定时器/计数器1外部输入端
P3.6——
:
外部数据存储器写选通信号
P3.7——
:
外部数据存储器读选通信号
5.时钟电路
80C52单片机内有一个高增益反相放大器,其频率范围为1.2MHz~12MHz,XTAL1和XTAL2分别为放大器的输入端和输出端。
时钟可以由内部方式或外部方式产生。
80C52内部方式时钟电路如图2-10(a)所示。
在XTAL1和XTAL2引脚上外接定时元件,就能构成自激振荡电路。
定时元件通常采用石英晶体和电容组成的并联谐振电路。
电容器C1和C2主要起频率微调作用,电容值可选取为30pF左右(外接晶体时)或40pF左右(外接陶瓷谐振器时)。
80C52外部方式时钟电路如图2-10(b)所示。
XTAL1接外部振荡器,XTAL2悬空。
对外部振荡信号无特殊要求,只要保证脉冲宽度,一般采用频率低于12Hz的信号。
2.2.2芯片的选择
抢答器电路的核心是89C52单片机,其内部带有8KB的FLASHROM,无需外扩程序存储器;抢答器没有大量的运算和暂存数据现有的256B篇内RAM已经能满足容量需求,故不需外扩片外RAM,系统配有2个8段数码显示管共用一个CD4511驱动,管采用共阴数码管,作为选手号的显示输出。
2.2.3复位电路的设计
复位电路的设计如图2-1所示:
图2-1复位电路原理图
该复位电路采用上电自动复位和手动复位两种复位方式,图中右侧引脚接到单片机的复位引脚。
要实现复位只需在,52系列单片机的RESET引脚上加上5ms的高电平就可以了。
上电复位是利用电容的充电来实现的,即上电瞬间RESET端的电位与Vcc相同,随着电容上储能增加,电容电压也逐渐增大,充电电流减小,RESET端的电位。
这样就会建立一个脉冲电压,调节电容与电阻的大小可对脉冲的持续时间进行调节。
通常若采用12MHz的晶振时,复位元件参数为22μF的电解电容和10kΩ的电阻。
按钮复位电路是通过按下复位按钮时,电源对RESET端维持两个机器周期的高电平实现复位的。
2.2.4晶振电路的设计
图2-2晶振电路原理图
MSC-52单片机的定时控制功能是用时钟电路和振荡器完成的,而根据硬件电路的不同,连接方式分为内部时钟方式和外部时钟方式。
本设计中采用内部时钟方式。
单片机内部有一个反相放大器,XTAL1、XTAL2分别为反相放大器的输入端和输出端,外接定时反馈元件组成振荡器(内部时钟方式),产生时钟送至单片机内部各元件。
时钟频率越高,单片机控制器的控制节拍就越快,运算速度也就越快。
一般来说单片机内部有一个带反馈的线性反相放大器,外界晶振(或接陶瓷振荡器)和电容就可组成振荡器,如图2-2所示。
加电以后延时一段时间(约10ms)振荡器产生时钟,不受软件控制,图中Y1为晶振,震荡产生的时钟频率主要由Y1确定。
电容C1,C2的作用有两个:
一是帮助振荡器起振,二是对振荡器的频率起微调作用,典型值为30pF。
2.2.5数码显示电路的设计
图2.3数码显示管电路图
数码显示管用来作为9秒倒计时显示和选手号,两个共阴极数码管共用一个CD4511驱动,每个数码管有一个位选端分别接P3.2、P3.3口。
P2.0、P2.1、P2.2、P2.3作为CD4511数据输入端。
2.2.6报警电路的设计
图2.4报警电路图
使用蜂鸣器作为报警电路,NPN三极管的基极通过电阻与单片机的P0.0引脚连接,再用330Ω的上拉电阻接电源,三极管的集电极接电源,发射极接蜂鸣器的正极。
当P0.0输出低电平时蜂鸣器响。
2.2.7总电路的设计
图2.5总电路原理图
2.2.8PCB板的制作
画好原理图检查无误后,画PCB版图,本设计由于电路连接比较简单,接线较少,所以用明线直接连接,不用制版,画出PCB版图的目的是便于插板时的布局和链接。
2.3软件详细设计
2.3.1主程序的设计
此程序的及时采用定时器T0和T1中断完成,其余状态循环调用显示子程序。
系统主程序流程图如图3-1所示。
图2-3-1系统主程序流程图
2.3.2显示子程序的设计
2.3.3定时器T0、T1中断服务程序的设计
定时器T0用于复位程序,当给RST口加10ms的复位信号时,单片机复位。
定时器T1用于计时程序,当主持人按下开始抢答按钮9秒内无人抢答时,蜂鸣器发出报警信号。
2.3.4抢答处理程序的设计
当有选手第一个按下抢答器按扭时数码管显示选手号码,同时选手指示灯点亮,蜂鸣器发出三声间隔1秒的警告,并锁定抢答。
当在此选手之后再有选手按下按扭时无效,数码管不变。
2.3.5四路抢答器程序
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitstart=P3^4;
sbitbuzzer=P0^0;
sbitkey1_led=P1^4;
sbitkey2_led=P1^5;
sbitkey3_led=P1^6;
sbitkey4_led=P1^7;
sbitkey5_led=P3^6;
uchartemp;
ucharcodewei[]={0xfb,0xf7};
ucharcodeduan[]={0x00,0x01,0x02,0x03,0x04,
0x05,0x06,0x07,0x08,0x09};
uchartt=0,key=0,sw=0,key_flag=0,start_flag=0,
buzz_flag=0,x=0,y=0,j=9,m=0;
//*****************************************//
//延时函数
//*****************************************//
voiddelay(unsignedintt)
{
unsignedinti,j;
for(i=1000;i>0;i--)
for(j=t;j>0;j--);
}
//*****************************************//
//定时器初始化
//*****************************************//
voidinit_timer()
{
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
ET0=0;
TR0=0;
}
//*****************************************//
//按键检测
//*****************************************//
voidkey_jc()
{
temp=P1;
sw=0x0f&temp;
if(sw!
=0x0f)
{
delay
(1);
if(sw!
=0x0f)
{
temp=P1;
sw=0x0f&temp;
while(sw==0x0f);
switch(sw)
{
case0x0e:
key_flag=1;
key1_led=1;
key=2;
break;
case0x0d:
key_flag=2;
key2_led=1;
key=2;
break;
case0x0b:
key_flag=3;
key3_led=1;
key=2;
break;
case0x07:
key_flag=4;
key4_led=1;
key=2;
break;
default:
break;
}
}
}
}
//******************************************//
//动态数码管显示
//显示按键值和计时值
//******************************************//
voidxianshi(ucharn)
{
uchari=0;
for(i=0;i<=1;i++)
{
if(i==0)
{
P3=wei[0];
P2=duan[j];
}
elseif(i==1)
{
P3=wei[1];
P2=duan[n];
}
for(x=500;x>0;x--)
for(y=10;y>0;y--);
}
}
//******************************************//
//数码管显示
//******************************************//
voidLed()
{
uchari=0;
if(key==2)
{
start_flag=2;//准备复位
switch(sw)
{
case0x0e:
//按键1
xianshi
(1);
break;
case0x0d:
//按键2
xianshi
(2);
break;
case0x0b:
//按键3
xianshi(3);
break;
case0x07:
//按键4
xianshi(4);
break;
default:
break;
}
}
elseif(key==0)//初始状态“00”显示
{
for(i=0;i<=1;i++)
{
P3=wei[i];
P2=duan[0];
for(x=5;x>0;x--)
for(y=1;y>0;y--);
}
}
elseif(key==1)//未有按键按下,仅计时显示
{
for(i=0;i<=1;i++)
{
if(i==0)
{
P3=wei[1];
P2=duan[0];
}
elseif(i==1)
{
P3=wei[0];
P2=duan[j];
}
for(x=500;x>0;x--)
for(y=10;y>0;y--);
}
}
}
//******************************************//
//蜂鸣器函数
//******************************************//
voidbuzz()
{
if(buzz_flag==0)
{
buzz_flag=1;
ET0=1;
TR0=1;
}
if(buzz_flag==1)
{
if(tt==10)
{
tt=0;
m++;
if(m==6)
{
m=0;
buzzer=1;
buzz_flag=2;
start_flag=2;//准备复位
}
elseif(m<=6)
{
buzzer=~buzzer;
}
}
}
}
//******************************************//
//主函数
//start_flag=0:
初始状态
//start_flag=1:
开始
//start_flag=2:
复位
//******************************************//
voidmain()
{
init_timer();
start_flag=0;
buzzer=1;
P1=0x0f;
while
(1)
{
if(start==0)//开始按键被按下
{
delay
(1);
if(start==0)
{
while(start==0);
if(start_flag==0)
{
start_flag=1;//开始
ET0=1;
TR0=1;
key=1;
}
if(start_flag==2)//复位
{
start_flag=0;
buzz_flag=0;
key_flag=0;
key5_led=0;
buzzer=1;
P1=0x0f;
key=0;
ET0=0;
TR0=0;
tt=0;
m=0;
j=9;
}
}
}
if(start_flag==1)//开始
{
if(j>0)//在计时完成之前检测按键
{
key_jc();
}
}
if(key==2)
{
if(buzz_flag==0)
{
ET0=0;
TR0=0;
tt=0;
}
buzz();
}
Led();
}
}
//******************************************//
//定时中断函数
//******************************************//
voiditc_timer()interrupt1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
tt++;
if(start_flag==1)//开始
{
if((tt==10)&&(buzz_flag==0))
{
tt=0;
if(key_flag==0)