基本功能:1.8路抢答器
2.抢答成功和抢答失败(别人抢答后再抢答认定为失败)有不同的蜂鸣器提示
3.抢答成功对应的指示灯会亮起来,数码管显示对应的抢答人序号
4.主持人可以按下按键开始下一轮抢答
基本思路:当选手按下抢答器的时候,对应的单片机端口感受到电平的变化,这时候让灯亮,蜂鸣器响,所以这个时候我们在外面写一个灯函数,蜂鸣器抢答成功失败2个函数。这里我们要注意拿一个变量作为锁资源(当自己抢答后别人再抢答是不能抢答成功的),我这里用了bn_num变量名字。同时为了让蜂鸣器有不同声效,我们可以在自己写一个delay延时函数。注意蜂鸣器是不能通过单片机IO口输出的电流来驱动,所以我们要用一个三极管来放大电流
这里是仿真图:
详细的看一下代码:
#include <REGX52.H>
sbit N_one = P2^0; //1号选手
sbit N_two = P2^1; //2号选手
sbit N_three = P2^2; //3号选手
sbit N_four = P2^3; //4号选手
sbit N_five = P2^4; //5号选手
sbit N_six = P2^5; //6号选手
sbit N_seven = P2^6; //7号选手
sbit N_eight = P2^7; //7号选手
sbit N_cp = P1^2; //主持人号选手
sbit led = P1^0; //灯
sbit beep=P1^1; //定义蜂鸣器引脚
typedef unsigned int u16;
unsigned char bn_num;
unsigned char code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f};//共阴极数码管对应的数组
void delay(){ //延时函数,我自己测试这个循环是我自己想要达到的效果,实际自己可以调整参数等
int i, j;
volatile int k; // 使用volatile关键字,防止编译器优化
for(i=0; i<100; i++)
for(j=0; j<100; j++)
k = j; // 添加一个看似无用的操作
}
void LED(){ //让灯亮一会再关闭
led=0; //灯端口置0,开灯的意思
delay();
led=1;//灯端口置1,关灯的意思
}
void BEEPs(){ //抢答成功让蜂鸣器响一会再关闭
beep=0;
delay();
beep=1;
}
void BEEPf(){ //抢答失败让蜂鸣器响3次
int count=0;
while(count<=2){
beep=0;
delay();
beep=1;
delay();
count++;
}
}
void main()
{
while(1){
if(N_one==0){ //如果检测到1号选手按下开关,这个时候端口检测到低电平,这个函数代表选手按下按钮
if(bn_num==0){ //bn_num我说的锁,如果它等于0,代表没有人抢答过
bn_num=1;
P0=tab[bn_num]; //数码管为1
LED(); //开灯
BEEPs(); //蜂鸣器响
}
else if(bn_num!=0){ //判断是不是已经有人抢答过了,如果是bu_num是不为0
BEEPf();//蜂鸣器响3下
}
while(N_one==0);//检测按键是否松开
}
if(N_two==0){ //2号选手
if(bn_num==0){
bn_num=2;
P0=tab[bn_num];
LED();
BEEPs();
}
else if(bn_num!=0){
BEEPf();
}
while(N_two==0);
}
if(N_three==0){ //3号选手
if(bn_num==0){
bn_num=3;
P0=tab[bn_num];
LED();
BEEPs();
}
else if(bn_num!=0){
BEEPf();
}
while(N_three==0);
}
if(N_four==0){
if(bn_num==0){
bn_num=4;
P0=tab[bn_num];
LED();
BEEPs();
}
else if(bn_num!=0){
BEEPf();
}
while(N_four==0);
}
if(N_five==0){
if(bn_num==0){
bn_num=5;
P0=tab[bn_num];
LED();
BEEPs();
}
else if(bn_num!=0){
BEEPf();
}
while(N_five==0);
}
if(N_six==0){
if(bn_num==0){
bn_num=6;
P0=tab[bn_num];
LED();
BEEPs();
}
else if(bn_num!=0){
BEEPf();
}
while(N_six==0);
}
if(N_seven==0){
if(bn_num==0){
bn_num=7;
P0=tab[bn_num];
LED();
BEEPs();
}
else if(bn_num!=0){
BEEPf();
}
while(N_seven==0);
}
if(N_eight==0){
if(bn_num==0){
bn_num=8;
P0=tab[bn_num];
LED();
BEEPs();
}
else if(bn_num!=0){
BEEPf();
}
while(N_eight==0);
}
if(N_cp==0){ //主持人按键,主持人按下,代表这一轮抢答重新开始
bn_num=0;//归还锁资源
P0=tab[bn_num];
while(N_cp==0);
}
}
}
特别需要主义的是,因为delay是软件延时,可能在Proteus仿真中会出现问题(delay函数延时太多导致仿真会卡死),所以建议用实物一点一点测试,实物的delay仿真仿真不出来。
同时,我想让三者(灯,蜂鸣器,数码管)达到同一时间响应,我把beeps放在最后,让数码管,灯先工作(他们占用cpu时间比较短),这样就可以差不多达到三者同时工作,如果把beeps函数放在最前面,可以看到按下后一小段时间,数码管才亮。
实物图:
(新人第一次写博客,希望支持!!)