设计思路
1.LCD1602显示A 000:B 000 右下角显示24的数字,显示一节时间12:00.
2.规定矩阵键盘每一位表示的含义
s1按下,A队加一分 s2按下,A队加两分 s3按下,A队加三分 s4按下,A队减一分
如果加错了,减分修改错误计分,一分一分修改。
s5按下,B队加一分 s6按下,B队加两分 s7按下,B队加三分 s8按下,B队减一分
如果加错了,减分修改错误计分,一分一分修改。
S9: 控制比赛计时时间,第一次按下,比赛开始,再一次按下,时间暂停。(篮球比赛是不是可以叫暂停,暂停时比赛时间是不能计时的)
S10: 按下24秒重新开始计时(暂停时,我想要变回24s)
3.定时器中断,控制24秒一秒一秒减。,一节时间也是一秒一秒的减少。12:00---11:59---10:00---09:59.........
4.篮球比赛进球了,此时24秒无论计时到多少是不是要重新变成24秒。也就是S1--S8按下,24秒重新计时。
看一下任务要求:
具体任务要求:
1、能显示2个队的当前比分;(完成)
2、根据各自得分情况进行加1、2、3分,可按键修改错误计分(如2分被计为3分);(完成)
3、显示当前进攻队的进攻时间倒计(24秒);(完成)
4、计时归零时候,鸣响。(要用蜂鸣器)(完成一半)24秒计完时会鸣叫,但是时间计完时加入蜂鸣器鸣叫后出现了问题,很奇怪的bug,直接加了00在秒个后面,所以这一部分我暂时没有添加,后面我再想清楚原因弄好后再添加。
蜂鸣器
根据蜂鸣器发声方式不同,主要分为压电式(无源)和电磁式(有源)。同时根据蜂鸣器结构,分为有源蜂鸣器和无源蜂鸣器。有源蜂鸣器自带震荡电路,接通电源即可发声。无源没有震荡电路
振荡器电路的作用:产生脉冲信号。
无源蜂鸣器 需要提供一定频率的脉冲信号才能发声,频率一般在 1.5-5KHZ。
通过调节脉冲频率可改变音调(音色),通过改变高低电平占空比可以调节音量。
51单片机使用的是无源蜂鸣器。
蜂鸣器原理图
通过C51芯片的P15引脚持续输出脉冲信号(即高低电平交替),经过ULN2003D芯片放大电流从BEEP引脚输出到蜂鸣器即可发声
注意P2^5引脚同时控制着LED6,当脉冲信号在一定频率时,可以观察到LED6的闪烁,这就是为什么在LED实验中会有滴答滴答的声音。
实验:
让蜂鸣器发出声音,一段时间后再关闭,即让管脚输出一定频率的脉冲信号(高低电平)控制无源蜂鸣器。
代码如下:
cpp
#include <REGX52.H>
typedef unsigned char u8;
typedef unsigned int u16;
sbit BEEP=P2^5;
void delay_10us(u16 i)//i为1时,大约延时10us
{
while(i--);
}
void main()
{
u16 i=2000;
while(1)
{
while(i--)
{
BEEP=!BEEP;
delay_10us(100);
}
i=0;//结束循环
BEEP=1;//关闭第六个LED
}
}
篮球计分器总代码
main.c
cpp
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "Timer0.h"
sbit BEEP=P2^5;
unsigned char number=24;//24秒倒计时
unsigned char min_shi=1; //一节12分钟,分钟的十位
unsigned char min_ge=2 ; //一节12分钟,分钟的个位
unsigned char miao_shi=0 ; //一节12分钟,秒钟的十位
unsigned char miao_ge=0; //一节12分钟,秒钟的个位
unsigned char keyNumber; //接收矩阵键盘返回的值
unsigned char score_A; //A队的分数,3位
unsigned char score_B; //B队的分数,3位
unsigned char Mode=1; //Mode=1,比赛暂停,Mode=0,比赛开始。
unsigned int i=2000; //蜂鸣器报警时长。
void main()
{
Timer0Init();
LCD_Init();
LCD_ShowChar(1,1,'A');
LCD_ShowChar(1,2,' ');
LCD_ShowChar(1,6,':');
LCD_ShowChar(1,7,'B');
LCD_ShowChar(1,8,' ');
LCD_ShowChar(2,3,':');
while(1)
{
keyNumber=MatrixKey();
LCD_ShowNum(1,3,score_A,3);
LCD_ShowNum(1,9,score_B,3);
LCD_ShowNum(2,15,number,2);
LCD_ShowNum(2,1,min_shi,1);
LCD_ShowNum(2,2,min_ge,1);
LCD_ShowNum(2,4,miao_shi,1);
LCD_ShowNum(2,5,miao_ge,1);
if(keyNumber)
{
if(keyNumber==1)//s1按下,A队加一分
{
score_A++;
number=24;
LCD_ShowNum(1,3,score_A,3);//更新显示
LCD_ShowNum(2,15,number,2);//更新显示
}
if(keyNumber==2)//s2按下,A队加两分
{
score_A=score_A+2;
number=24;
LCD_ShowNum(1,3,score_A,3);//更新显示
LCD_ShowNum(2,15,number,2);//更新显示
}
if(keyNumber==3)//s3按下,A队加三分
{
number=24;
score_A=score_A+3;
LCD_ShowNum(1,3,score_A,3);//更新显示
LCD_ShowNum(2,15,number,2);//更新显示
}
if(keyNumber==4)//s4按下,A队减一分 如果加错了,减分修改错误计分,一分一分修改
{
score_A=score_A-1;
LCD_ShowNum(1,3,score_A,3);//更新显示
}
if(keyNumber==5)//s1按下,B队加一分
{
number=24;
score_B++;
LCD_ShowNum(1,9,score_B,3);//更新显示
LCD_ShowNum(2,15,number,2);//更新显示
}
if(keyNumber==6)//s2按下,A队加两分
{
number=24;
score_B=score_B+2;
LCD_ShowNum(1,9,score_B,3);//更新显示
LCD_ShowNum(2,15,number,2);//更新显示
}
if(keyNumber==7)//s3按下,A队加三分
{
number=24;
score_B=score_B+3;
LCD_ShowNum(1,9,score_B,3);//更新显示
LCD_ShowNum(2,15,number,2);//更新显示
}
if(keyNumber==8)//s3按下,A队减一分 如果加错了,减分修改错误计分,一分一分修改
{
score_B=score_B-1;
LCD_ShowNum(1,9,score_B,3);//更新显示
}
if(keyNumber==9)
{
Mode++;
if(Mode>=2)
Mode=0;
}
if(keyNumber==10)
{
number=24;
LCD_ShowNum(1,9,score_B,3);//更新显示
}
}
}
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++;
if(T0Count>=1000) //定时器分频,1s
{
T0Count=0;
//number=number-1;
if(Mode==0)
{
if(number==0)
{
number=25;
while(i--)
{
BEEP=!BEEP;
Delay(1);
}
i=2000;
BEEP=1;//关闭第六个LED
}
number=number-1;
if(miao_ge==0)
{
miao_ge=10;
if(miao_shi==0)
{
if(min_ge==0)
{
min_shi=0;
min_ge=10;
}
min_ge=min_ge-1;
miao_shi=6;
}
miao_shi=miao_shi-1;
}
miao_ge= miao_ge-1;
}
}
}
除了main函数外,其他函数都是模块化编程好的,都在我写过的易于模块化编程函数里面直接复制粘贴就OK了,如:
实验现象我会录制视频,请在视频观看