八路电子抢答器的设计与实现

这篇具有很好参考价值的文章主要介绍了八路电子抢答器的设计与实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

随着科学技术的发展和普及,各种各样的竞赛越来越多,其中抢答器的作用也就显而易见。本课程设计出以STC89C52RC单片机为核心,以八路抢答为基本理念,利用普中集成开发板设计八路抢答器。考虑到依需设定倒计时抢答的功能,利用51单片机及外围接口实现的抢答系统,利用单片机的定时器定时的原理,将软、硬件有机地结合起来,使得系统能够正确地进行计时,同时使用LCD1602显示倒计时和抢答者的序号。用按键输出,蜂鸣器发出抢答和倒计时提示。同时系统能够实现:在抢答中,只有当主持人按开始键后倒计时开始,倒计时结束并发出警示可以抢答,若抢答者提前抢答,将会在LCD上显示违规,且显示违规者的序号,抢答成功蜂鸣器发声并从LCD显示相应的抢答者序号;倒计时未结束,按键锁定;同时用Proteus进行仿真,实物和仿真都完美运行成功。

PROTEUS仿真

八路电子抢答器的设计与实现

main.c

//main.c
#include <REGX52.H>
#include "Timer0.H"
#include "Key.H"
#include "Timer1.H"
#include "INTRINS.H"
#include "LCD1602.H"
sbit Buzzer=P1^5;
unsigned char KeyNum,Sec=10,TimeLock,MemoryTime,UserKey,User;fault=0;    //调节Sec为计时初始值
void Buzzer_Delay500us()        
{
    unsigned char i;

    _nop_();
    i = 247;
    while (--i);
}
void Buzzer_Time(unsigned int ms)        //蜂鸣器播放,时间单位:ms
{
    unsigned int i;
    for(i=0;i<ms*2;i++)
    {
        Buzzer=!Buzzer;
        Buzzer_Delay500us();
    }
}

void main()
{    
    Timer0_Init();
    Timer1Init();
    LCD_Init();
    MemoryTime=Sec;        
    while(1)
    {    

        LCD_ShowString(1,1,"Count down:");
        if(fault==0){LCD_ShowString(2,1,"Responder:");}
        LCD_ShowNum(2,13,User,1);
        LCD_ShowNum(1,13,Sec,2);
        KeyNum=Key();
        UserKey=Matrix_Key();
        if(KeyNum)        //主持人按下按键执行:
        {        
            
                if(KeyNum==1){TimeLock=~TimeLock;ET1=1;Buzzer_Time(500);}
                if(KeyNum==2){TimeLock=0;fault=0;Sec=MemoryTime;User=0;ET1=1;}
                if(KeyNum==4){if(TimeLock==0){if(Sec<=60){Sec--;}MemoryTime=Sec;};}
                if(KeyNum==3){if(TimeLock==0){if(Sec>=0){Sec++;}MemoryTime=Sec;};}    
            
        }
        if(UserKey)
        {
            if(User==0)
            {
            switch(UserKey)        //选手按下按键执行:
//犯规抢答中断
//            {    
//                case 1:if(TimeLock&&Sec==0){User=1;ET1=0;Buzzer_Time(500);}break;
//                case 2:if(TimeLock&&Sec==0){User=2;ET1=0;Buzzer_Time(500);}break;
//                case 3:if(TimeLock&&Sec==0){User=3;ET1=0;Buzzer_Time(500);}break;
//                case 4:if(TimeLock&&Sec==0){User=4;ET1=0;Buzzer_Time(500);}break;
//                case 5:if(TimeLock&&Sec==0){User=5;ET1=0;Buzzer_Time(500);}break;
//                case 6:if(TimeLock&&Sec==0){User=6;ET1=0;Buzzer_Time(500);}break;
//                case 7:if(TimeLock&&Sec==0){User=7;ET1=0;Buzzer_Time(500);}break;
//                case 8:if(TimeLock&&Sec==0){User=8;ET1=0;Buzzer_Time(500);}break;        
//            }
//犯规抢答显示
            {    
                case 1:if(TimeLock){User=1;if(Sec!=0){LCD_ShowString(2,1,"Illegality:");LCD_ShowNum(2,13,User,1);fault=1;}ET1=0;Buzzer_Time(500);}break;
                case 2:if(TimeLock){User=2;if(Sec!=0){LCD_ShowString(2,1,"Illegality:");LCD_ShowNum(2,13,User,1);fault=1;}ET1=0;Buzzer_Time(500);}break;
                case 3:if(TimeLock){User=3;if(Sec!=0){LCD_ShowString(2,1,"Illegality:");LCD_ShowNum(2,13,User,1);fault=1;}ET1=0;Buzzer_Time(500);}break;
                case 4:if(TimeLock){User=4;if(Sec!=0){LCD_ShowString(2,1,"Illegality:");LCD_ShowNum(2,13,User,1);fault=1;}ET1=0;Buzzer_Time(500);}break;
                case 5:if(TimeLock){User=5;if(Sec!=0){LCD_ShowString(2,1,"Illegality:");LCD_ShowNum(2,13,User,1);fault=1;}ET1=0;Buzzer_Time(500);}break;
                case 6:if(TimeLock){User=6;if(Sec!=0){LCD_ShowString(2,1,"Illegality:");LCD_ShowNum(2,13,User,1);fault=1;}ET1=0;Buzzer_Time(500);}break;
                case 7:if(TimeLock){User=7;if(Sec!=0){LCD_ShowString(2,1,"Illegality:");LCD_ShowNum(2,13,User,1);fault=1;}ET1=0;Buzzer_Time(500);}break;
                case 8:if(TimeLock){User=8;if(Sec!=0){LCD_ShowString(2,1,"Illegality:");LCD_ShowNum(2,13,User,1);fault=1;}ET1=0;Buzzer_Time(500);}break;        
            }
            }    
        }
    }
}
void Timer0_Routine() interrupt 1            //定时器扫描按键
{
    static unsigned int T0Count1,T0Count2;
    TL0 = 0x66;        //设置定时初值
    TH0 = 0xFC;        //设置定时初值
    T0Count1++;
    T0Count2++;
    if(T0Count2>20)
    {
        T0Count2=0;
        Loop_MatrixKey();
    }    

    if(T0Count1>20)
    {
        T0Count1=0;
        Loop_Key();

    }

}
void Timer1_Routine() interrupt 3
{
    static unsigned int T1Count;
    TL1 = 0x66;        
    TH1 = 0xFC;    
    
    if(TimeLock)
    {    
    T1Count++;
    if(T1Count>=1000)        //Sec倒计时,1S
    {
        T1Count=0;
        if(Sec)
            Sec--;
            if(Sec<=3&&Sec>=0)
                Buzzer_Time(500);    
            if(User!=0)
                Buzzer=0;
                
        
    }
    }
}

