我是靠谱客的博主 瘦瘦铅笔,最近开发中收集的这篇文章主要介绍keil 5与proteus8.9仿真实现四路抢答计分器设计目的二、代码实现仿真图,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 设计目的
  • 代码实现
  • 仿真图


设计目的

设计一个四位抢答器与计分系统。

模拟四位抢答器与计分系统,实现倒计时抢答,选择自己所选选项,统计所得分数等功能。

(1)抢答器同时供四名选手或四个代表队使用,分别用一号,二号,三号,四号四个按钮表示。

(2)设置一个抢答开始控制开关,该开关由主持人控制。开关按下开始倒计时30s,有人抢答后就停止倒计时。

(3)抢答器具有锁存与显示的功能。即按下开始按键后,选手按下抢答按钮,锁存相应的编号,且优先抢答的选手的编号会一直保存至下一次抢答开始。

(4)抢答后选手应该给出自己的答案,并通过A,B,C,D四个按钮选择选项,同时显示器会显示所选答案。

(5)回答问题给出选项后,主持根据正确答案对相应选手进行加分或减分(开始时全部选手以十分为底,答对一题加一分,答错扣一分,最少总分为零分。)若回答正确绿灯亮,回答错误红灯亮。

(6)四个显示器分别显示对应选手的总得分。

二、代码实现

代码如下(示例):

#include "regx52.h"

#include <intrins.h>

sbit DIN=P3^0;// 串行数据输入端

sbit LD=P3^1;// 装载数据信号输入端

sbit CLK=P3^2;// 移位脉冲输入端

sbit begin=P3^6;//开始按钮

sbit led1=P2^4;

sbit led2=P2^5;

unsigned char a=10,b=10,c=10,d=10,e=0;

unsigned char choice=15;//选项,没选时显示为灭

unsigned char second=30;//倒计时时间

unsigned char counter=0;//记录中断次数

unsigned char number=0;

unsigned char people=0;//选手编号

unsigned char num_add[]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};//max7219读写地址,内容。

unsigned char num_dat[]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b};//非译码方式时的共阴数码管显示编码,0-9

unsigned char NixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x40,0x00};//共阴数码管显示编码,0-9,a-d,- 灭

void delay(unsigned int xms)//延时函数

{

       unsigned char i, j;

       while(xms--)

       {

              i = 2;

              j = 239;

              do

              {

                     while (--j);

              } while (--i);

       }

}

unsigned char shuzi()//键盘扫描函数(按列扫描),并返回对应的键值。

{

  unsigned char i;

  unsigned int temp;

  P1=0xfe;

  for(i=4;i>0;i--)

  {

       temp=P1;

       temp=temp&0xf0;

       while(temp!=0xf0)

       {

         switch(temp)

         {

           case 0x70:number=i;

               break;

              case 0xb0:number=i+4;

               break;

              case 0xd0:number=i+8;

               break;

              case 0xe0:number=i+12;

               break;

         }

 while(temp!=0xf0)

         {

           temp=P1;

              temp=temp&0xf0;

         }

        

       }

       temp=P1;

       temp=temp|0xf0;

       temp=_crol_(temp,1);

       P1=temp;

  }

       return number;

}

void Nixie(unsigned char Location,Number)//四位数码管动态显示,Nixie(unsigned char Location,Number),第一个参数显示的位码,第二个为显示的段码

{

       switch(Location)      

       {

              case 4:P2_3=1;P2_2=1;P2_1=1;P2_0=0;break;

              case 3:P2_3=1;P2_2=1;P2_1=0;P2_0=1;break;

              case 2:P2_3=1;P2_2=0;P2_1=1;P2_0=1;break;

              case 1:P2_3=0;P2_2=1;P2_1=1;P2_0=1;break;

       }

       P0=NixieTable[Number];

       delay(1);

  P0=0x00;

                                  

}

void people_display()//选手编号显示,在四位数码管的第一位(最高位)显示选手编号

{Nixie(4,people);

}

void xuanxiang_display()//选手选项显示,在四位数码管的第二位显示选手选项

{Nixie(3,choice);

}

void time_display(unsigned char x)//倒计时时间显示函数

{     unsigned char i,j;

       i=x/10;

       j=x%10;

       Nixie(2,i);

       Nixie(1,j);

}

void max7219_send(unsigned char addr,unsigned char wdata)//向max7219写命令

{

unsigned char temp,i=1,j,k;

LD=0;

while(i<16)

{

       if(i<8) {temp=addr;} //先写入MAX7219内部寄存器地址,再向内部寄存器写入操作数值

       else {temp=wdata;}

       for(j=0;j<8;j++)

       {

       CLK=0;

       if((temp&0x80)==0x80) DIN=1; //先发送数据的最高位

       else DIN=0;

       for(k=5;k>0;k--); //时钟频率高的单片机需曾加延时时间,此处为12MHz

       CLK=1;

       for(k=5;k>0;k--);

       temp<<=1;

       }

       i+=8;

}

LD=1;

}

