四位竞赛抢答器系统设计
1、设计一个四位竞赛抢答单片机系统,可同时供 4 名选手或 4 个代表队参加比赛,
每队设置单独的抢答按钮,编号为 1、2、3、4;
2、给节目主持人设置一个“抢答开始”控制开关,用来控制抢答开始;
3、给节目主持人设置一个“系统清除”控制开关,用来控制系统清零;
4、抢答器具有编号锁存、抢答计分、时间显示和声响提示等功能。
1)主持人按下“抢答开始”后,系统以减计时方式,显示抢答剩余时间。
2)如果抢答时间计时结束,却没有选手抢答时,本次抢答无效,系统报警提示(显
示单音,持续 2 秒);
3)抢答时间内,若有选手按动对应的抢答按钮,此对编号立即锁存,数码管上显
示出队伍编号和此队累计分数,同时系统给出音响提示(显示单音,持续 2 秒)。
4)在主持人启动“抢答开始”键前,选手提前抢答,抢答无效,系统报警提示(显
示单音,持续 2 秒)。
5、抢答成功后,禁止其他选手抢答,优先抢答选手的编号一直保持到主持人将系
统清零为止;
6、抢答器具有利用旋钮调整抢答时间功能,时间范围 20 秒~50 秒。
我们需要硬件操作,仿真图中的显示是根据我们用的试验箱调整的,另外我加了正误判断。其中还是有一些小的问题要改的。(懒不想改了)
需要其他功能可以自己看着改。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
仿真图
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define u8 unsigned char
- #define u16 unsigned int
- #define LED_xianshi P0 //数码管显示端口
- #define LED_wei P2 //位选
- #define KEY_COL P3 //P3口计时信号输ru
- sbit start=P1^5; //P1^5 开始抢答
- sbit clear=P1^4; //清零信号
- sbit man1=P1^0; //4人抢答口
- sbit man2=P1^1;
- sbit man3=P1^2;
- sbit man4=P1^3;
- sbit s1=P3^0;//对错判断
- sbit s2=P3^1;
- sbit k1=P2^0;//位选
- sbit k2=P2^1;
- sbit k3=P2^2;
- sbit k4=P2^3;
- char dc=0;
- int man=0;
- int score[4]={0,0,0,0}; //分数存储开始为0
- int cont=0;
- int state=0; //状态
- int sec0=20; //起始值
- int sec=20; //调节后的值
- char ji=0;
- char si=0;
- sbit warningLED =P1^7; //蜂鸣器声响控制
- char biaozhi=0;
- //u8 code seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};
- u8 code seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x11,0xbf};
- unsigned int T0RH,T0RL,T1RH,T1RL;
- u8 duan[]={0x5f,0x5f,0x5f,0x40};
- u8 ad0;
- u8 KEY_up_flag=1;
- u8 KEY_use=0;
- char code dx516[3] _at_ 0x003b;
- u8 flag500ms=0; //设置标志位
- u8 startflag=0;
- u8 warning=0;
- unsigned char GetADCValue(unsigned char chn); //函数申明调用
- extern void I2CStart();
- extern void I2CStop();
- extern unsigned char I2CReadNAK();
- extern bit I2CWrite(unsigned char dat);
- unsigned char KEYscan(); //键盘扫描
- void reset_init();
- void KEYexe(u8 val);
- void Duanmove(u8 Movedir);
- void shanshuo();
- int scanduicuo();
- void delay2s()
- {
- TMOD=0x11;
- TH1=0x3c;
- TL1=0xb0;
- ET1=1;
- TR1=1;
- EA=1;
- }
- void delay(u16 t)
- {
- while(t--);
- }
- void chushihua()
- {
- TMOD=0x11;
- TH0=0x3c;
- TL0=0xb0;
- EA=1;
- ET0=1;
- TR0=1;
- }
- void display()
- {
- k4=0;
- LED_xianshi=duan[0];
- delay(255);
- k4=1;
- LED_xianshi=0x00;
-
- k3=0;
- LED_xianshi=duan[1];
- delay(255);
- k3=1;
- LED_xianshi=0x00;
-
- k2=0;
- LED_xianshi=duan[2];
- delay(255);
- k2=1;
- LED_xianshi=0x00;
-
- k1=0;
- LED_xianshi=duan[3];
- delay(255);
- k1=1;
- LED_xianshi=0x00;
- }
- void main()
- {
-
- chushihua();
-
- warningLED=0;
-
- while(1)
- {
- k4=0;
- LED_xianshi=duan[0];
- delay(255);
- k4=1;
- LED_xianshi=0x00;
-
- k3=0;
- LED_xianshi=duan[1];
- delay(255);
- k3=1;
- LED_xianshi=0x00;
-
- k2=0;
- LED_xianshi=duan[2];
- delay(255);
- k2=1;
- LED_xianshi=0x00;
-
- k1=0;
- LED_xianshi=duan[3];
- delay(255);
- k1=1;
- LED_xianshi=0x00;
-
-
- KEYscan(); //判断是那个人按下
- if(state==0) //在未开始时能进行的操作
- {
- ad0=GetADCValue(0); //在未开始时可以设置倒计时初值;
- sec0=ad0*30/255+20;
-
- duan[3]=0xbf;
- duan[2]=0xbf;
- duan[1]=seg[sec0/10];
- duan[0]=seg[sec0%10];
-
- delay(255);
-
- if(man!=0)
- {
- man=0;
- warning=1;
- }
-
- if(start==0)
- {
- reset_init();//按下开始后倒计时 state标志位置1
- state=1;
- }
- }
-
- if(state==1) //处于开始的状态时
- {
-
- if(man!=0)
- {
- dc=0;
- while(!dc)
- {
- scanduicuo();
-
- k4=0;
- LED_xianshi=seg[man];
- delay(255);
- k4=1;
- LED_xianshi=0x00;
-
- k3=0;
- LED_xianshi=0xbf;
- delay(255);
- k3=1;
- LED_xianshi=0x00;
-
- k2=0;
- LED_xianshi=0xbf;
- delay(255);
- k2=1;
- LED_xianshi=0x00;
-
- k1=0;
- LED_xianshi=0xbf;
- delay(255);
- k1=1;
- LED_xianshi=0x00;
-
- if(clear==0)
- {
- state=2;
- break;
- }
- }
- score[man-1]=score[man-1]+cont; //抢到后判断对错。对了加一分,错了不加分
- duan[3]=seg[man];
- duan[2]=seg[17];
- duan[1]=seg[score[man-1]/10%10];
- duan[0]=seg[score[man-1]%10];
-
- display();
-
- state=2;
- warning=1;
- }
- else
- {
- if(flag500ms)
- {
- flag500ms=0;
- sec--;
- duan[3]=0xff;
- duan[2]=0xff;
- duan[1]=seg[sec/10%10];
- duan[0]=seg[sec%10];
- if(sec==0)
- {
- warning=1;
- state=2;
- }
- }
- }
- }
- else if(state==2)
- {
- if(start==1)
- {
- man=0x0000;
- delay(255);
- state=0;
- }
- }
- if(clear==0)
- {
- state=0;
- score[3]=0;
- score[2]=0;
- score[1]=0;
- score[0]=0;
- duan[3] = seg[17];
- duan[2] = seg[17];
- duan[1] = seg[17];
- duan[0] = seg[17];
-
- display();
-
- warningLED=0;
- delay(1000);
- while(!clear) //直到清零状态结束
- {
- display();
- }
- }
- if(warning)
- {
- warning=0x0000;
- shanshuo();
- }
- }
- }
- unsigned char GetADCValue(unsigned char chn)
- {
- unsigned char val;
- I2CStart();
- if(!I2CWrite(0x48<<1))
- {
- I2CStop();
- return 0;
- }
- I2CWrite(0x40 | chn);
- I2CStart();
- I2CWrite(0x48<<1 | 0x01);
- val = I2CReadNAK();
- I2CStop();
- return val;
- }
- unsigned char KEYscan()
- {
- if(man1==0)
- {
- delay(1000);
- if(man1==0)
- {
- man=1;
- }
- }
- if(man2==0)
- {
- delay(1000);
- if(man2==0)
- {
- man=2;
- }
- }
- if(man3==0)
- {
- delay(1000);
- if(man3==0)
- {
- man=3;
- }
- }
- if(man4==0)
- {
- delay(1000);
- if(man4==0)
- {
- man=4;
- }
- } //扫描谁按下的
- if(start==1)
- {
- state=0;
- }
- if(start==0)
- {
- state==1;
- }
- if(clear==0)
- {
- state==2;
- }
- }
- void reset_init()
- {
- sec=sec0;
- duan[3] = 0;
- duan[2] = 0;
- duan[1] = seg[sec/10%10];
- duan[0] = seg[sec%10];
-
- man=0;
- flag500ms=0;
- TH0=0x3c;
- TL0=0xb0;
- }
- void shanshuo()
- {
- warningLED=1;
- delay2s();
- while(warningLED)
- {
- display();
- }
- if(warningLED==0 || si==0)
- {
- TR1=0;
- ET1=0;
- }
- }
- //定时
- void time() interrupt 1
- {
- TH0=0x3c;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
设计1.1.zip
(165.13 KB, 下载次数: 75)
|