只需一步,快速开始
热门: 51单片机 | 24小时必答区 | 单片机教程 | 单片机DIY制作 | STM32 | Cortex M3 | 模数电子 | 电子DIY制作 | 音响/功放 | 拆机乐园 | Arduino | 嵌入式OS | 程序设计
侯从彬;吕卫伟;刘艳平;朱强
实验要求:
1: 两个两位的数码管,
一个用来显示倒计时时间,
一个用来显示选手的编号。
2: 主持人控制两个按键K1-K2:
功能键K1:抢答开始,开始倒时,扬声器响。
功能键K2: 功能1:清除显示(时间从倒计时的最大时间开始,选手编号显示清零);
功能2:设置倒计时的时间。
八位选手各控制一键,待主持人按下开始键后,第一个按下抢答键的选手的编号将被显示。扬声器停,其他键均被屏蔽,至到主持人再次按下开始键。
实验模块分析:
共阴极:
(1)
位选端: 置数功能 P00…P07
输入
0X3F
0X06
0X5B
0X4F
0X66
0X6D
0X7D
0X07
0X7F
0X6F
显示
0
1
2
3
4
5
6
7
8
9
(2)
段选端: 控制功能 D0..D1;
D0=0 启动置数;
D0=1 停止置数;
例如:置D0=0;P0=0X3F;
则数码管显示数字 0
2 .
本实验需要两个数码管同时显示,实际上是达不到同时显示的;但可以利用“视觉暂留效应”达到此效果;
同时也要考虑到消除数码管显示抖动现象;
这就需要实验者熟练应用 delay() 延时函数;
d1=0;
P0=tab[num/10];//倒计时控制
delay(5);
d1=1;
d2=0;
P0=tab[num%10];
d2=1;
其中的 delay(5) 就是为了达到一上所叙述的目的
<二>、
蜂鸣器:
只要在BUZ 端接地即可鸣叫。
<二、程序框图>
主函数:
实物图连接:
P1口接8选手开关,在ZK1 ZK2为主持人开关,功能与题目要求一样
P0 口为数码管位选 。
注意:P0口使用时必须接上拉电阻否则为高阻态 。
P2口的分别用作主持人开关(P2^0、P2^1)两数码管段选(P2^4...P2^7);
实验程序分析:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define max 20
uchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,};
sbit d1=P2^4;//**************段选
sbit d2=P2^5;
sbit x1=P2^6;
sbit x2=P2^7;
sbit k1=P1^0;//*********************八位选手开关
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;
sbit k5=P1^4;
sbit k6=P1^5;
sbit k7=P1^6;
sbit k8=P1^7;
sbit zk1=P2^0;//*****************************主持人开关zk1 zk2
sbit zk2=P2^1;
sbit buz=P2^2;//*******************蜂鸣器
uchar num,aa;
uchar f,flag;
void jianpan();
void init(void)
{
TMOD=0X01;//***************T0,模式1,定时
TL0=0XB0; //********************定时50ms
TH0=0X3C;
ET0=1; //**************开中断
EA=1;
num=max;//置倒计时计数初值
}
void delay(uint xms)
uint x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
/**********************************************
倒计时 选手号显示函数
**********************************************/
void display()
{d1=0; //控制开始置数
P0=tab[num/10];//倒计时控制取最高位
d1=1; //停止置数操作
P0=tab[num%10];//倒计时取最低位
x1=0; //控制开始置数
P0=tab[flag/10];//选手号控制
x1=1; //停止置数操作
x2=0;
P0=tab[flag%10];
x2=1;
/**********************************************************主函数部分
**********************************************************/void main()
init();
while(1)
{ jianpan();display();} }
/***************************************
中断控制倒计时
*************************************/
void timer0(void) interrupt 1
TL0=0XB0; //******重装初值,定时50ms
aa++;
if(aa==20)//**********************************1秒到了
aa=0;//**************************************计数清零
num--;
if(num==0)//倒计时为0时迅速变为初值同时关中断停止倒计时
{ num=max;
TR0=0; }
buz=0;//***************要求蜂鸣器响
delay(20);//**************************蜂鸣器响,特别注意时间为一秒buz=1;
/**************************************************
按键控制 程序的核心部分
****************************************************/
void jianpan()
if(zk1==0&flag=0)
delay(5);//消除数码管抖动操作
flag=0;//数码管显示0
display();
TR0=1;//ZK1键按下,开中断以此控制:只有当此键按下时才抢答
if(zk2==0&&TR0==0)//注意这里要求TR0=0;
delay(5);//消除抖动
if(zk2==0&&TR0==0)
if(flag==0)
{num--;buz=0;delay(20);buz=1;}
if(num==0)
num=max;
if(flag!=0)//ZK2键清零操作
flag=0;
num=max;//倒计时显示最大值
TR0=0;//注意此时关中断,不再进行倒计时
buz=0;
delay(20);
buz=1;
while(!zk2)//倒计时中ZK2 键不可影响
/**********************************************************TR0控制抢答先后顺序
*********************************************************/
if(k1==0&&TR0==1)//注意此时TR0=1才执行以下按键操作
flag=1;
TR0=0;//此键按下关中断,其他选手按键不再受影响
/*************************************
以下原理相同
if(k2==0&&TR0==1)
buz=0;delay(20);buz=1;
flag=2;
TR0=0;
if(k3==0&&TR0==1)
flag=3;
if(k4==0&&TR0==1)
flag=4;
display(); }
if(k5==0&&TR0==1)
flag=5;
if(k6==0&&TR0==1)
display(); }
if(k7==0&&TR0==1)
buz=0;delay(20);
flag=7;
if(k8==0&&TR0==1)
flag=8;
(1).
此实验最大的特点便是中断的巧妙应用
另外要注意延迟函数对数码管显示效果的影响
(2).
控制选手先后顺序时,设置了两个条件:按键和TR0,
而TR0则是控制关键,也是主持人按键控制的关键
使用道具 举报
本版积分规则 发表回复 回帖后跳转到最后一页
手机版|小黑屋|51黑电子论坛 | 管理员QQ:125739409;技术交流QQ群281945664
Powered by 单片机教程网