定时器

include <REGX52.H>


void Timer1Init(void)        //1毫秒@11.0592MHz
{
    TMOD &= 0x0F;        
    TMOD |= 0x10;        //设置定时器模式
    TL1 = 0x66;        
    TH1 = 0xFC;        
    TF1 = 0;        
    TR1 = 1;
    ET1 = 1;       
    PT1 = 1;
    
}
    
    
    
    
#include <REGX52.H>


void Timer0_Init(void)
{
    TMOD &= 0xF0;        //设置定时器模式
    TMOD |= 0x01;        //设置定时器模式
    TL0 = 0x66;        //设置定时初值 1ms
    TH0 = 0xFC;        //设置定时初值
    TF0 = 0;        //清除TF0标志
    TR0 = 1;        //定时器0开始计时
    ET0 = 1;
    EA = 1;
    PT0 = 0;    //优先级标志位
}

LCD1602

#include <REGX52.H>

//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0

//函数定义:
/**
  * @brief  LCD1602延时函数,12MHz调用可延时1ms
  * @param  无
  * @retval 无
  */
void LCD_Delay()
{
    unsigned char i, j;

    i = 2;
    j = 239;
    do
    {
        while (--j);
    } while (--i);
}

/**
  * @brief  LCD1602写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void LCD_WriteCommand(unsigned char Command)
{
    LCD_RS=0;
    LCD_RW=0;
    LCD_DataPort=Command;
    LCD_EN=1;
    LCD_Delay();
    LCD_EN=0;
    LCD_Delay();
}

/**
  * @brief  LCD1602写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void LCD_WriteData(unsigned char Data)
{
    LCD_RS=1;
    LCD_RW=0;
    LCD_DataPort=Data;
    LCD_EN=1;
    LCD_Delay();
    LCD_EN=0;
    LCD_Delay();
}

/**
  * @brief  LCD1602设置光标位置
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @retval 无
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
    if(Line==1)
    {
        LCD_WriteCommand(0x80|(Column-1));
    }
    else if(Line==2)
    {
        LCD_WriteCommand(0x80|(Column-1+0x40));
    }
}

/**
  * @brief  LCD1602初始化函数
  * @param  无
  * @retval 无
  */
void LCD_Init()
{
    LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
    LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
    LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
    LCD_WriteCommand(0x01);//光标复位,清屏
}

