51单片机的六路抢答器Protues仿真设计,附演示和源程序
电路一点通 2025-02-07
目录

一、设计背景

二、实现功能

三、仿真演示

四、源程序(部分)


一、设计背景

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

为了保证抢答过程的准确性和公平性,设计中还需要考虑到以下因素。首先,按键模块需要具备快速响应和高可靠性,以确保抢答者的动作能够被准确地捕捉到。其次,显示屏模块需要能够实时更新抢答结果,并显示相应的信息,比如参与者的编号和抢答时间。最后,在电路连接方面,需要注意各个模块之间的线路布局,以避免信号干扰和电气问题。 软件系统采用C语言编写程序,包括显示程序,定时中断服务,延时程序等,并在KEIL5中调试运行,硬件系统利用PROTEUS8.13强大的功能来实现,简单切易于观察,在仿真中就可以观察到实际的工作状态。

二、实现功能

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

(1)设定矩阵键盘的6个键作为6位选手的抢答按键,键的编号即选手编号,为1~6号;设定1个独立按键作为抢答开始键;选择四位数码管作为倒计时、选手编号显示;选择蜂鸣器作为正常抢答和犯规抢答的提示。
(2)只有当裁判按下开始键时才可以进入正常抢答,否则属于犯规抢答。抢答完毕,或计时时间到,停止抢答。当裁判按下抢答开始键时,开始抢答,计时器开始倒计时,10秒倒计期间,若有抢答,则停止计时,数码管显示选手号;若倒计时结束时无人抢答,则停止抢答。
(3)正常抢答时,有效抢答指示灯亮起,蜂鸣器播放音乐1,低位数码管数码管显示抢答选手的编号,高位数码管开始60s倒计时,60s时间到,数码管显示0-00。违规抢答时,无效抢答指示灯亮起,蜂鸣器播放音乐2,低位数码管显示违规抢答选手编号,高位数码管显示抢答倒计时时间10s。

三、仿真演示

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

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


按下启动按键,进入抢答界面,开始10秒抢答倒计时。

在抢答倒计时范围内,按下序号为1~6的选手抢答按键,抢答有效指示灯亮起,蜂鸣器播放《两只老虎》的旋律,低位数码管上显示抢答选手序号,高位数码管开始60s倒计时。


当裁判未按下开始键时,若有选手抢答视为犯规抢答,抢答无效指示灯亮起,蜂鸣器播放《粉刷匠》的旋律,低位数码管显示犯规选手的编号,高位数码管显示10。


正常抢答还是犯规抢答结束后,按下复位按钮恢复到准备界面,以便进行下一次抢答。



四、源程序(部分)


