51单片机编程应用(C语言):篮球比赛计分器

设计思路

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了,如:

实验现象我会录制视频,请在视频观看

相关推荐
lulu_gh_yu15 分钟前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
~yY…s<#>2 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
极客小张3 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩
EricWang13584 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
我是谁??4 小时前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
希言JY5 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
午言若5 小时前
C语言比较两个字符串是否相同
c语言
m0_739312876 小时前
【STM32】项目实战——OV7725/OV2604摄像头颜色识别检测(开源)
stm32·单片机·嵌入式硬件
嵌入式小章6 小时前
基于STM32的实时时钟(RTC)教学
stm32·嵌入式硬件·实时音视频
TeYiToKu6 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm