沈阳航空航天大学

 

课 程 设 计 报 告

 

课程设计名称:单片机系统课程设计

课程设计题目: 多路抢答器的设计

 

院(系):  

专    业:  

班    级:  

学    号:  

姓    名:  

指导教师:  

说明:结论(优秀、良好、中等、及格、不及格)作为相关教环节考核必要依据;格式不符合要求;数据不实,不予通过。报告和电子数据必须作为实验现象重复的关键依据。

 
   

 

 



学术诚信声明 

本人声明:所呈交的报告(含电子版及数据文件)是我个人在导师指导下独立进行设计工作及取得的研究结果。尽我所知,除了文中特别加以标注或致谢中所罗列的内容以外,报告中不包含其他人己经发表或撰写过的研究结果,也不包含其它教育机构使用过的材料。与我一同工作的同学对本研究所做的任何贡献均己在报告中做了明确的说明并表示了谢意。报告资料及实验数据若有不实之处,本人愿意接受本教学环节“不及格”和“重修或重做”的评分结论并承担相关一切后果。   

 

 

本人签名:              日期:           年      月    日

 

 

 

 

 

 

 

 

 

 

 

沈阳航空航天大学

课程设计任务书

课程设计名称

单片机系统课程设计

专业

计算机科学与技术

学生姓名

 

班级

 

学号

 

题目名称

多路抢答器的设计

起止日期

2017

06

26

日起至

2017

07

07

日止

 

课设内容和要求:

设计一款6路或以上的抢答器;

设计一个抢答控制开关(开始抢答后才允许答题者抢答),供主持人用;

设定抢答时间限制,超过时间后,该题作废;

设定答题时间;

数字LED显示当前答题者号数;

有犯规(未按开始键就抢答的)时显示其号码;

要求画出电路原理图。

参考资料:

《基于Proteus的单片机应用技术》 、《单片机课程设计指导》 、

《单片机C语言编程与Proteus仿真技术》 、《单片机原理及应用技术》 、

《微型计算机控制技术》 、《单片机实验与实践教程》

教研室审核意见:                  教研室主任签字:

指导教师(签名)

 

 

 

 

 

学 生(签名)

 

 

 

 

 

课程设计总结:

通过这次课程设计,我认识了抢答器的工作原理,掌握了它的调整及测试方法,使我对Proteus 仿真软件的使用和汇编语言、C语言有了更进一步的了解和掌握。本次课程设计,让我进一步的巩固了单片机的各种知识,在设计的过程中遇到的很多问题,通过翻阅及查找相关资料中的内容得以解决。我编程的过程时,刚开始,自己编写的程序是思路不清晰,冗余度高,效率低下的,然后在我不断调试修改的过程中,逐渐找到优于原本思想及算法的的思路,然后经过自己的努力与别人的帮助,我最终写出了自己能写出的最好的程序,自己最终也很满意。

不过就本课程设计来说我的程序还有优化的可能及待优化的的地方,不过由于我的能力限制,我写不出来,非常遗憾。所以自己编程能力还有提高的空间。

 

                                           

目    录

1  设计任务..................................................................................................................... 2

1.1  题目介绍.............................................................................................................. 2

1.2  功能要求.............................................................................................................. 2

2  系统硬件设计............................................................................................................. 3

2.1  系统功能结构图.................................................................................................. 3

  2.2  按键模块............................................................................................................. 3

  2.3  显示器模块......................................................................................................... 3

3  系统软件设计............................................................................................................. 6

3.1  C语言源程序数据结构设计............................................................................... 6

  3.2  C语言源程序函数描述.......................................... 6

  3.3  C语言源程序算法描述.......................................... 8

    3.3.1 主函数流程图 .............................................. 8

    3.3.2 抢答函数流程图............................................. 9

    3.3.3 犯规函数流程图............................................. 9

    3.3.4 回答函数流程图............................................ 10

4  仿真与性能测试...................................................................................................... 11

4.1  C语言程序在PROTEUS电路图中运行结果图................................................. 11

参考文献......................................................................................................................... 13

附录................................................................................................................................. 14

 

 


 1  设计任务

1.1  题目介绍

