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实验中会有滴答滴答的声音。
实验:
让蜂鸣器发出声音,一段时间后再关闭,即让管脚输出一定频率的脉冲信号(高低电平)控制无源蜂鸣器。
代码如下:
#include 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
#include #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了,如:
实验现象我会录制视频,请在视频观看