基于51单片机的五路抢答器Protues仿真设计

目录

一、设计背景

二、实现功能

三、仿真演示

四、源程序(部分)


一、设计背景

        近年来随着科技的飞速发展,单片机的应用正在不断的走向深入。本文阐述了基于51单片机的五路抢答器设计。本设计中,51单片机充当了核心控制器的角色,通过IO口与各个功能模块相连接。按键模块负责检测参与者的抢答动作,当有人按下抢答按钮时,会通过IO口电平的变化通知单片机,单片机会记录按键的次序,并通过数码管显示当前的抢答结果。

        为了保证抢答过程的准确性和公平性,设计中还需要考虑到以下因素。首先,按键模块需要具备快速响应和高可靠性,以确保抢答者的动作能够被准确地捕捉到。其次,显示屏模块需要能够实时更新抢答结果,并显示相应的信息,比如参与者的编号和抢答时间。最后,在电路连接方面,需要注意各个模块之间的线路布局,以避免信号干扰和电气问题。

       软件系统采用C语言编写程序,包括显示程序,定时中断服务,延时程序等,并在KEIL5中调试运行,硬件系统利用PROTEUS8.11强大的功能来实现,简单切易于观察,在仿真中就可以观察到实际的工作状态。

二、实现功能

        以51单片机为控制核心,设计一种五路抢答器。整个系统包括MCU、晶振电路、时钟电路、蜂鸣器控制电路、指示灯控制电路、独立按键电路、矩阵键盘以及数码管显示电路等。可具体实现以下功能:

     (1)设定矩阵键盘的5个键作为5位选手的抢答按键,键的编号即选手编号,为1~5号,同时设定5个LED灯作为5位选手抢答状态指示;设定1个独立按键作为抢答开始键;选择两位数码管作为倒计时、选手编号及犯规显示;选择蜂鸣器作为开始、抢答、犯规和计时结束的提示。
     (2)只有当裁判按下开始键时才可以进入正常抢答,否则属于犯规抢答。抢答完毕,或计时时间到,停止抢答,数码管显示0。当裁判按下抢答开始键时,开始抢答,计时器开始倒计时,10秒倒计期间,若有抢答,则停止计时,相应选手的LED灯亮,数码管显示选手号;若倒计时结束时无人抢答,则停止抢答。
     (3)正确抢答时,抢答选手的LED灯缓慢闪烁,数码管显示抢答选手的编号;犯规抢答时,犯规选手的LED灯快速闪烁,低位数码管显示犯规选手的编号,高位数码管显示F(foul,犯规)。
       (4)开始抢答按键按下时、倒计时结束时和抢答键按下时蜂鸣器响1声,犯规时响2声。

三、仿真演示

未运行仿真时,数码管不显示。

运行仿真后,进入准备界面,数码管显示00。

按下启动按键,蜂鸣器响一声,进入抢答界面,开始10秒抢答倒计时。

在抢答倒计时范围内,按下序号为1~5的选手抢答按键,蜂鸣器响1声,数码管上显示抢答选手序号,并且相应序号的指示灯缓慢闪烁4次。

当裁判未按下开始键时,若有选手抢答视为犯规抢答,蜂鸣器响2声指示犯规抢答犯规选手的LED灯快速闪烁20次,低位数码管显示犯规选手的编号,高位数码管显示F。

无论是正常抢答还是犯规抢答,指示灯停止闪烁后,数码管显示00,表示一次抢答结束。

按下复位按钮恢复到准备界面,以便进行下一次抢答。

四、源程序(部分)

#include "reg52.h"
#include "delay.h"
#include "smg.h"
#include "timer.h"

sbit key1Led = P3^1;	//四位选手
sbit key2Led = P3^2;
sbit key3Led = P3^3;
sbit key4Led = P3^4;
sbit key5Led = P3^5;
sbit start_stop = P3^6;	//抢答按钮
sbit Beep = P3^7;	//抢答按钮
_bool action = 0;
_bool key1_flag = 0;
_bool key2_flag = 0;
_bool key3_flag = 0;
_bool key4_flag = 0;
_bool key5_flag = 0;

_bool Rush_flag = 0;

_bool reset_flag = 0; //复位标志位
_bool start_stop_flag = 0; //抢答标志位
_bool BeepF=0;	

uint8 second = 0;	//时间
uint8 timer0_count = 0;	//定时器1计数值
uint8 LedFre0Count = 0;
uint8 LedFre1Count = 0;
uint8 number = 0; //队号
uint8 number_display = 0;	//队号显示
uint8 a = 0xff;	//按键值
uint8 key_scan8(void);
uint8 Fval = 0;
void start_stop_keyscan(void);
void keycheckdown(void);				/* 反转法键盘扫描 */
/*-----------------------------------------------------------
主函数
------------------------------------------------------------*/
void LedDisplay(uint8 _number)
{
	switch(_number)
	{
		case 1:
			key1Led=~key1Led;
		break;
		case 2:
			key2Led=~key2Led;
		break;
		case 3:
			key3Led=~key3Led;
		break;
		case 4:
			key4Led=~key4Led;
		break;
		case 5:
			key5Led=~key5Led;
		break;
	}
}
void SMG_delay(uint8 t)
{
	while(t--)
	{
	  display(second);
	}
}

void SMG_Bdelay(uint8 t)
{
	while(t--)
	{
      P2 = 0xfe;
			P0 = table[number_display];
			Delay_ms(2);
			
			P2 = 0xfd;
			P0 = table[15];
			Delay_ms(2);		
	}
}

void keycheckdown()				/* 反转法键盘扫描 */
{
	short temp1,temp2,temp;
	P1=0xf0;						/* 输入行值(或列值) */
  SMG_delay(20);
	temp1=P1;						/* 读列值(或行值) */
	P1=0xff;
  SMG_delay(20);
	P1=0x0f;						/* 输入列值(或行值) */
  SMG_delay(20);
	temp2=P1;						/* 读行值(或列值) */
	P1=0xff;
	temp=(temp1&0xf0)|(temp2&0xf);	/* 将两次读入数据组合 */
	switch(temp)					/* 通过读入数据组合判断按键位置 */
	{
		case 0x77 :a=0x0a;break;//  按键+   
		case 0x7b :a=0x0e; break;// 按键=	
		case 0x7d :a=0;	   break;// 按键0
		case 0x7e :a=0x0f; break;// 按键CE

		case 0xe7 :a=0x0d;break;// 	按键/
		case 0xeb :a=0x9;break; //  按键9
		case 0xed :a=0x8;break; //  按键8 
		case 0xee :a=0x7;break; // 	按键7

		case 0xd7 :a=0x0c;break;//  按键*
		case 0xdb :a=0x6;break; // 	按键6
		case 0xdd :a=0x5;Beep=0;SMG_delay(500);Beep=1;break; // 	按键5
		case 0xde :a=0x4;Beep=0;SMG_delay(500);Beep=1;break; // 	按键4

		case 0xb7 :a=0x0b; break;// 按键-
		case 0xbb :a=3;Beep=0;SMG_delay(500);Beep=1;break;	//  按键3
		case 0xbd :a=2;Beep=0;SMG_delay(500);Beep=1;break;	//  按键2
		case 0xbe :a=1;Beep=0;SMG_delay(500);Beep=1;break;	//  按键1

		default :a=0xff;
	}
}

void main()
{
	ConfigTimer0();//定时器初始化
	while(1)
	{
		start_stop_keyscan();//开始按键
		keycheckdown();//键盘扫描	
		Fval=key_scan8();
		if(action)//有队抢答
		{
		   second=10;
		}
		else
		{
			if(a!=0xff)
			{
			   Rush_flag=1;//违规抢答
				 second=8;
				 TR0=1;
			}		
		}
    while(Rush_flag==1)
		{
			if(BeepF==0)
			{
				Beep=0;
				SMG_Bdelay(200);
				Beep=1;	
				SMG_Bdelay(200);
				Beep=0;
				SMG_Bdelay(200);
				Beep=1;	
        BeepF=1;				
			}
			P2 = 0xfe;
			P0 = table[number_display];
			Delay_ms(2);
			
			P2 = 0xfd;
			P0 = table[15];
			Delay_ms(2);		
			if(second==0)
			{
				Rush_flag=0;
				TR0=0;
				key1Led = 1;	
				key2Led = 1;
				key3Led = 1;
				key4Led = 1;
				key5Led = 1;	
        BeepF=0;					
				break;
			}
		}
		while(action==1)//按下开始键为1,抢答结束为0
		{
			while(!key_scan8())	//无队抢答
			{
				display(second);
				TR0 = 1;
				if(second == 0)
				{
					Beep=0;
			    SMG_delay(200);
			    Beep=1;
					break;
				}
				keycheckdown();//键盘扫描	
			}
			if(number_display)//有队抢答
			{
				second=8;
			}
			while(number_display)
			{
				display(number_display);
				if(second == 0)
				{
					key1Led = 1;	
					key2Led = 1;
					key3Led = 1;
					key4Led = 1;
					key5Led = 1;					
					break;			
				}
			}
			TR0 = 0;//时间到
			second=0;
			display(second);
			action = 0;//抢答结束
			break;
		}
		display(second);	
	}
}

/*-----------------------------------------------------------
中断服务函数
------------------------------------------------------------*/
void timer0() interrupt 1
{
	TH0 = (65536-50000)/256; //50ms
	TL0 = (65536-50000)%256;	
	timer0_count ++;
	if(timer0_count == 20)//1s
	{
		timer0_count = 0;
		second--;	//10s倒计时
		if(second == 0)//计时结束
		{
			TR0 = 0;
			number_display = 0;
			action = 0;
			second = 0;
		}
	}	
	if(number_display!=0)
	{
		if(Rush_flag==0)
		{  
			 LedFre0Count++;
			 if(LedFre0Count==20)
			 {
				 LedFre0Count=0;
			   LedDisplay(number_display);
			 }
		}
		else
		{
			 LedFre1Count++;
			 if(LedFre1Count==5)
			 {
				 LedFre1Count=0;
			   LedDisplay(number_display);
			 }	
		}
	}
}

/*-----------------------------------------------------------
开始键扫描函数
------------------------------------------------------------*/
void start_stop_keyscan(void)
{
	if(start_stop == 0)
	{
		SMG_delay(800);
		if((start_stop == 0)&&(!start_stop_flag))
		{
			start_stop_flag = 1;
			action = 1;
			TR0 = 1;
			Beep=0;
			SMG_delay(200);
			Beep=1;
			reset_flag = 0;
		}
	}
	else
	{
		start_stop_flag = 0;	
	}
}

/*-----------------------------------------------------------
四位抢答键扫描函数
------------------------------------------------------------*/
uint8 key_scan8(void)
{
	if((a == 1)&&(!key1_flag))
	{
		key1_flag = 1;
		number  = 1;
		number_display = number;
	}
	else
	{
		key1_flag = 0;
		number  = 0;	
	}
	
	if((a == 2)&&(!key2_flag))
	{
		key2_flag = 1;
		number  = 2;
		number_display = number;
	}
	else
	{
		key2_flag = 0;
		number  = 0;	
	}
	
	if((a == 3)&&(!key3_flag))
	{
		key3_flag = 1;
		number  = 3;
		number_display = number;
	}
	else
	{
		key3_flag = 0;
		number  = 0;	
	}
	
	if((a == 4)&&(!key4_flag))
	{
		key4_flag = 1;
		number  = 4;
		number_display = number;
	}
	else
	{
		key4_flag = 0;
		number  = 0;	
	}
	if((a == 5)&&(!key5_flag))
	{
		key5_flag = 1;
		number  = 5;
		number_display = number;
	}
	else
	{
		key5_flag = 0;
		number  = 0;	
	}			
	
	if(number_display != 0)	
	{
		return 1;
	}
	else
	{
		return 0;
	}	
}