void max7219_init()//max7219初始化

{

max7219_send(0x0a,0x07); //显示亮度,取值范围0~f

max7219_send(0x0b,0x07);//8位扫描显示,取值范围0x01~0x07

max7219_send(0x09,0x00);//译码方式,0x00为不译码,0xff为译码

max7219_send(0x0c,0x01); //操作方式,0x00为低功耗模式,0x01为正常操作模式

max7219_send(0x0f,0x00); //显示状态,0x00为正常显示,0x01为显示测试

}void timer_init()//定时器T0初始化

{     EA=1;//总中断允许

       ET0=1;//允许定时器T0中断

       TMOD=0x01;//定时器T0方式1定时

       TH0=0xd8;//设置10毫秒中断一次

       TL0=0xf0;//0xd8f0=55536,65536-55536=10000us=10ms

}

void timer0() interrupt 1//定时器T0中断函数,进行100次中断,即用时1s

{

       if(counter<100)

       {

              counter++;

       }

  else

       {

              counter=0;

              second=second-1;

              if(second==0){second=30;}

       }

       TH0=0xd8;//重新装初值

       TL0=0xef;

       TR0=1;//启动定时器0

}

void grade_display()//全部选手得分显示

{unsigned char i,j,k,l,m,n,o,p;

       i=a/10;

       j=a%10;

       k=b/10;

       l=b%10;

       m=c/10;

       n=c%10;

       o=d/10;

       p=d%10;

       max7219_send(num_add[1],num_dat[j]);

       max7219_send(num_add[0],num_dat[i]);

       max7219_send(num_add[3],num_dat[l]);

       max7219_send(num_add[2],num_dat[k]);

       max7219_send(num_add[5],num_dat[n]);

       max7219_send(num_add[4],num_dat[m]);

       max7219_send(num_add[7],num_dat[p]);

       max7219_send(num_add[6],num_dat[o]);

}

void holderscan()//倒计时和选手编号初始化设置,时间设置30s,选手编号设置为0.并对编号,得分,倒计时进行显示

{     max7219_init();grade_display();people=0;second=30;

       time_display(second);people_display();

}

void main()

{     while(1)

       {

              do{holderscan();

              }while(begin);//一直进行倒计时和选手编号初始化设置,直到按下开始按钮

              while(~begin);//按键消抖

              timer_init();//定时器T0初始化,10ms产生一次中断

              TR0=1;//开启定时器计数

              do{time_display(second);

                     if(shuzi()<=4){people=number;}

                     else{people=0;}

                     people_display();

              }while((!people));//一直进行键盘扫描,直到按下键值小于等于4时,people不为零且为键值,跳出循环。

             

              TR0=0;//关闭定时器计数

             

       do{time_display(second);people_display();shuzi();

       if(number<=8&&number>=5) {choice=number+5;}

       else {choice=15;}

       xuanxiang_display();}while(choice==15);//一直进行键盘扫描,直到按下键值小于等于8,且大于等于5时,choice不为15且为键值+5,跳出循环。

       do{time_display(second);people_display();xuanxiang_display();shuzi();

       if(number==people+8||number==people+12) {e=number;}

       else {e=0;}

       switch(e)//进行选择,若e=9,对a加一,绿灯亮1.5秒;若e=13,对a减一,红灯亮1.5秒;......

                     { case(9):a++;led2=0;delay(1500);led2=1;break;

                            case(10):b++;led2=0;delay(1500);led2=1;break;

                            case(11):c++;led2=0;delay(1500);led2=1;break;

                            case(12):d++;led2=0;delay(1500);led2=1;break;

                            case(13):a--;if(a==-1){a=0;}led1=0;delay(1500);led1=1;break;

                            case(14):b--;if(b==-1){b=0;}led1=0;delay(1500);led1=1;break;

                            case(15):c--;if(c==-1){c=0;}led1=0;delay(1500);led1=1;break;

                            case(16):d--;if(d==-1){d=0;}led1=0;delay(1500);led1=1;break;

                     }    

                    

              }while(e==0);//一直进行键盘扫描,直到按下键值等于people+8或等于people+12时,e不为0且为键值,跳出循环。

       }

}


仿真图

 

 

 

 

 

最后

以上就是瘦瘦铅笔为你收集整理的keil 5与proteus8.9仿真实现四路抢答计分器设计目的二、代码实现仿真图的全部内容,希望文章能够帮你解决keil 5与proteus8.9仿真实现四路抢答计分器设计目的二、代码实现仿真图所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部