在信息化高速发展的时代,抢答在智力竞赛中是一种常见的答题方式。在抢答时,对于谁先谁后抢答,何时抢答,如何计算答题时间等问题,仅仅凭借人的主观判断,容易出现误判,所以需要一种智能抢答器来解决这些问题。本设计为六路抢答器,它可以准确公正的判断出首位抢答者,通过数码管显示手段指示出首位抢答者。本设计能够实现优先抢答,具有数字集成电路的锁存性。

1.2  功能要求

1.设计一款6路或以上的抢答器,由答题者控制,每一路都具有独立的开关控制。

2.设计一个抢答控制开关,由主持人控制,当主持人按下开关后,才允许答题者进行抢答,若主持人没有按下控制开关,则不允许答题者抢答。

3.设定抢答时间,在抢答倒计时为0之前,答题者可进行抢答,当倒计时为0后,则不允许答题者抢答,如果答题者抢答则视为违规抢答。

4.设定答题时间,在倒计时为0之前,答题者进行答题,倒计时为0后,答题者不可以答题。答题者答完题后,由主持人按下控制键,结束答题。

5.主持人按下控制开关允许答题者抢答后,数字LED显示抢答倒计时,答题者抢答成功后,数字LED显示当前答题者号数,及剩余答题时间,并进行倒计时。

6.当答题者未在抢答倒计时内规定抢答时,则视为答题者违规抢答,数字LED显示答题者号数,时间显示数码管显示值为00.

 

 

 

 

 

 

2  系统硬件设计

2.1  系统功能结构图

图1 系统工作原理图

2.2按键模块

2.2.1按键模块电路图

 

图2

2.2.2按键模块功能

开始按键的功能是主持人按下开始后,进行抢答倒计时30s.按键1-6的功能是答题者在抢答时间按下按键后,视为成功抢答,若不在抢答时间内,视为犯规抢答。成功抢答后,进行答题倒计时。完成答题后,由主持人按下清零键清零。

2.3 显示器模块

2.3.1显示器模块电路图

 

图3

2.3.2显示器模块功能

显示器采用四个显示数码管,它们的数据线有八根,片选线有四根。当进行抢答倒计时的时候,右边的两个显示倒计时,左边的不显示,当进行答题倒计时的时候,最左边的一个显示答题者的号码,右边的两个显示答题倒计时。当答题者犯规抢答的时候,最左边的显示答题者的号码,右边的两个显示数字0。当清零后,最左边的和右边的两个,显示的都是0.从左往右数的第二个数码管不显示任何东西。

2.4 单片机模块

2.4.1单片机模块电路图

 

图4

2.4.2单片机模块功能

在硬件上该单片机的P3口的P3.2、P3.3作为主持人的控制开关,P1口的P1.0-P1.5作为答题者的抢答开关,P2与P0口共同作为显示数码管的地址线输出口,P0口作为显示数码管的数据线输出口。且在Proteus中可以直接编辑该单片机的属性,从而直接为其选择12M的晶振周期,因此没有外接的晶振模块。

在软件上,该单片机的作为程序的存储器及运行器,源程序的输入从P3、P1口输入,源程序的输出从P2、P0口输出。

 

 

 

 

 

 

 

 

 

3  系统软件设计

3.1  C语言源程序数据结构设计

3.2.1 段码数组

unsigned char code

table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x76};//数字0~9

该数组的作用是,显示数字时从这个数组中查找对应的段码送到数码管中。

3.2  C语言源程序函数描述

3.2.1延时函数 void delay(uchar x)

函数的参数有一个无符号字符类型的参数,即x毫秒。此函数作用是延时,即数码管显示某个数字时延迟一定时间。具体实现方法是利用两层嵌套for循环,达到延迟一定时间的目的。

3.2.2 抢答函数 void qiangdaz()

此函数没有参数,它的作用是实现主持人控制开关按下后,开始倒计时,并判断出是几号答题者抢答的,然后进入回答函数,执行相应的操作。实现方法是,利用三层for循环,前两层的作用是秒的十位与个位的递减,第三层的作用在一秒内刷新数码管一定的次数。也就是三层for循环在一秒内秒把十位与个位同时刷新相同的次数。然后,每次刷新时再判断,是否有答题者抢答以及抢答者的号码,若有抢答的人就进入回答函数。具体的硬件方法是,每次显示数字时,利用P2口作为片选口选择需要点亮的数码管,然后再利用P0口向数码管送入相对于数字的共阴极段码并延时,然后对下一个数码管做类似的操作。判断是否有人抢答时,利用P1口的电平变化,正常情况下,P1口的值为0xff,如果有人按下抢答开关,那么P1口的值不再是0xff,然后再判断抢答者的号码,过程是,先对P1口取反,然后再判断P1口的值,0x01,0x02,0x04,0x08,0x10,0x20对应的抢答者的号码分别是1,2,3,4,5,6.

3.2.3 回答函数 void huida(uchar b)

此函数有一个无符号字符类型的参数,即b号答题者。它的作用是实现答题者抢答成功后,显示抢答者的号码、答题倒计时,且判断主持人是否按下清零开关。实现方法同样是,与抢答函数中类似的三层for循环,只不过需要多显示一个抢答者的号码,且第三层for循环中的判断是判断主持人是否按键。具体的硬件方法是,显示数字与抢答函数类似,判断按键时需要判断P3口的值,P3口的值为0xff,如果主持人按下抢答开关,那么P3口的值不再是0xff,具体过程是先对P3口取反,然后再判断P3口的值,0x04,0x08对应的分别是主持人按下开始键,清零键而区别后只对主持人按下清零键执行相应的操作,即,把显示数码管的需要显示数字都改为0,然后退出回答函数。

3.2.4 犯规函数 void fangui(uchar f)

此函数的参数是一个无符号字符类型的参数,即f号答题者。这个函数的作用是答题者犯规抢答后,显示犯规答题者的号数,一段时间后自动消失

3.2.5 主函数 void main()

此函数没有参数。它是我所知的所有C语言程序必须的。首先是一个死循环,然后判断主持是否按键,若主持人按键,则进入抢答函数,主持人没有按键时,再判断答题者是否按键,如果答题者按键,则进入犯规函数。然后如此循环下去。

 

 

 

 

 

 

 

 

 

 

3.3  C语言源程序算法描述

3.3.1主函数流程图

 

 

 

 

图5

3.3.2 抢答函数流程图

 

 

 

图6

3.3.3 犯规函数流程图


 

 

图7

3.3.4 回答函数流程图

 

 


图8

 

 

 

 

 

 

 

4  仿真与性能测试

4.1  C语言程序在Proteus电路图中运行结果图

1.未产生任何按键时与程序运行结果如图9

 

图9

2.主持人按键开始抢答运行结果如图10

 

图10

3.答题者按键抢答成功,答题运行结果如图11

 

图11

 

 

 

 

 

4.答题者答题结束清零运行结果如图12

 

图12

5.答题者犯规抢答运行结果如图13

 

图13


参考文献

[1] 江世明.基于Proteus的单片机应用技术.北京:电子工业出版社,2008

[2] 楼然苗,李光飞.单片机课程设计指导.北京:北京航空航天大学出版社,2007

[4] 徐钧爱.单片机C语言编程与Proteus仿真技术.北京:电子工业出版社,2016

[5] 赵全利,肖兴达.单片机原理及应用技术.北京:机械工业出版社,2007

[6] 潘新民,王燕芳.微型计算机控制技术.北京:电子工业出版社,2011

[7] 万光毅.单片机实验与实践教程.北京:北京航空航天大学出版社,2003

[8] 冯波琴,吴宁.微机计算机原理与接口技术.北京:清华大学出版社,2007

[9] 李泉溪.单片机原理与应用实例仿真.北京:北京航空航天大学出版社,2009

[10] 郭建江.单片机技术与应用.南京:南京东南大学出版社,2008

      

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Proteus 总电路图

 

图14

 

 

附代码

 