仿真源文件及源程序百度网盘链接:https://pan.baidu.com/s/12J02HAeeTJgKW468viFx1g 
提取码:kc9n 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/790537.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python实现傅里叶级数可视化工具

Python实现傅里叶级数可视化工具 flyfish 有matlab实现,我没matlab,我有Python,所以我用Python实现。 整个工具的实现代码放在最后,界面使用PyQt5开发 起源 傅里叶级数(Fourier Series)由法国数学家和物理学家让-巴…

[激光原理与应用-106]:南京科耐激光-激光焊接-焊中检测-智能制程监测系统IPM介绍 - 9 - 图解常见的焊接缺陷/缺欠分类

目录 前言: 1、焊接缺陷的类型 2、焊接缺陷的危害 3、结论 一、功能性缺陷 1.1 虚焊:最重要的非视觉检测的缺陷 1.虚焊的定义 2.虚焊的成因 3.虚焊的危害 4.虚焊的检测与解决 二、成型性缺陷 2.1 黑爆缺陷 1、黑爆缺陷的定义与外观 2、黑爆…

深度优先搜索(所有可达路径)

参考题目:所有可达路径 题目描述 给定一个有 n 个节点的有向无环图,节点编号从 1 到 n。请编写一个函数,找出并返回所有从节点 1 到节点 n 的路径。每条路径应以节点编号的列表形式表示。 输入描述 第一行包含两个整数 N,M&…

红日靶场----(三)2.漏洞利用

上期的通过一句话木马实现对目标主机的持久后门 我使用的是蚁剑,蚁剑安装及使用参考: 下载地址: GitHub - AntSwordProject/AntSword-Loader: AntSword 加载器 安装即使用: 1. 快速入门 语雀 通过YXCMS的后台GETSHELL 利用…

C++第四弹 -- 类与对象(中上) (构造函数 析构函数 拷贝构造函数)

目录 前言构造函数1. 概念2. 特征 析构函数1. 概念2. 特征 拷贝构造函数1. 概念2. 特征 总结 前言 让我们一起揭开 C 对象生命周期管理的神秘面纱,掌握构造函数、析构函数和拷贝构造函数的精髓! 博客主页: 酷酷学!!! 期待更多好文, 点击关注~ 构造函…

Linux系统中磁盘管理LVM与挂载

Linux系统中磁盘管理LVM与挂载 本文以属于Linux系统基本概念,如果以查找教程教程,解决问题为主,只需要查看本文后半部分。如需要系统性学习请查看本文前半部分。 本文操作极容易导致主机无法自动重启,请慎重操作。操作前务必要进…

新手教学系列——crontab 使用不当引发的服务器性能问题

起因及症状 最近,我们的一台服务器随着运行时间的增加,逐渐出现了压力过大的问题。具体表现为数据库连接数飙升至 4000+,Redis 频繁超时,系统报错文件打开数过多等。针对这些问题,我们逐一检查了数据库连接池、Redis 连接池以及系统的 ulimit 配置,但都未能找到问题的根…

ROS服务通信自定义srv

服务通信自定义srv 流程:创建ROS功能包按照固定格式创建srv文件编译配置文件编译生成中间文件 流程: srv 文件内的可用数据类型与 msg 文件一致,且定义 srv 实现流程与自定义 msg 实现流程类似,需查阅msg文件的可以浏览ROS话题通信流程自定义数据msg格式…

7月报名 | 海克斯康CAEfatigue疲劳分析培训

您好!感谢您长期以来对优飞迪科技与海克斯康的关注与支持。我们诚邀您参加海克斯康CAEfatigue疲劳分析培训,特邀海克斯康原厂讲师将通过培训帮助您了解CAEfatigue的功能并使用其进行疲劳分析的过程、参数设置以及软件操作方法和技巧,学会使用…

