1.设计任务
利用AT89C51单片机为核心控制元件,设计一个简易的数字电压表,设计的系统实用性强、操作简单,实现了智能化、数字化。
接通电源后,主持人将开关拨到“清除”
状态,抢答器处于禁止状态,编号显示器熄灭,定时器显示设定时间;主持人将开关置,“开始”状态,宣布“开始”抢答器工作。定时器倒计时,扬声器给出声响提示.
如果再次抢答必须由主持人再次操作“开始,停止”状态开关。
2. 设计要求
2.1系统方案论证
根据设计任务,分析设计系统的组成,给出实现设计任务的几种方案,分析比较几种设计方案的优略,本着尽量以软件代替硬件,同时力求电路简单,工作可靠的原则,确定总体设计方案。
2.2系统硬件电路设计
根据系统设计方案进行软、硬件的分配,软、硬件设计分别进行。硬件设计包括单片机最小系统和扩展接口及配置,硬件结构在设计时要选择合适的元器件,硬件电路要简洁、工作可靠,需用Proteus绘制整个系统的电路仿真原理图。
2.3软件设计
根据该系统要求的功能进行软件设计,简述软件的功能,并根据每个模块的功能绘制软件流程图,根据流程图编写程序并汇编调试通过;列出软件清单,软件清单要求加以注释。
仿真图:
/*************************************************************
八路抢答器系统
补充说明:
***************************************************************/
#include //头文件
/**********************引脚定义************************/
sbit key_zhu=P2^2; //主持人键
sbit key_jia=P2^1; //加键
sbit key_jian=P2^0; //减键
sbit key_1=P1^1; //八位选手按键定义
sbit key_2=P1^3;
sbit key_3=P1^5;
sbit key_4=P1^7;
sbit key_5=P3^1;
sbit key_6=P3^3;
sbit key_7=P3^5;
sbit key_8=P3^7;
sbit led_1=P1^0; //八位LED灯按键定义
sbit led_2=P1^2;
sbit led_3=P1^4;
sbit led_4=P1^6;
sbit led_5=P3^0;
sbit led_6=P3^2;
sbit led_7=P3^4;
sbit led_8=P3^6;
/**********************变量定义************************/
uchar zhu_f=0; //比赛进行阶段标记位,=0表示没有按。=1表示在设置倒计时的时间。=2表示开始抢答
uchar qiang_f=0; //抢答犯规标记,=0没有犯规。=1表示有人犯规
uchar wan_f=0; //抢答完成标记,=0抢答没完成后还没有开始。=1表示抢答完成
uchar time=30; //倒计时时间
uchar T0_num; //定时器0计数
uchar number; //抢答成功选手的编号,或犯规选手的编号。=0的时候表示没有
/********************************************************
函数名称:void delayms(uint ms)
函数作用:毫秒延时函数
参数说明:
********************************************************/
void delayms(uint ms)
{
unsigned char i=100,j;
for(;ms;ms--)
{
while(--i)
{
j=10;
while(--j);
}
}
}
/********************************************************
函数名称:void bajing()
函数作用:抢答犯规报警提示
参数说明:
********************************************************/
void bajing()
{
buzz=0; //开蜂鸣器
delayms(10);
buzz=1; //关蜂鸣器
delayms(10);
}
/********************************************************
函数名称:uchar qianda()
函数作用:抢答按键检测,返回抢答编号
参数说明:
********************************************************/
uchar qianda()
{
uchar temp=0;
if(key_1==0) //一号犯规,下同
temp=1; //记录1号
else
if(key_2==0)
temp=2;
else
if(key_3==0)
temp=3;
else
if(key_4==0)
temp=4;
else
if(key_5==0)
temp=5;
else
if(key_6==0)
temp=6;
else
if(key_7==0)
temp=7;
else
if(key_8==0)
temp=8;
return temp;
}
/********************************************************
函数名称:void led_kongzhi(uchar num,bit mode)
函数作用:LED灯控制
参数说明:num控制哪一个灯,k=1,点亮,=0关闭。mode=0全灭后在控制这个灯,=1单独控制这个灯
********************************************************/
void led_kongzhi(uchar num,bit k,bit mode)
{
if(mode==0)
{
led_1=1; //八位LED灯全灭
led_2=1;
led_3=1;
led_4=1;
led_5=1;
led_6=1;
led_7=1;
led_8=1;
}
if(k==1)
{
switch (num) //控制对应LED灯亮
{
case 1:led_1=0;
break;
case 2:led_2=0;
break;
case 3:led_3=0;
break;
case 4:led_4=0;
break;
case 5:led_5=0;
break;
case 6:led_6=0;
break;
case 7:led_7=0;
break;
case 8:led_8=0;
break;
}
}
else
{
switch (num) //控制对应LED灯灭
{
case 1:led_1=1;
break;
case 2:led_2=1;
break;
case 3:led_3=1;
break;
case 4:led_4=1;
break;
case 5:led_5=1;
break;
case 6:led_6=1;
break;
case 7:led_7=1;
break;
case 8:led_8=1;
break;
}
}
}
/********************************************************
函数名称:void scan(void)
函数作用:按键检测函数
参数说明:
********************************************************/
void scan(void)
{
uchar qiangda_num=0;
//主持人键
if(key_zhu==0) //按键按下
{
delayms(7); //显示消抖
if(key_zhu==0&&zhu_f!=2&&qiang_f==0&&wan_f==0)//判断是否有人犯规或者抢答是否开始或者抢答是否完成
{
zhu_f++; //比赛阶段标记+1
if(zhu_f==2) //比赛正式开始
{
TR0=1; //比赛开始,开启定时
wan_f=0; //清除比赛完成标志
bajing(); //提示比赛开始
}
}
else
if(key_zhu==0&&qiang_f==1) //判断是否有人犯规
{
buzz=1; //清除报警
qiang_f=0; //清除抢答标志
number=0; //清除选手编号
time=EEPROM_read(0x2000);//重新读取存储的抢答总时长
led_kongzhi(0,0,0);
}
else
if(key_zhu==0&&wan_f==1) //判断是否有人完成
{
buzz=1; //清除报警
wan_f=0; //清除完成标志
number=0; //清除选手编号
time=EEPROM_read(0x2000);//重新读取存储的抢答总时长
led_kongzhi(0,0,0);
}
else
if(key_zhu==0&&zhu_f==2) //暂停比赛
{
TR0=0; //关闭定时
zhu_f=1; //重新回到设置比赛时间阶段
bajing(); //提示暂停比赛
}
while(!key_zhu);//检测按键松开
}
//加值键,支持连按
if(key_jia==0&&zhu_f==1&&qiang_f==0) //判断是否在设置倒计时时间
{
delayms(7); //延时消抖
if(key_jia==0) //再次判断按键按下
{
if(time<99) //比赛时间最大值99S
time++; //比赛时间+1S
EEPROM_delete(0x2000); //擦除EEPROM煽区
EEPROM_write(0x2000,time); //写入【比赛时间】数据保存
display(time/10,time%10,10,0); //显示设置比赛时间
}
}
//减值键,支持连按
if(key_jian==0&&zhu_f==1&&qiang_f==0) //判断是否在设置倒计时时间
{
delayms(7); //延时消抖
if(key_jian==0) //再次判断按键按下
{
if(time!=0) //比赛时间最小值0S
time--; //比赛时间-1S
EEPROM_delete(0x2000); //擦除EEPROM煽区
EEPROM_write(0x2000,time); //写入【比赛时间】数据保存
display(time/10,time%10,10,0); //显示设置比赛时间
}
}
//选手按键
qiangda_num=qianda();
if(qiangda_num!=0) //判断是否有选手按下按键
{
if(zhu_f!=2&&qiang_f==0&&wan_f==0)//如果还没有开始抢答时按下
{
zhu_f=1;
buzz=0; //蜂鸣器报警
qiang_f=1; //抢答犯规标记
number=qiangda_num;
led_kongzhi(number,1,0);
}
else
if(zhu_f==2&&wan_f==0) //在开始抢答时按下
{
wan_f=1; //标记抢答完成
zhu_f=0; //主持人标记复位
TR0=0; //关闭倒计时定时器
number=qiangda_num;
led_kongzhi(number,1,0);
bajing(); //提示有人抢答完成
}
}
}
/*********************************************************
函数名称:void main()
函数作用:主函数函数
参数说明:
*********************************************************/
void main()
{
uchar i=0;
T0_init(); //定时器初始化
if(key_jian==0)
{
delayms(100);
if(key_jian==0)
{
EEPROM_delete(0x2000); //擦除EEPROM煽区
EEPROM_write(0x2000,30); //写入【比赛时间】数据保存
}
}
time=EEPROM_read(0x2000); //读取存储的【比赛时间】数据
for(i=0;i<9;i++)
{
led_kongzhi(i,1,1);
delayms(10);
}
for(i=9;i>0;i--)
{
led_kongzhi(i-1,0,1);
delayms(10);
}
led_kongzhi(0,0,0);
while(1) //死循环
{
scan(); //按键检测处理
if(zhu_f==0&&wan_f==0) //判断是否还没进入比赛阶段
display(10,10,10,10); //未进入,显示"----"
else
if(zhu_f==0&&wan_f==1) //进入比赛阶段,并且处于设置比赛时间
display(time/10,time%10,10,number);//显示设置比赛时间
else
if(zhu_f!=0)
{
if(qiang_f==1) //设有人犯规
display(11,11,10,number); //显示FF-犯规编号
else
display(time/10,time%10,10,number);//显示比赛剩余时间和抢答者编号,未抢答显示0
}
}
}
【iBot机器人工作室的个人空间-哔哩哔哩】 https://b23.tv/ryUWVKa