#include "reg52.h" #include "delay.h" #include "smg.h" #include "timer.h" sbit Beep = P1^5; //六位选手 sbit key1 = P1^1; sbit key2 = P1^2; sbit key3 = P1^3; sbit key4 = P1^4; sbit key5 = P1^5; sbit key6 = P1^6; sbit EffectLED = P2^6; //抢答有效指示灯 sbit UeffectLED = P2^7; //抢答无效指示灯 sbit start_stop = P3^1; //抢答按钮 sbit L1 = P1^7; sbit L2 = P1^6; sbit R1 = P1^3; sbit R2 = P1^2; sbit R3 = P1^1; sbit R4 = P1^0; //**《两只老虎》 uint8 code x0[]={1+7,2+7,3+7,1+7,1+7,2+7,3+7,1+7,3+7,4+7,5+7,3+7,4+7,5+7,5+7,6+7,5+7,4+7,3+7,1+7,5+7,6+7,5+7,4+7,3+7,1+7,1+7,5,1+7,1+7,5,1+7}; uint8 code y0[]={4,4,4,4,4,4,4,4,4,4,8,4,4,8,3,1,3,1,4,4,3,1,3,1,4,4,4,4,8,4,4,8}; //**《粉刷匠》 uint8 code x1[]={5+7,3+7,5+7,3+7,5+7,3+7,1+7,2+7,4+7,3+7,2+7,5+7,5+7,3+7,5+7,3+7,5+7,3+7,1+7,2+7,4+7,3+7,2+7,1+7,2+7, 2+7,4+7,4+7,3+7,1+7,5+7,2+7,4+7,3+7,2+7,5+7,5+7,3+7,5+7,3+7,5+7,3+7,1+7,2+7,4+7,3+7,2+7,1+7}; uint8 code y1[]={4,4,4,4,4,4,8,4,4,4,4,16,4,4,4,4,4,4,8,4,4,4,4,16,4,4,4,4,4,4,8,4,4,4,4,16,4,4,4,4,4,4,8,4,4,4,4,16}; //以下定义低中高共21个音阶的定时参数,通过定时器来实现不同音频的输出 uint8 code ti[21][2]={ {0xf8,0x8c},{0xf9,0x5c},{0xfa,0x14},{0xfa,0x67},{0xfb,0x04},{0xfb,0x90},{0xfc,0x0c}, //低音 {0xfc,0x44},{0xfc,0xb6},{0xfd,0x09},{0xfd,0x34},{0xfd,0x82},{0xfd,0xc8},{0xfe,0x06}, //中音 {0xfe,0x22},{0xfe,0x56},{0xfe,0x8c},{0xfe,0x9a},{0xfe,0xc1},{0xfe,0xe4},{0xff,0x03}}; //高音 uint8 th,tl,i; _bool action = 0; _bool key1_flag = 0; _bool key2_flag = 0; _bool key3_flag = 0; _bool key4_flag = 0; _bool key5_flag = 0; _bool key6_flag = 0; _bool start_stop_flag = 0; //抢答标志位 _bool cntflag=0; uint8 second = 10; //时间 uint8 timer0_count = 0; //定时器1计数值 uint8 number = 0; //队号 uint8 number_display = 0; //队号显示 uint8 a = 0xff; //按键值 uint8 key_scan8(void); void start_stop_keyscan(void); void music1(void);//演奏《两只老虎》 void music2(void);//演奏《粉刷匠》 void keycheckdown(void); /* 反转法键盘扫描 */ /*----------------------------------------------------------- 主函数 ------------------------------------------------------------*/ void SMG_delay(uint8 t) { while(t--) { display(number_display,second); } } void main() { ConfigTimer();//定时器初始化 while(1) { start_stop_keyscan();//开始按键 keycheckdown(); if(key_scan8()&&action==0&&cntflag==0) { UeffectLED=0; EffectLED=1; music2(); cntflag=1; } while(action)//按下开始键为1,抢答结束为0 { keycheckdown(); if(cntflag==1) { number_display=0; cntflag=0; } while(!key_scan8()) //无队抢答 { keycheckdown(); display(number_display,second); if(second == 0) { break; } } if(number_display)//有队抢答 { EffectLED=0; UeffectLED=1; second=60; music1(); } while(number_display) { display(number_display,second); TR0 = 1; if(second == 0) { break; } } TR0 = 0;//时间到 display(number_display,second); action = 0;//抢答结束 break; } display(number_display,second); } } void music1(void)//演奏《两只老虎》 { for(i=0;i<14;i++) { th=ti[x0[i]-1][0]; tl=ti[x0[i]-1][1]; TH1=th; TL1=tl; TR1=1; SMG_delay(y0[i]*10); TR1=0; } } void music2(void)//演奏《粉刷匠》 { for(i=0;i<12;i++) { th=ti[x1[i]-1][0]; tl=ti[x1[i]-1][1]; TH1=th; TL1=tl; TR1=1; SMG_delay(y1[i]*9); TR1=0; } } /*----------------------------------------------------------- 中断服务函数 ------------------------------------------------------------*/ 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; } } } /*----------------------------------------------------------- 开始键扫描函数 ------------------------------------------------------------*/ void start_stop_keyscan(void) { if(start_stop == 0) { SMG_delay(8); if((start_stop == 0)&&(!start_stop_flag)) { start_stop_flag = 1; action = 1; TR0 = 1; } while(start_stop == 0){display(number_display,second);} } else { start_stop_flag = 0; } } void keycheckdown() { L1=0;L2=1; R1=R2=R3=R4=1; if(R1==0) { while(R1==0) { display(number_display,second); } a=1; } else if(R2==0) { while(R2==0) { display(number_display,second); } a=2; } else if(R3==0) { while(R3==0) { display(number_display,second); } a=3; } else if(R4==0) { while(R4==0) { display(number_display,second); } a=0x4; } L2=0;L1=1; R1=R2=R3=R4=1; if(R1==0) { while(R1==0) { display(number_display,second); } a=0x5; } else if(R2==0) { while(R2==0) { display(number_display,second); } a=0x6; } else if(R3==0) { while(R3==0) { display(number_display,second); } a=0x7; } else if(R4==0) { while(R4==0) { display(number_display,second); } a=0x8; } } /*----------------------------------------------------------- 六位抢答键扫描函数 ------------------------------------------------------------*/ 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 == 0x4)&&(!key4_flag)) { key4_flag = 1; number = 4; number_display = number; } else { key4_flag = 0; number = 0; } if((a == 0x5)&&(!key5_flag)) { key5_flag = 1; number = 5; number_display = number; } else { key5_flag = 0; number = 0; } if((a == 0x6)&&(!key6_flag)) { key6_flag = 1; number = 6; number_display = number; } else { key6_flag = 0; number = 0; } if(number_display != 0) { return 1; } else { return 0; } } void Timer1Service() interrupt 3 /* T0中断服务程序 */ { Beep=~Beep; TH1=th; TL1=tl; }