VS2019使用C#写窗体程序技巧(1)

1、打开串口 private void button1_Click(object sender, EventArgs e){myPort cmb1.Text;mybaud Convert.ToInt32(cmb2.Text, 10);databit 8;parity Parity.None;stopBit StopBits.One;textBox9.Text "2";try{sp new SerialPort(myPort, mybaud, parity, dat…

Linux:进程池制作(基于匿名管道和命名管道两个版本)

Linux:进程池制作 & 匿名管道 & 命名管道 前言一、匿名管道制作进程池一、进程池框架二、创建管道、创建进程、工作进程执行任务2.1 创建管道、创建进程 2.2 工作进程执行任务三、主进程向子进程发送任务3.1 任务封装3.2 主进程向子进程发送任务 四、回收资…

数学建模·层次分析法

层次分析法 LAF 定义 具体用途 评价体系的优劣影响,计算评价指标的权重 主要步骤 关键在于一致性检验和求权值 权重的计算 注意权重之和为1,需要归一化 算数平均法 特征值法 矩阵的一致性检验 为什么要检验?:简单来说就…

Qt 实战(2)搭建开发环境 | 2.3、qmake详解

文章目录 一、qmake详解1、相关概念2、qmake作用3、运行qmake4、Qt Creator构建项目与执行qmake操作之间的区别4.1、功能与目的4.2、执行时机与流程 5、总结 前言: Qt qmake 是一个用于自动化生成 Makefile 的工具,它极大地简化了 Qt 应用程序和库的编译…

免费听书TV版v1.0.1

使用非常稳定流畅,UI界面设计美观简洁,纯净无广。资源虽然不是特别多,但是日常听书还是可以满足需求。 完全免费,操作简单方便,安装即用,没有任何限制。 可以适配遥控器操作,OK键开启或关闭语…

第二证券:销量暴跌95%,这一巨头市值蒸发超3000亿元!

在多重要素刺激下,PCB工作站上风口。 波音销量堕入停滞 6月仅售出3架客机 据央视财经,在一系列丑闻的影响下,波音公司本年出售遭到明显冲击。当地时间9日,波音发布的数据闪现,在以前一个月,该公司仅卖出…

【鸿蒙学习笔记】Stage模型

官方文档:Stage模型开发概述 目录标题 Stage模型好处Stage模型概念图ContextAbilityStageUIAbility组件和ExtensionAbility组件WindowStage Stage模型-组件模型Stage模型-进程模型Stage模型-ArkTS线程模型和任务模型关于任务模型,我们先来了解一下什么是…

旷野之间8 - LLMOps 与 MLOps操作化 AI 模型

介绍 随着人工智能越来越多地应用于商业应用,简化人工智能系统(尤其是机器学习模型)的开发和持续管理的新实践也不断涌现。MLOps 已成为一种基于 DevOps 原则实施机器学习的流行方法。 现在,随着 GPT-3 等大型语言模型 (LLM) 的…

火热夏季:浦语*书生InternLM大模型实战闯关-入门岛之Linux基础知识

一、ssh链接与端口映射并运行hello_wold.py 1.创建开发机 InternStudio创建开发机 2.进入开发机 3.Ssh链接开发机 powerShell终端ssh链接开发机。 4.创建一个hello_world.py文件web demo 5.运行web demo 6.端口映射 7.本地浏览器打开web 二、 VSCODE 远程连接开发机并创建一个…

LeetCode67(二进制求和[位运算,大数运算])

二进制求和 题目要求: 给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。 这道题其实有几种解法.我们先来介绍简单的方法. 我们可以将两个字符串的二进制转成十进制,获取对应值相加之后,我们可以不断对2取余,获取尾数拼接即可.也就是像我们平常求一…

笔试算法刷题

猿辅导2021校园招聘笔试(算法一) 牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com) 第一眼看到这个题想到的是蓝桥杯飞机降落,贪心题。但是这样算的是最大不相交区间数量&#xff0…