- /**************************************************************************************
- 篮球记分器的设计
- /AT89C51单片机、数码管若干、38译码器、矩阵按键、蜂鸣器
- ***************************************************************************************/
- #include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
- typedef unsigned int u16; //对数据类型进行声明定义
- typedef unsigned char u8;
- sbit LSA=P2^0; //38译码器控制
- sbit LSB=P2^1;
- sbit LSC=P2^2;
- sbit LSD=P2^3; //蜂鸣器触发口
- sbit F1=P2^4; //倒计时数码管控制口
- sbit F2=P2^5;
- sbit S1=P2^6;
- sbit S2=P2^7;
- u8 KeyValue; //用来存放读取到的键值
- u8 feng; //蜂鸣器
- #define GPIO_DIG P0 //计分数码管输出口
- #define GPIO_KEY P1 //矩阵按键输入口
- #define GPIO_TIME P3 //倒计时数码管输出口
- u8 code DIG_CODE[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示0~9的值
- unsigned char Show[8]={ 0,0,0,0,0,0,0,0,}; //数组存放向数码管输入的数
- unsigned char TShow[4]={ 0,0,0,0,};
- u16 Ascore,Bscore,Change; //分数
- u8 Period; //节数
- u8 m=12,n,c; //定时器变量
- /*******************************************************************************
- * 函 数 名 : delay
- * 函数功能 : 延时函数,i=1时,大约延时10us
- *******************************************************************************/
- void delay(u16 i)
- {
- while(i--);
- }
- /*******************************************************************************
- * 函 数 名 : KeyDown
- * 函数功能 : 检测有按键按下并读取键值
- *******************************************************************************/
- void KeyDown(void)
- {
- char a=0;
- GPIO_KEY=0x0f;
- KeyValue=20; //初始值
-
- if(GPIO_KEY!=0x0f)//读取按键是否按下
- {
- delay(100);//延时10ms进行消抖
- if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
- {
- //测试列
- GPIO_KEY=0X0F;
- switch(GPIO_KEY)
- {
- case(0X0E): KeyValue=0;break;
- case(0X0D): KeyValue=4;break;
- case(0X0B): KeyValue=8;break;
- case(0X07): KeyValue=12;break;
- }
- //测试行
- GPIO_KEY=0XF0;
- switch(GPIO_KEY)
- {
- case(0X70): KeyValue=KeyValue;break;
- case(0XB0): KeyValue=KeyValue+1;break;
- case(0XD0): KeyValue=KeyValue+2;break;
- case(0XE0): KeyValue=KeyValue+3;break;
- }
- while((a<500)&&(GPIO_KEY!=0xf0)) //检测按键松手检测
- {
- delay(1000);
- a++;
- }
- }
- }
- }
- /**********************************************************************
- *函 数 名 : Score
- *函数功能 : 加分程序,按键执行程序
- *************************************************************************/
- void Score()
- {
- if(KeyValue!=20)
- switch(KeyValue)//A队的计分
- {
- case(0): Ascore=Ascore+1;KeyValue=20;break;
- case(1): Ascore=Ascore+2;KeyValue=20;break;
- case(2): Ascore=Ascore+3;KeyValue=20;break;
- case(3): Ascore=Ascore-1;KeyValue=20;break;
- }
- switch(KeyValue)//B队的计分
- {
- case(4): Bscore=Bscore+1;KeyValue=20;break;
- case(5): Bscore=Bscore+2;KeyValue=20;break;
- case(6): Bscore=Bscore+3;KeyValue=20;break;
- case(7): Bscore=Bscore-1;KeyValue=20;break;
- }
- switch(KeyValue)
- {
- case(8): Period=Period+1;KeyValue=20;break; //每一节加一
- case(9): Period=Period-1;KeyValue=20;break; //减一//
- case(10): Change=Ascore;Ascore=Bscore;Bscore=Change;break; //交换场地
- case(11): Ascore=0; Bscore=0;Period=0;KeyValue=20;break; //计分板复位
- case(12): TR0 = 1; m=12; n=0; KeyValue=20;break; //定时50ms,20*50=1000msbreak;
- case(13): TR0 = 1; break; //继续比赛
- case(14): feng=1;TR0 = 0; KeyValue=20;break; //暂停比赛
- case(15): feng=0; KeyValue=20;break; //关闭蜂鸣器
- }
- }
- /************************************************************
- *函 数 名 : fengMQ
- *函数功能 : 蜂鸣器触发程序
- **************************************************************/
- void fengMQ(void)
- {
- if(feng==1)
- {
- LSD=~LSD;
- }
- }
- /******************************************************************
- *函 数 名 : Conut
- *函数功能 : 分离开送给数码管的数字
- *******************************************************************/
- void Conut(void)
- {
- Show[0]=Period%10;
- Show[1]=Ascore/100;
- Show[2]=Ascore/10%10;
- Show[3]=Ascore%10;
-
- Show[4]=0;
- Show[5]=Bscore/100;
- Show[6]=Bscore/10%10;
- Show[7]=Bscore%10;
-
- TShow[0]=m/10;
- TShow[1]=m%10;
- TShow[2]=n/10;
- TShow[3]=n%10;
-
- }
- /*******************************************************************************
- * 函 数 名 : DigDisplay
- * 函数功能 : 数码管动态扫描函数,循环扫描8个数码管显示
- *******************************************************************************/
- void DigDisplay()
- {
- u8 i,w;
- for(i=0;i<8;i++)
- {
- switch(i) //位选,选择点亮的数码管,比分显示
- {
- case(0):
- LSA=0;LSB=0;LSC=0; break;//显示第0位
- case(1):
- LSA=1;LSB=0;LSC=0; break;//显示第1位
- case(2):
- LSA=0;LSB=1;LSC=0; break;//显示第2位
- case(3):
- LSA=1;LSB=1;LSC=0; break;//显示第3位
- case(4):
- LSA=0;LSB=0;LSC=1; break;//显示第4位
- case(5):
- LSA=1;LSB=0;LSC=1; break;//显示第5位
- case(6):
- LSA=0;LSB=1;LSC=1; break;//显示第6位
- case(7):
- LSA=1;LSB=1;LSC=1; break;//显示第7位
- }
- GPIO_DIG = DIG_CODE[Show[i]];//发送段码
- delay(10); //间隔一段时间扫描
- P0=0x00;//消隐
- }
- for(w=0;w<4;w++) //倒计时显示
- {
- switch(w) //位选,选择点亮的数码管,
- {
- case(0):
- F1=0;F2=1;S1=1;S2=1; break;//显示第1位
- case(1):
- F1=1;F2=0;S1=1;S2=1; break;//显示第2位
- case(2):
- F1=1;F2=1;S1=0;S2=1; break;//显示第3位
- case(3):
- F1=1;F2=1;S1=1;S2=0; break;//显示第4位
- }
- GPIO_TIME = DIG_CODE[TShow[w]];
- delay(10); //间隔一段时间扫描
- P3=0x00; //消隐
- }
- }
- /*******************************************************************************
- * 函 数 名 : Timer0Init
- * 函数功能 : 配置定时器0,定时50ms
- *******************************************************************************/
- void Timer0Init()
- {
- TMOD |= 0x01; //选择工作方式1
- TH0 = 0x3C; //设置初始值,定时50MS
- TL0 = 0xB0;
- EA = 1; //打开总中断
- ET0 = 1; //打开定时器0中断
- // TR0 = 1; //启动定时器0
- }
- /*******************************************************************************
- * 函 数 名 : main
- * 函数功能 : 主函数
- *******************************************************************************/
- void main()
- {
- Timer0Init();
- while(1)
- {
- KeyDown();
- Score();
- Conut(); //分离出数
- fengMQ(); //*蜂鸣器
- DigDisplay(); //数码管显示函数
- }
- }
- void Timer0() interrupt 1 //中断程序
- {
- static u16 q; //定义变量q,1s=50ms*20
- TH0 = 0x3C; //设置初始值,定时50MS
- TL0 = 0xB0;
- q++;
- if(q==20) //计时20次时为1秒
- {
- q=0; //变量q置零
- if(n==0) //当倒计时秒针为0时,分针减一,秒针为59
- {
- n=60;
- m=m-1;
- }
- n=n-1; //每秒减一
- }
- if(m==0&&n==0) //一节结束定时器停止,时间重置12:00;
- {
- TR0 =0;
- }
- }
复制代码
正在重新握手 ... 成功 [0.594"]
当前的波特率: 115200
正在擦除目标区域 ... 完成 ! [0.313"]
芯片出厂序列号 : F002C4B208E7AE
正在下载用户代码 ... 完成 ! [0.875"]
正在设置硬件选项 ... 完成 ! [0.015"]
更新后的硬件选项为:
. 当前的时钟频率: 11.088MHz
. 系统频率为12T(单倍速)模式
. 振荡器的放大增益不降低
. 当看门狗启动后,任何复位都可停止看门狗
. MCU内部的扩展RAM可用
. ALE脚的功能选择仍然为ALE功能脚
. P1.0和P1.1与下次下载无关
. 下次下载用户程序时,不擦除用户EEPROM区
单片机型号: STC89C52RC/LE52RC
固件版本号: 6.6.4C
操作成功 !
|