这是本人最近单片机的作品之一,纯原创手打。
一、实验目的
利用所学知识点(按键、数码管、中断等),设计一个篮球计分器。
二、实验内容
利用两位共阴数码管、4082与门、AT89C51单片机、按钮等元器件设计电路及相关代码,完成以下功能:
AB两队各一个两位(共阴)7段数码管计分器,计数范围00-99。
四个按键功能:
K1: 清零记分器
K2: 加1分
K3: 减1分
K4: 切换计分队伍
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
3、原理图:
单片机代码#include "reg51.h"
sbit shi = P3^0; //十位位选
sbit ge = P3^1; //个位位选
char led_mod[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共阴数码管012345679
unsigned char num1 = 0; //数码管显示内容 队伍1分数
unsigned char num2 = 0;//队伍2分数
unsigned char team = 1;//选择队伍 初始为1
void init_int0();
void delay(unsigned int time);
void display();
void main()
{
init_int0(); //中断初始化
while(1)
{
display(); //数码管显示
}
}
void display()
{
shi = 0; //共阴极数码管显示十位 shi=P3^0连着两位数码管的1
ge = 1; //个位 ge=P3^1 连着两位数码管的2
P2 = led_mod[((num1/10)%10)]; //十位
P1 = led_mod[((num2/10)%10)];
delay(10);
P2 = 0x00; //消隐
P1 = 0x00;
shi = 1; //显示个位
ge = 0;
P2 = led_mod[(num1%10)]; //个位
P1 = led_mod[(num2%10)];
delay(10);
P2 = 0x00; //消隐
P1 = 0x00;
}
void delay(unsigned int time){
unsigned int j = 0;
for(;time>0;time--)
for(j=0;j<125;j++);
}
void init_int0()
{
IT0=1;EX0=1;EA=1;
}
void key() interrupt 0 //键控中断
{
delay(10); //延时消抖
if((P0 & 0x0f) != 0xf0) //检测按键是否有按下
{
if((P0 & 0x01) == 0x00) //按键1按下
{
if(team == 1)num1 = 0;
if(team == 2)num2 = 0;
}
if((P0 & 0x02) == 0x00) //按键2按下
{
if(team ==1 && num1 < 99)
num1++;
else if (team == 2 && num2 < 99)
num2++;
}
if((P0 & 0x04) == 0x00) //按键3按下
{
if(team ==1 && num1 > 0)
num1--;
else if(team == 2 && num2 > 0)
num2--;
}
if((P0 & 0x08) == 0x00) //按键4按下
{
if(team == 1)team = 2;
else if (team == 2)team = 1;
}
}
}
4、实验结果及分析
AB两队各一个两位(共阴)7段数码管计分器,计数范围00-99。
四个按键功能:K1: 清零记分器K4: 切换计分队伍 K2: 加1分 K3: 减1分
分析:有两个记录A、B队伍分数的变量num1、num2,以及记录当前控制队伍的变量team,team的值只取1或2,表示当前控制队伍为A队或B队,按下按钮后,连接与门4082的INT0中断口会从1变为0,触发中断,再根据P1口可以判断按下的是哪个按钮,若是K1则当前team的num变为0,若是K2,则当前team的num++,K3则当前team的num--,K4则team由1变0或由0变1。
数码管分别连的是P1口和P0口,num1给P0,num2给P1,这样就能两个数码管显示不同的数字。两个数码管共用两个单片机引脚作为数码管的位选码,当是个位时num的个位赋给P口,十位时,num的十位赋给P口,在超循环仿真下,就可以看起来是同时亮了。
|