找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1607|回复: 5
打印 上一主题 下一主题
收起左侧

8位抢答器,现在只有共阴的代码,但数码管是共阳的,需要换哪,我换半天都不对

[复制链接]
跳转到指定楼层
楼主
ID:339804 发表于 2019-11-29 14:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "reg51.h"        
#include "intrins.h"      
#define uchar unsigned char
#define uint unsigned int  
bit OK;                //开始抢答标志位,响铃标志位
sbit speak=P3^7;            //声音输出口
sbit start=P3^0;            //开始
sbit end=P3^1;                //终止
sbit add=P3^4;                //+
sbit sub=P3^5;                //-
//其中抢答设置时间,以及回答设置时间,采用的是单片机中断口p3.2以及p3.3,故不用定义
sbit S1=P2^1;//第一个数码管
sbit S2=P2^3;//第二个数码管
sbit S3=P2^5;//第三个数码管
sbit S4=P2^7;//第四个数码管
uchar Q_T=20,H_T=30,qt,ht;        //初始抢答时间,回答时间
uchar a=11,b=11,c=11,d=11,n,m=0,k;                //数码管显示选手编号与计数值,计时器中断次数,犯规选手号
/*****************************************************************************/
uchar code dis_7[]={0x3F,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};
/* 共阴七段LED段码表  "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9" "不亮" "-"*/               
/********1毫秒延时子函数**********/
void delay1ms(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<120;j++)
;
}
/*******************************响铃标志子程序********************************/
void nose()
{speak=0;
delay1ms(500);
speak=1;
}
/********************************显示子程序**********************************/
void display()
{
P0=dis_7[a];          //第一个数码管显示
S1=0;              //打开第一个数码管显示
delay1ms(5);          //稍作延时
S1=1;              //关闭数码管显示
P0=dis_7[11];
S2=0;
delay1ms(5);
S2=1;
P0=dis_7[b];
S3=0;
delay1ms(5);
S3=1;
P0=dis_7[c];
S4=0;
delay1ms(5);
S4=1;
}
/************************************非法抢答*********************************/
void false()
{
if(P1!=0xff)      //如果p1口不等于ff,则执行一下程序,否则跳过
{
if(P1==0xf7)    //1号选手违规按下
{m=1;}              //赋值1,送显示
if(P1==0xfb)      //2号选手违规按下
{m=2;}              //赋值2,送显示
if(P1==0xfd)      //3号选手违规按下
{m=3;}              //赋值3,送显示
if(P1==0xfe)      //4号选手违规按下
{m=4;}              //赋值4,送显示
if(P1==0xef)      //5号选手违规按下
{m=5;}              //赋值5,送显示
if(P1==0xdf)      //6号选手违规按下
{m=6;}              //赋值6,送显示
if(P1==0xbf)      //7号选手违规按下
{m=7;}              //赋值7,送显示
if(P1==0x7f)      //8号选手违规按下
{m=8;}              //赋值8,送显示
n=0;              //计数器中断次数清零
while(end==1)      //停止按键未按下,循环以下
{ if(n<6)          //若计数器中断次数小于6,则执行以下
{a=10;b=10;c=10;//a,b,c均赋值10,不显示
display();      //延时
speak=1;}          //蜂鸣器关闭
if(n>=6)          //若计数器中断次数大于等于6,则执行以下程序
{a=m;b=11;c=11; //a赋值违规选手号数,b,c赋值11,显示数码管中间一横
display();      //延时
speak=0;
}          //开启蜂鸣器
if(n==20)      //若计数器中断次数等于20,则执行以下程序
{n=0;}          //清零
}
speak=1;m=0;      //关闭蜂鸣器;违规抢答位清零
a=10;b=10;c=10;  //a,b,c均赋值10
}
}
main()
{TMOD=0x11;
TH0=0x3c;
TL0=0xb0;
EA=1;
ET0=1;
EX0=1;
EX1=1;
OK=0;
speak=1;
TR0=1;
while(1)      //无尽循环
{display();  //显示程序
while(start==1)  //开始未按下,循环以下程序
{false();          //违规子程序
display();      //显示子程序
if(start==0)      //若开始按键按下,则执行以下程序
{delay1ms(2);      //稍作延时,防止抖动
while(start==0);    //若开始按键按下,则执行以下程序
nose(); //响铃子程序
OK=1;  //开始抢答标志位
TR0=0;
qt=Q_T; //抢答时间赋初值
n=0;      //计数器中断次数清零
while(qt>0&&end==1&&OK==1&&P1==0xff) //抢答时间大于0且停止按键未按下且开始抢答标志为1且未有选手按键按下则执行以下程序
{TR0=1;
a=10;        //a赋值10
b=qt/10;    //b赋值抢答时间十位
c=qt%10;    //c赋值抢答时间个位
display();    //调用显示
speak=1;
if(n>20)    //若计数器中断大于20,则执行以下程序
{n=0;        //n清零
qt--;        //抢答时间减1
}
if(qt<=5)    //如果抢答时间小于等于5,则执行以下程序
{if(n<7)    //如果n小于7,则执行以下程序
{speak=1;
}
if(n>7)
{speak=0;}
}
}
if(qt==0)    //如果抢答时间等于0
{a=10;b=10;c=10;d=10;OK=0;speak=1;m=0;n=0;
}            //则a,b,c,d均置10;抢答标志,响铃关闭,选手号,计数器中断数均清零
if(end==0)    //如果主持人按下终止按键
{a=10;b=10;c=10;d=10;OK=0;speak=1;m=0;n=0;
}            //则a,b,c,d均置10;抢答标志,响铃关闭,选手号,计数器中断数均清零
if(P1!=0xff)    //如果有选手按下按钮,则执行以下程序
{k=P1;         //p1口数值赋给k
nose();        //响铃子程序
if(k==0xf7)    //比较k的值
{m=1;}            //赋对应选手号给m
if(k==0xfb)    //跟以上一样,以下以此类推
{m=2;}
if(k==0xfd)
{m=3;}
if(k==0xfe)
{m=4;}
if(k==0xef)
{m=5;}
if(k==0xdf)
{m=6;}
if(k==0xbf)
{m=7;}
if(k==0x7f)
{m=8;}   
n=0;            //n清零
ht=H_T;        //回答时间赋初值
while(end==1&&ht>0)  //当终止未按下且回答时间大于0,则循环以下程序
{TR0=1;               //打开计时器
a=m;              //a赋值选手号
b=ht/10;          //b赋值回答时间十位
c=ht%10;          //c赋值回答时间个位
display();          //调用显示子程序
speak=1;
if(n==20)          //如果计时器中断次数等于20,则执行以下程序
{n=0;              //清零
ht--;              //回答时间减1
}
if(ht<=5)          //如果回答时间小于等于5,则执行以下程序
{if(n<7)         
{speak=1;
}
if(n>7)
{speak=0;
}
}
}
}
{a=10;b=10;c=10;d=10;OK=0;speak=1;m=0;n=0;
}    //清零
}
}
}
}
/**********************************定时0中断**********************************/
void time_intt0(void) interrupt 1
{TH0=0x3c;TL0=0xb0;      //赋初值
n++;
}
/*****************************************************************************/
/********************************外中断0**************************************/
void time_intt2(void) interrupt 0    //采用中断设置时间
{while(end==1)            //终止未按下,循环以下
{if(add==0)            //如果+键按下,执行以下程序
{delay1ms(2);        //稍作延时,防止抖动
while(add==0);        //当+键等于0,则循环
if(Q_T>=99)            //如果抢答时间大于等于99
{Q_T=0;            //则抢答时间清零
}
else                //否则
{Q_T++;            //抢答时间加1
}
}
if(sub==0)            //如果-键按下,执行以下程序
{delay1ms(2);        //稍作延时,防止抖动
while(sub==0);        //当-键等于零,则循环
if(Q_T<=0)            //如果抢答时间小于等于0
{Q_T=99;            //则抢答时间等于99
}
else                //否则
{Q_T--;            //抢答时间减1
}
}
a=10;b=Q_T/10;c=Q_T%10;display();    //a赋值10,b赋值抢答时间十位,c赋值抢答时间个位,调用显示子程序
}
a=10;b=10;c=10;display();    //a,b,c均赋值10,调用显示子程序
}
/*****************************************************************************/
/************************************外中断1**********************************/
void time_intt3(void) interrupt 2      //采用中断设置时间
{while(end==1)                          //解释与上一个中断一样
{if(add==0)
{delay1ms(2);
while(add==0);
if(H_T>=99)                //回答时间
{H_T=0;
}
else
{H_T++;
}
}
if(sub==0)
{delay1ms(2);
while(sub==0);
if(H_T<=0)
{H_T=99;              //回答时间
}
else
{H_T--;
}
}
a=10;b=H_T/10;c=H_T%10;display();        //b,c赋值的是回答时间
}
a=10;b=10;c=10;display();
}
/*************************************************************************/

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:275826 发表于 2019-11-29 19:38 | 只看该作者
对在显示子程序里的每个P0=~dis_7[a];都取反就OK了
回复

使用道具 举报

板凳
ID:235200 发表于 2019-11-29 20:11 | 只看该作者
换共阳数码管的同时,其位控制电路也需改变,如果电路没有问题的情况下,只需把显示程序P0=dis_7[a];改成P0=~dis_7[a];后面的S1至S4相应值0改为1,1改为0即可
回复

使用道具 举报

地板
ID:413383 发表于 2019-11-29 22:52 | 只看该作者
共阳共阴这个跟段码有关,当然还要看实际电路连接
回复

使用道具 举报

5#
ID:652301 发表于 2019-11-30 21:35 | 只看该作者
tyrl800 发表于 2019-11-29 19:38
对在显示子程序里的每个P0=~dis_7[a];都取反就OK了

能帮忙看看我的程序吗。。
回复

使用道具 举报

6#
ID:524818 发表于 2019-12-1 08:40 | 只看该作者
数组值取反
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表