声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 【7.24 深圳】2025国际AI+IoT生态发展大会/2025全球 MCU及嵌入式技术论坛


  • 相关技术文库
  • 单片机
  • 嵌入式
  • MCU
  • STM
  • 3AT89C51单片机引脚说明及引脚图

    AT89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU...

    07-11
  • 51单片机对LCD1602液晶的驱动设计

    51单片机——LCD1602 1、1602液晶读写时序 (1)、读状态 RS=L,R/W=H,E=H。(判断忙完毕后释放总线) (2)、读数据 RS=H,R/W=H,E=H。 (3)、写指令 RS=L,R/W=L,D0~D7=指令码,E=高脉冲 (4)、写数据 RS=H,R/W=L,D0~D...

    07-11
  • 单片机串口如何接收不定长数据的?

    我们在使用其他STM32的单片机的时候,会发现有些困难,会发现常用的方法并不能用,在还没有接收完数据的时候,就解决不了。于是,只能用通用的方法来解决了。 这个通用的方法,其实原理和使用IDLE的原理一样:...

    07-11
  • ARM处理器的选型原则

    鉴于ARM微处理器的众多优点,随着国内外嵌入式应用领域的逐步发展,ARM微处理器必然会获得广泛的重视和应用。但是,由于ARM微处理器有多达十几种的内核结构,几十个芯片生产厂家,以及千变万化的内部功能配置组合,...

    07-10
  • 有哪些低功耗设计方法?单片机系统低功耗设计要点介绍

    功耗,已经是一个老生常谈的话题了。对于功耗,大家多多少少有所了解。目前,很多产品的宣传里便带有低功耗噱头。为增进大家对功耗的认识,本文将基于两点介绍功耗:1.低功耗主要设计方法,2.单片机系统低功耗设计...

    07-10
  • 8位32位MCU如何选择?如何选择合适的MCU?

    MCU,对于普通人而言,是一个高大上的存在。但是,在工业中,MCU确实常见产品。为增进大家对MCU的认识,本文将基于两点介绍MCU:1.8位MCU和32位MCU如何选择?2.如何选择合适的MCU。如果你对MCU具有兴趣,不妨继续往...

    07-09
  • ARM开发:一 ARM微处理器概述

    1.1ARM-Advanced RISC Machines ARM(Advanced RISC Machines),既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。 1991年ARM公司成立于英国剑桥,主要出售芯片设计技术...

    07-08
  • 分析C51单片机的一些误区和注意事项

    简介:常看见初学者要求使用_at_,这是一种谬误,把C当作ASM看待了。在C中变量的定位是编译器的事情,初学者只要定义变量和变量的作 用域,编译器就把一个固定地址给这个变量。怎么取得这个变量的地址?要用指针。 1) C...

    07-08
  • 51单片机几个延时程序

    简介:51单片机几个精确延时程序:在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响. 一. 500ms延时子程序(晶振12MHz,一个机器周期1us.) 程...

    07-08
  • 总结单片机软件抗干扰的几种办法

    简介:在提高硬件系统抗干扰能力的同时,软件抗干扰以其设计灵活、节省硬件资源、可靠性好越来越受到重视。下面以MCS-51单片机系统为例,对微机系统软件抗干扰方法进行研究。 1、软件抗干扰方法的研究 在工程实践中...

    07-08
  • 基于C51单片机实现汽车座椅自动控制系统的软硬件设计

    引言 随着人们生活水平的提高,对汽车座椅的舒适性要求也越来越高,要求对汽车座椅地调节能够更加简单、方便、快捷。目前,汽车座椅位置的调节多采用基于手动调节方式的机械和电动控制两种方式。汽车座椅位置的调节...

    07-02
  • MCS51单片机程序设计时堆栈的计算方法解析

    用C语言进行MCS51系列单片机程序设计是单片机开发和应用的必然趋势。Keil公司的C51编译器支持经典8051和8051派生产品的版本,通称为Cx51。应该说,Cx51是C语言在MCS51单片机上的扩展,既有C语言的共性,又有它自己...

    07-02
下载排行榜
更多
评测报告
更多
广告