本帖最后由 123456ld 于 2019-11-11 15:09 编辑
基于c51的四路抢答器,本实验通过数码管结合矩阵按键及独立按键组成四路抢答器。对不同选手的判断从而在数码管上显示那位选手抢答成功暂停计时,或哪三位选手犯规触发蜂鸣器报警。其中倒计时的开始由独立按键K1实现,对抢答或倒计时的恢复由独立按键K3实现。程序源码为本人自创,如有不懂,请留言发问。篇幅有限仅提供部分代码。详情请下载后查阅。
该程序适用stc89c51单片机
单片机源程序如下:
- /****************************************************
- * 实验内容
- * 四路抢答器
- **************************************************/
- #include <reg52.h>
- typedef unsigned int u16;
- typedef unsigned char u8;
- /***********************************************
- *
- * 变量及引脚定义声明
- *************************************************/
- sbit AA = P2^2;
- sbit BB = P2^3;
- sbit CC = P2^4;
- sbit k3 = P3^2;
- sbit k4 = P3^3;
- sbit beep = P1^5;
- int i=0; //初始状态控制毫秒的两位数码管为0
- int j=10; //初始状态控制秒的两位数码管为10
- int jishu=0; //以10ms为一个剂量,精准控制毫秒的99-0
- int cishu=0; //消除最后一秒带来的影响
- int xuanshou=0; //选手编号
- int biaozhi=1; //控制抢答开始后只有一个人可以被记录
- int wei1=0 , wei2=0 , wei3=0;
- enum position {zero, one, two, three, four, five, six, seven};
- u16 code duanxuan[16] = { 0x3f,0x06,0x5b,0x4f,
- 0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,
- 0x39,0x5e,0x79,0x71};
- /*****************************************************
- *
- * 子函数申明
- ******************************************************/
- void delay(u16 i); //延时函数
- void jvzhen(); //矩阵键盘选手确定
- void weixuan( u16 i ); //数码管位选
- void timer0(); //定时器初始化
- void xianshi(); //数码管倒计时显示
- void int0(); //中断0倒计时开始
- void int1(); //中断1问题结束恢复数码管
- void panduan(); //答题选手的判断
- void qiangda(); //选手抢答时的判断
-
- /*****************************************************
- * 主函数
- *******************************************************/
- void main()
- {
- int0();
- int1();
- timer0();
- while(1)
- {
- xianshi();
- jvzhen();
- panduan();
- qiangda();
- }
- }
- void qiangda()
- {
- if( j==10&&xuanshou!=0 )
- {
- wei1 = xuanshou;
- while(1)
- {
- xianshi();
- weixuan(7);
- P0 = duanxuan[wei1];
- delay(1);
- P0 = 0x00;
-
- beep=~beep;
- delay(1);
- jvzhen();
- if( xuanshou!=wei1 )
- {
- break;
- }
- if( k4==0 )
- {
- break;
- }
- }
- wei2 = xuanshou;
- while(1)
- {
- xianshi();
-
- weixuan(7);
- P0 = duanxuan[wei2];
- delay(1);
- P0 = 0x00;
-
- weixuan(6);
- P0 = duanxuan[wei1];
- delay(1);
- P0 = 0x00;
-
- beep=~beep;
- delay(1);
- jvzhen();
- if( xuanshou!=wei2 )
- {
- break;
- }
- if( k4==0 )
- {
- break;
- }
- }
- wei3 = xuanshou;
- while(1)
- {
- xianshi();
-
- weixuan(7);
- P0 = duanxuan[wei3];
- delay(1);
- P0 = 0x00;
-
- weixuan(6);
- P0 = duanxuan[wei2];
- delay(1);
- P0 = 0x00;
-
- weixuan(5);
- P0 = duanxuan[wei1];
- delay(1);
- P0 = 0x00;
-
- beep=~beep;
- delay(1);
- jvzhen();
- if( k4==0 )
- {
- break;
- }
- }
- }
- }
- /* 延时 */
- void delay(u16 i)
- {
- u16 a;
- while(i--)
- {
- for(a = 0; a < 100; a++)
- {
- ;
- }
- }
- }
- /* 显示哪位选手按键暂停 */
- void panduan()
- {
- if( i!=0 && xuanshou!=0 )
- {
- switch( xuanshou )
- {
- case 1 : TR0=0; weixuan(7); P0=duanxuan[1]; delay(1); P0 = 0x00; break;
- case 2 : TR0=0; weixuan(7); P0=duanxuan[2]; delay(1); P0 = 0x00; break;
- case 3 : TR0=0; weixuan(7); P0=duanxuan[3]; delay(1); P0 = 0x00; break;
- case 4 : TR0=0; weixuan(7); P0=duanxuan[4]; delay(1); P0 = 0x00; break;
- }
- biaozhi=0;
- }
- }
- /* 矩阵键盘选手确定 */
- void jvzhen()
- {
- P1 = 0x0f;
- if( (P1!=0x0f&&biaozhi==1) )
- {
- delay(5);
- if( (P1!=0x0f) )
- {
- switch( P1 )
- {
- case 0x07 : xuanshou = 1; break;
- case 0x0b : xuanshou = 2; break;
- case 0x0d : xuanshou = 3; break;
- case 0x0e : xuanshou = 4; break;
- }
- P1=0xf0;
- switch( P1 )
- {
- case (0x70) : xuanshou = xuanshou; break;
- }
- }
- }
- }
- /* 数码管位选*/
- void weixuan( u16 i )
- {
- switch(i)
- {
- case (zero): CC = 0; BB = 0; AA = 0; break; //第零位
- case (one): CC = 0; BB = 0; AA = 1; break; //第一位
- case (two): CC = 0; BB = 1; AA = 0; break; //第二位
- case (three): CC = 0; BB = 1; AA = 1; break; //第三位
- case (four): CC = 1; BB = 0; AA = 0; break; //第四位
- case (five): CC = 1; BB = 0; AA = 1; break; //第五位
- case (six): CC = 1; BB = 1; AA = 0; break; //第六位
- case (seven): CC = 1; BB = 1; AA = 1; break; //第七位
- }
- }
- /* 定时器初始化*/
- void timer0()
- {
- TMOD =0x01;
- TH0 = (65536-1000)/256;
- TL0 = (65536-1000)%256; //1ms
- ET0 = 1;
- EA = 1;
- }
- /* 倒计时显示 */
- void xianshi()
- {
- weixuan(0);
- P0 = duanxuan[i%10];
- delay(1);
- P0 = 0x00;
-
- weixuan(1);
- P0 = duanxuan[i/10];
- delay(1);
- P0 = 0x00;
- weixuan(2);
- P0 = 0x40;
- delay(1);
- P0 = 0x00;
-
- weixuan(3);
- P0 = duanxuan[j%10];
- delay(1);
- P0 = 0x00;
-
- weixuan(4);
- P0 = duanxuan[j/10];
- delay(1);
- P0 = 0x00;
- }
- /* 倒计时开始 */
- void int0()
- {
- EA=1;
- IT0=1;
- EX0=1;
- }
- /* 数码管复位 */
- void int1()
- {
- EX1=1;
- IT1=1;
- EA=1;
- }
复制代码
所有资料51hei提供下载:
四路抢答器(倒计时).zip
(35.3 KB, 下载次数: 39)
|