一、设计背景
近年来随着科技的飞速发展,单片机的应用正在不断的走向深入。本文阐述了基于51单片机的八路抢答器设计。本设计中,51单片机充当了核心控制器的角色,通过IO口与各个功能模块相连接。按键模块负责检测参与者的抢答动作,当有人按下抢答按钮时,会通过IO口电平的变化通知单片机,单片机会记录按键的次序,并通过数码管显示当前的抢答结果。
为了保证抢答过程的准确性和公平性,设计中还需要考虑到以下因素。首先,按键模块需要具备快速响应和高可靠性,以确保抢答者的动作能够被准确地捕捉到。其次,显示屏模块需要能够实时更新抢答结果,并显示相应的信息,比如参与者的编号和抢答时间。最后,在电路连接方面,需要注意各个模块之间的线路布局,以避免信号干扰和电气问题。
软件系统采用C语言编写程序,包括显示程序,定时中断服务,延时程序等,并在KEIL5中调试运行,硬件系统利用PROTEUS8.11强大的功能来实现,简单切易于观察,在仿真中就可以观察到实际的工作状态。
二、实现功能
以51单片机为控制核心,设计一种四路抢答器。整个系统包括MCU、晶振电路、时钟电路、功能按键以及数码管显示。该系统利用共阳数码管实时显示抢答倒计时时间,通过独立按键设计控制抢答器的启动、复位、以及不同选手的抢答。可具体实现以下功能:
(1) 按下启动键后,在10s倒计时的过程中,按下任意路抢答按键,数码管上对应显示抢答选手的序号并开始60s倒计时,60s倒计时结束后,抢答数据清零。
(2) 按下复位键后,抢答器复位,再次按下启动键可以实现新一轮的抢答。
(3)·定时器定时50ms,20次定时可产生1秒钟计时。
三、仿真演示
未运行仿真时,数码管不显示。
运行仿真后,进入准备界面,数码管显示默认抢答序号0和抢答倒计时10秒。
按下启动按键,进入抢答界面,开始10秒抢答倒计时,并在数码管上实时显示。
在抢答倒计时范围内,按下序号为1~4的选手抢答按键,抢答倒计时归零,数码管上显示抢答选手序号和倒计时60秒。
60s倒计时结束后,数码管显示0-00,表示1次抢答结束。
按下复位按钮恢复到准备界面,以便进行下一次抢答。
四、源程序(部分)
#include "reg52.h"
#include "delay.h"
#include "smg.h"
#include "timer.h"sbit key1 = P1^0; //四位选手
sbit key2 = P1^1;
sbit key3 = P1^2;
sbit key4 = P1^3;sbit start_stop = P3^6; //抢答按钮_bool action = 0;
_bool key1_flag = 0;
_bool key2_flag = 0;
_bool key3_flag = 0;
_bool key4_flag = 0;_bool reset_flag = 0; //复位标志位
_bool start_stop_flag = 0; //抢答标志位uint8 second = 10; //时间
uint8 timer0_count = 0; //定时器1计数值
uint8 number = 0; //队号
uint8 number_display = 0; //队号显示uint8 key_scan8(void);
void start_stop_keyscan(void);
/*-----------------------------------------------------------
主函数
------------------------------------------------------------*/
void main()
{ConfigTimer0();//定时器初始化while(1){start_stop_keyscan();//开始按键while(action)//按下开始键为1,抢答结束为0{while(!key_scan8()&&!reset_flag) //无队抢答{display(number_display,second);if(second == 0){break;}}if(number_display)//有队抢答{second=60;}while(number_display&&!reset_flag){display(number_display,second);TR0 = 1;if(second == 0){break;}}TR0 = 0;//时间到display(number_display,second);action = 0;//抢答结束break;}display(number_display,second); }
}/*-----------------------------------------------------------
中断服务函数
------------------------------------------------------------*/
void timer0() interrupt 1
{TH0 = (65536-50000)/256; //50msTL0 = (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){Delay_ms(8);if((start_stop == 0)&&(!start_stop_flag)){start_stop_flag = 1;action = 1;TR0 = 1;reset_flag = 0;}}else{start_stop_flag = 0; }
}/*-----------------------------------------------------------
四位抢答键扫描函数
------------------------------------------------------------*/
uint8 key_scan8(void)
{if(key1 == 0){Delay_ms(8);if((key1 == 0)&&(!key1_flag)){key1_flag = 1;number = 1;number_display = number;}}else{key1_flag = 0;number = 0; }if(key2 == 0){Delay_ms(8);if((key2 == 0)&&(!key2_flag)){key2_flag = 1;number = 2;number_display = number;}}else{key2_flag = 0;number = 0; }if(key3 == 0){Delay_ms(8);if((key3 == 0)&&(!key3_flag)){key3_flag = 1;number = 3;number_display = number;}}else{key3_flag = 0;number = 0; }if(key4 == 0){Delay_ms(8);if((key4 == 0)&&(!key4_flag)){key4_flag = 1;number = 4;number_display = number;}}else{key4_flag = 0;number = 0; }if(number_display != 0) {return 1;}else{return 0;}
}/*-----------------------------------------------------------
复位键外部中断函数
------------------------------------------------------------*/
void EXINT0() interrupt 0 //外部中断0触发函数
{if(!reset_flag){reset_flag = 1;number_display = 0;action=0;second=10;}}
仿真源文件及源程序百度网盘链接:https://pan.baidu.com/s/1xKDNPqCrTqCiqI-F8pCGcQ
提取码:v8a3