八路抢答器
//八路抢答器说明:P2.7口为显示个位数码管的位选线;P2.6口为显示十位数码管的位选线 ;抢答或倒计时结束后按复位键进行下一次抢答.
#include <STCREG.H>
#define uchar unsigned char //宏定义
#define uint unsigned int
uchar code table[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e}; //共阳数码管段码表
sbit beep = P3^4; //蜂鸣器控制位
sbit XSBHW = P3^5; //选手编号位1
sbit XSBHW2 = P3^2; //选手编号位2
sbit DJSBW = P3^3; //倒计时百位
sbit DJSSW = P3^6; //倒计时十位
sbit DJSGW = P3^7; //倒计时个位
uchar num, t1, shu, shu2, temp, bai, shi, ge; //声明变量
uint i;
//延时子程序
void delay(uint z)
{
uint x, y;
for(x = 0; x < z; x++)
for(y = 0; y < 123; y++);
}
//初始化子程序
void init()
{
P0 = 0xff; //消隐
P2 = 0xff;
P1 = 0x0f; //保证抢答前P1口全为高电平(单片机检测低电平认为抢答)
P3 = 0xff;
temp = P1;
TMOD = 0x01; //选择定时器0为工作方式
TH0 = (65536 - 50000) / 256; //定时器装初值
TL0 = (65536 - 50000) % 256;
EA = 1; //开总中断
ET0 = 1; //开定时器0
TR0 = 1; //启动定时器0
num = 200; //倒计时数为200
}
void display() //抢答倒计时显示子函数
{
bai = num / 100;
shi = num / 10 % 10;
ge = num % 10;
P0 = table[bai]; //显示bai位,送段码
XSBHW = 1;
XSBHW2 = 1;
DJSBW = 0; //送位码
DJSSW = 1;
DJSGW = 1;
delay(20); //延时
P0 = table[shi]; //显示shi位,送段码
XSBHW = 1;
XSBHW2 = 1;
DJSBW = 1; //送位码
DJSSW = 0;
DJSGW = 1;
delay(20);
P0 = table[ge]; //显示个位,送段码
XSBHW = 1;
XSBHW2 = 1; //送位码
DJSBW = 1;
DJSSW = 1;
DJSGW = 0;
delay(20); //延时
XSBHW = 1;
XSBHW2 = 1; //送位码
DJSBW = 1;
DJSSW = 1;
DJSGW = 1;
}
//主程序
void main()
{
init(); //调初始化
//大循环
while(1)
{
//倒计时显示程序
P1 = 0x0f;
while(temp == 0x0f)
{
display(); //抢答倒计时显示函数
temp = P1; //判断之前,先把P1口的数据送给temp;
while(temp != 0x0f) //判断
break;
}
//独立键盘扫描程序
while(temp != 0x0f) //有键按下
{
delay(5); //软件延时消抖
temp = P1; //重读按键
while(temp != 0x0f) //再次确认有键按下
{
P1 = 0xef;
temp = P1;
temp = temp & 0x0f;
if(temp != 0x0f)
{
switch(temp) //判断哪个键按下
{
case 0x0e : shu = 0 ,shu2 = 1; //1号选手抢答成功
P3 = 0xfe;
break;
case 0x0d : shu = 0 ,shu2 = 2; //2号选手抢答成功
P3 = 0xfd;
break;
case 0x0b : shu = 0 ,shu2 = 3; //3号选手抢答成功
P3 = 0xfb;
break;
case 0x07 : shu = 0 ,shu2 = 4; //4号选手抢答成功
P3 = 0xf7;
break;
}
}
else
{
P1 = 0xdf;
temp = P1;
temp = temp & 0x0f;
if(temp != 0x0f)
{
switch(temp) //判断哪个键按下
{
case 0x0e : shu = 0 ,shu2 = 5; //5号选手抢答成功
P3 = 0xef;
break;
case 0x0d : shu = 0 ,shu2 = 6; //6号选手抢答成功
P3 = 0xdf;
break;
case 0x0b : shu = 0 ,shu2 = 7; //7号选手抢答成功
P3 = 0xbf;
break;
case 0x07 : shu = 0 ,shu2 = 8; //8号选手抢答成功
P3 = 0x7f;
break;
}
}
else
{
P1 = 0xbf;
temp = P1;
temp = temp & 0x0f;
if(temp != 0x0f)
{
switch(temp) //判断哪个键按下
{
case 0x0e : shu = 0 ,shu2 = 9; //9号选手抢答成功
P3 = 0xef;
break;
case 0x0d : shu = 1 ,shu2 = 0; //10号选手抢答成功
P3 = 0xdf;
break;
case 0x0b : shu = 1 , shu2 = 1; //11号选手抢答成功
P3 = 0xbf;
break;
case 0x07 : shu = 1 , shu2 = 2; //12号选手抢答成功
P3 = 0x7f;
break;
}
}
else
{
P1 = 0x7f;
temp = P1;
temp = temp & 0x0f;
if(temp != 0x0f)
{
switch(temp) //判断哪个键按下
{
case 0x0e : shu = 1 ,shu2 = 3; //13号选手抢答成功
P3 = 0xef;
break;
case 0x0d : shu = 1 ,shu2 = 4; //14号选手抢答成功
P3 = 0xdf;
break;
case 0x0b : shu = 1 ,shu2 = 5; //15号选手抢答成功
P3 = 0xbf;
break;
case 0x07 : shu = 1 ,shu2 = 6; //16号选手抢答成功
P3 = 0x7f;
break;
}
}
}
}
}
P0 = table[shu]; //显示所按下的键,送段码
XSBHW = 0; //送位码
XSBHW2 = 1;
DJSBW = 1;
DJSSW = 1;
DJSGW = 1;
delay(20);
P0 = table[shu2];
XSBHW = 1;
XSBHW2 = 0;
DJSBW = 1;
DJSSW = 1;
DJSGW = 1;
beep = 0; //开蜂鸣器
delay(500); //有键按下时蜂鸣器响500ms
beep = 1; //关闭蜂鸣器
while(1) //进入死循环,将所按下的键显示并定格,防止有键再按下时将其覆盖;
{
EA = 0;
P0 = table[shu]; //显示所按下的键,送段码
XSBHW = 0; //送位码
XSBHW2 = 1;
DJSBW = 1;
DJSSW = 1;
DJSGW = 1;
delay(20); //延时
P0 = table[shu2];
XSBHW = 1;
XSBHW2 = 0;
DJSBW = 1;
DJSSW = 1;
DJSGW = 1;
delay(20);
display(); //抢答倒计时显示函数
}
}
}
}
}
//定时器T0中断子函数
void timer0() interrupt 1
{
TH0 = (65536 - 20000) / 256; //重赋初值,定时时间为20ms
TL0 = (65536 - 20000) % 256;
t1++;
if(t1 == 50) //20ms*50=1s,1秒到
{
t1 = 0; //定时计数清0
num--; //30秒倒计时
if(num == 0)
{
TR0 = 0; //关断定时器0
beep = 0; //开蜂鸣器
while(1) //进入死循环防止超时抢答
{
for(i = 0; i < 600; i++)//循环调用显示延时,同时刷新显示
{
display(); //抢答倒计时显示函数
}
beep = 1; //关断蜂鸣器
}
}
}
}
相关阅读
近些天感觉学习硬件还是得从学习单片机开始,所以开始整理和单片机相关的资料,希望能帮到大家。博客:http://blog.csdn.net/jzj1993/a
1、串行通信的的基本知识 在实际的工业生产,或者生活中,计算机的CPU要与外部的设备之间进行信息的交流,数据的交换,所有的这些信息交
这个8*8按键程序
*在学习51之前,最先接接触到的是Arduino,这个东西上手确实十分的简单,可以做出来一些小玩意,但是它的性能终究是不够强大,对于一些比较
在做完流水灯后就可以尝试做一个结合数码管和按键结合的简单加法器我所用的是sct89c51单片机此单片机有3个数码管,可以通过2个key