/**
  * @brief  在LCD1602指定位置上显示一个字符
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的字符
  * @retval 无
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
    LCD_SetCursor(Line,Column);
    LCD_WriteData(Char);
}

/**
  * @brief  在LCD1602指定位置开始显示所给字符串
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串
  * @retval 无
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
    unsigned char i;
    LCD_SetCursor(Line,Column);
    for(i=0;String[i]!='\0';i++)
    {
        LCD_WriteData(String[i]);
    }
}

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
    unsigned char i;
    int Result=1;
    for(i=0;i<Y;i++)
    {
        Result*=X;
    }
    return Result;
}

/**
  * @brief  在LCD1602指定位置开始显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~65535
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
    unsigned char i;
    LCD_SetCursor(Line,Column);
    for(i=Length;i>0;i--)
    {
        LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
    }
}

/**
  * @brief  在LCD1602指定位置开始以有符号十进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-32768~32767
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
    unsigned char i;
    unsigned int Number1;
    LCD_SetCursor(Line,Column);
    if(Number>=0)
    {
        LCD_WriteData('+');
        Number1=Number;
    }
    else
    {
        LCD_WriteData('-');
        Number1=-Number;
    }
    for(i=Length;i>0;i--)
    {
        LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
    }
}

/**
  * @brief  在LCD1602指定位置开始以十六进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~0xFFFF
  * @param  Length 要显示数字的长度,范围:1~4
  * @retval 无
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
    unsigned char i,SingleNumber;
    LCD_SetCursor(Line,Column);
    for(i=Length;i>0;i--)
    {
        SingleNumber=Number/LCD_Pow(16,i-1)%16;
        if(SingleNumber<10)
        {
            LCD_WriteData(SingleNumber+'0');
        }
        else
        {
            LCD_WriteData(SingleNumber-10+'A');
        }
    }
}

/**
  * @brief  在LCD1602指定位置开始以二进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度,范围:1~16
  * @retval 无
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
    unsigned char i;
    LCD_SetCursor(Line,Column);
    for(i=Length;i>0;i--)
    {
        LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
    }
}

按键文章来源地址https://www.toymoban.com/news/detail-504892.html

#include <REGX52.H>

unsigned char Key_KeyNum,Key_KeyNumber;
unsigned char Key()
{    unsigned char Temp=0;
    Temp=Key_KeyNum;
    Key_KeyNum=0;
    return Temp;    
}

unsigned char KeyNumber()
{    unsigned char KeyNum=0;
    if(P3_1==0){KeyNum=1;}
    if(P3_0==0){KeyNum=2;}
    if(P3_2==0){KeyNum=3;}
    if(P3_3==0){KeyNum=4;}
            return KeyNum;
}

void Loop_Key()
{    static unsigned char LastKey=0,NowKey=0;
    LastKey=NowKey;
    NowKey=KeyNumber();
    if(LastKey)
    {
        if(NowKey==0)
        {
        if(LastKey==1){Key_KeyNum=1;}
        if(LastKey==2){Key_KeyNum=2;}
        if(LastKey==3){Key_KeyNum=3;}
        if(LastKey==4){Key_KeyNum=4;}
        }
        
    }    
}
unsigned char Matrix_Key()
{
    unsigned char Temp;
    Temp=Key_KeyNumber;
    Key_KeyNumber=0;
    return Temp;
}

unsigned char MatrixKey()
{
    unsigned char KeyNumber=0;
            
    P1=0xFF;P1_0=0; 
    if(P1_6==0){KeyNumber=8;}
    if(P1_7==0){KeyNumber=4;}
    
    P1=0xFF;P1_1=0; 
    if(P1_6==0){KeyNumber=7;}
    if(P1_7==0){KeyNumber=3;}
    P1=0xFF;P1_2=0;     
    if(P1_6==0){KeyNumber=6;}
    if(P1_7==0){KeyNumber=2;}
    P1=0xFF;P1_3=0;     
    if(P1_5==0){KeyNumber=9;}
    if(P1_6==0){KeyNumber=5;}
    if(P1_7==0){KeyNumber=1;}
                    return KeyNumber;
}


void Loop_MatrixKey()
{
    static unsigned char LastKey=0,NowKey=0;
    LastKey=NowKey;
    NowKey=MatrixKey();
    if(LastKey==0  && NowKey==1){Key_KeyNumber=1;};
    if(LastKey==0  && NowKey==2){Key_KeyNumber=2;};
    if(LastKey==0  && NowKey==3){Key_KeyNumber=3;};
    if(LastKey==0  && NowKey==4){Key_KeyNumber=4;};
    if(LastKey==0  && NowKey==5){Key_KeyNumber=5;};
    if(LastKey==0  && NowKey==6){Key_KeyNumber=6;};
    if(LastKey==0  && NowKey==7){Key_KeyNumber=7;};
    if(LastKey==0  && NowKey==8){Key_KeyNumber=8;};
    
}

到了这里,关于八路电子抢答器的设计与实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于C语言的单片机八路抢答器课程设计

    1 、系统总体方案设计 本系统由硬件系统和软件系统组成。 硬件系统包括按键控制模块、中央处理AT89C51系统、指示灯显示模块、LED数码管显示模块和扬声器提示模块。 软件系统包括主程序、定时器0中断服务程序、定时器1中断服务程序、延时程序、按键程序和显示程序。 为

    2024年02月04日
    浏览(35)
  • 【单片机项目实训】八路抢答器

    将单片机项目实训——8路抢答器分享出来,如有不足,敬请指出。 【实验图片】  【实验视频】 【项目实训】8路抢答器 目录 一、设计要求 二、方案选择 三、硬件电路设计 五、其他图片 六、资料链接 七、关于作者 八、后记         设计一个共8名选手参加的8路抢答器。

    2024年02月11日
    浏览(29)
  • FPGA实现八位数字抢答器设计

    八位数字抢答器设计要求: 抢答器同时供8名选手或8个代表队比赛,分别用8个按钮S0 ~ S7表示。 设置一个系统清除和抢答控制开关S,该开关由主持人控制。 抢答器具有锁存与显示功能。即选手按动按钮,锁存相应的编号,并在优先抢答选手的编号一直保持到主持人将系统清

    2023年04月15日
    浏览(59)
  • 基于51单片机的抢答器设计

    一、 设计任务 基于单片机的抢答器的设计,实现抢答器的基本功能。 二、 性能指标要求 1. 需要自己设计电路并焊接电路板。 2. 有一个主持人控制开关和6路抢答按扭,当主持人允许抢答时才能进行抢答操作,并用一个数码管显示抢答选手的号码,同时其他选手不能再抢答。

    2024年02月10日
    浏览(26)
  • 带有显示的8路抢答器课程设计

    一: 课程设计目的    抢答器是竞赛问答中一种常用的必备装置智力竞赛时一般分为若干组各组对主持人提出的问题进行抢答。抢答时要判定哪组优先并予以指示和鸣叫。其设计包含了组合逻辑电路和时序逻辑电路的部分原理。。       课程需求 完成电路的初步设计对电

    2023年04月08日
    浏览(28)
  • 【工控老马】PLC六路抢答器系统设计详解

    随着我国经济和文化实业的发展,在很多公开竞争场合要求有公正的竞争裁决,诸如证券、股票交易及各种智力竞赛等,因此出现了抢答器。最初的抢答器是由优先权编码器构成的逻辑电路,其运算速度慢,线路复杂,可靠性不高,功能也比较简单,特别是当抢答路数很多时

    2024年02月06日
    浏览(27)
  • 基于51单片机的四路抢答器设计

    使用51单片机设计一个思路抢答器 正常抢答:主持人按下开始按钮后数码显示管显示最先按下按钮台号,蜂鸣器发出音响,其它抢答按钮无效;主持人按下开始按钮之前,若选手按下抢答器,抢答违规,显示器显示违规台号,违规指示灯亮,蜂鸣器发出音响,其他按钮不起作

    2024年02月08日
    浏览(31)
  • STM32单片机的抢答器设计

    一.硬件方案          以STM32单片机为核心的八路抢答器采用了数字显示器LCD1602,自动锁存显示结果设计思想,它能根据不同的抢答输入信号,经过单片机的控制处理并产生不同的与输入信号相对应的输出信号,最后通过LCD1602显示,即使两组的抢答时间相差几微秒,也可分

    2024年02月11日
    浏览(30)
  • Verilog实现八人抢答器

    抢答器由FPGA中verilog语言编写,一共有六个模块,分别为:daojishi,divscandisplay,fmq2,shuju,qqddqq组成,可实现八人抢答功能,并实现30s倒计时,当倒计时时间为0时无人抢答会使蜂鸣器报警,当有人成功抢答时会显示抢答选手序号并产生报警。qqddqq为顶层文件,级联各个模块 为实

    2024年02月11日
    浏览(51)
  • 基于单片机16路多路抢答器仿真系统设计

    ** 单片机设计介绍,基于单片机16路多路抢答器仿真系统设计   基于单片机16路多路抢答器仿真系统的设计概要主要涵盖硬件设计、软件编程以及功能实现等方面。以下是针对该设计的详细概述: 一、系统概述 该设计旨在开发一个基于单片机的16路多路抢答器仿真系统,能

    2024年04月27日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包