#include <reg51.h>
#include <absacc.h>
#define wdz XBYTE [0xf002] //位地址
#define ddz XBYTE [0xf004] //段地址
#define uchar unsigned char
//主持人按键P3口
sbit zcr=P3^2;
//开始键
sbit new=P3^3;
//清零键
unsigned char code
table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x76};
//数字0~9
uchar gws=9,qdsws=2,dtsws=5;
//个位数,抢答十位数,定时十位数
uchar numzcr=0,numxs=0,numnew,keyxs,keyzcr;
//主持人,选手,主持人清零,选手接口,主持人接口
void delay(uchar x)//延时 x ms
{
int i,j,k;
k=x+x;
for(i=0;i<k;i++)
{ for(j=0;j<250;j++);}
} //延时 x ms 结束
void huida(int b); //回答函数

void qiangda()//抢答函数,抢答倒计时30s
{
int i,j,k;
for (i=2;i>=0;i--)
{
for (j=9;j>=0;j--)
{
for (k=0;k<50;k++)//保持不闪
{
wdz=0x02;
ddz=table[i];//十位数字
delay(2);
wdz=0x01;
ddz=table[j];//个位数字
delay(2);
if (P1!=0XFF)
{
keyxs=~P1;
switch(keyxs)
{
case 0x01:numxs=1;break;
case 0x02:numxs=2;break;
case 0x04:numxs=3;break;
case 0x08:numxs=4;break;
case 0x10:numxs=5;break;
case 0x20:numxs=6;break;
default:break;
}
huida(numxs);
return;//抢答结束
}
}
}
}
}//抢答函数结束
void huida(uchar b) //答题倒计时60s
{
int i,j,k,m,n;
for (i=5;i>=0;i--)
{
for (j=9;j>=0;j--)
{
for (k=0;k<50;k++) //保持不闪
{
wdz=0x08;
ddz=table[b];//选手号码
delay(1);
wdz=0x02;
ddz=table[i];//十位数字
delay(1);
wdz=0x01;
ddz=table[j];//个位数字
delay(1);
if (P3!=0XFF)//主持人是否按键
{
delay(1);
if (P3!=0XFF)//再次确认
{
keyzcr=~P3;
switch(keyzcr)
{
case 0x04:numzcr=1;break; //开始,暂停
case 0x08:numnew=1;break; //清零
default:break;
}
if (numzcr==0)//暂停,不过暂时还做不到。
{
for (m=0;m<200;m++)//延迟一段时间
{
wdz=0x08;
ddz=table[b];//选手号码
delay(1);
wdz=0x02;
ddz=table[i];//十位数字
delay(1);
wdz=0x01;
ddz=table[j];//个位数字
delay(1);
}
return;//结束
} //暂停结束
else if (numnew==1) //清零
{
for (n=0;n<200;n++)//延迟一段时间
{
wdz=0x08;
ddz=table[0];//选手号码0
delay(1);
wdz=0x02;
ddz=table[0];//十位数字0
delay(1);
wdz=0x01;
ddz=table[0];//个位数字0
delay(1);
}
return;//结束
}//清零结束
else
{ } // default 情况下什么都不做
}//确认结束
}// 按键结束
}//第三个for结束
}
}
}//回答函数结束
void fangui(uchar f) //犯规抢答函数
{
int i;
for (i=0;i<100;i++)//延迟一段时间
{
wdz=0x08;
ddz=table[f];//选手号码
delay(1);
wdz=0x02;
ddz=table[0];//十位数字0
delay(1);
wdz=0x01;
ddz=table[0];//个位数字0
delay(1);
}
}//犯规抢答函数结束
void main()
{
while(1)
{
if(zcr==0)//判断主持人是否按键
{
delay(1);
if(zcr==0)
{
numzcr=1;
qiangda();//数码管显示数字,抢答倒计时开始
}
}
else if(new==0)//判断是否清零
{
delay(1);
if(new==0)
P2=0xff;
P0=0xff;//从头开始
}
else if (P1!=0XFF)
{
delay(1);
if (P1!=0XFF)
{
keyxs=~P1;
switch(keyxs)
{
case 0x01:numxs=1;break;
case 0x02:numxs=2;break;
case 0x04:numxs=3;break;
case 0x08:numxs=4;break;
case 0x10:numxs=5;break;
case 0x20:numxs=6;break;
default:break;
}
fangui(numxs);
return; //犯规显示结束
}
}//最后一个else if结束
}//while结束
}//main结束

 

posted on 2022-10-05 19:31  逆凌  阅读(664)  评论(0编辑  收藏  举报