找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1304|回复: 0
收起左侧

请问各位大佬这个篮球记分器程序有错吗?为什么不能控制加分和蜂鸣器

[复制链接]
ID:988120 发表于 2021-12-6 19:47 | 显示全部楼层 |阅读模式
  1. /**************************************************************************************
  2. 篮球记分器的设计
  3. /AT89C51单片机、数码管若干、38译码器、矩阵按键、蜂鸣器
  4. ***************************************************************************************/

  5. #include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

  6. typedef unsigned int u16;          //对数据类型进行声明定义
  7. typedef unsigned char u8;

  8. sbit LSA=P2^0;      //38译码器控制
  9. sbit LSB=P2^1;
  10. sbit LSC=P2^2;
  11. sbit LSD=P2^3;      //蜂鸣器触发口
  12. sbit F1=P2^4;       //倒计时数码管控制口
  13. sbit F2=P2^5;
  14. sbit S1=P2^6;
  15. sbit S2=P2^7;

  16. u8 KeyValue;        //用来存放读取到的键值
  17. u8 feng;      //蜂鸣器

  18. #define GPIO_DIG P0    //计分数码管输出口
  19. #define GPIO_KEY P1    //矩阵按键输入口
  20. #define GPIO_TIME P3   //倒计时数码管输出口

  21. u8 code DIG_CODE[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示0~9的值
  22. unsigned char Show[8]={ 0,0,0,0,0,0,0,0,};    //数组存放向数码管输入的数
  23. unsigned char TShow[4]={ 0,0,0,0,};

  24. u16 Ascore,Bscore,Change;  //分数
  25. u8 Period;                 //节数
  26. u8 m=12,n,c;             //定时器变量

  27. /*******************************************************************************
  28. * 函 数 名         : delay
  29. * 函数功能                   : 延时函数,i=1时,大约延时10us
  30. *******************************************************************************/
  31. void delay(u16 i)
  32. {
  33.         while(i--);        
  34. }

  35. /*******************************************************************************
  36. * 函 数 名         : KeyDown
  37. * 函数功能                   : 检测有按键按下并读取键值
  38. *******************************************************************************/
  39. void KeyDown(void)
  40. {
  41.         char a=0;
  42.         GPIO_KEY=0x0f;
  43.          KeyValue=20;   //初始值
  44.         
  45.         if(GPIO_KEY!=0x0f)//读取按键是否按下
  46.         {
  47.                 delay(100);//延时10ms进行消抖
  48.                 if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
  49.                 {        
  50.                         //测试列
  51.                         GPIO_KEY=0X0F;
  52.                         switch(GPIO_KEY)
  53.                         {
  54.                                 case(0X0E):        KeyValue=0;break;
  55.                                 case(0X0D):        KeyValue=4;break;
  56.                                 case(0X0B):     KeyValue=8;break;
  57.                                 case(0X07):        KeyValue=12;break;
  58.                         }
  59.                         //测试行
  60.                         GPIO_KEY=0XF0;
  61.                         switch(GPIO_KEY)
  62.                         {
  63.                                 case(0X70):        KeyValue=KeyValue;break;
  64.                                 case(0XB0):        KeyValue=KeyValue+1;break;
  65.                                 case(0XD0):     KeyValue=KeyValue+2;break;
  66.                                 case(0XE0):        KeyValue=KeyValue+3;break;
  67.                         }
  68.                         while((a<500)&&(GPIO_KEY!=0xf0))         //检测按键松手检测
  69.                         {
  70.                                 delay(1000);
  71.                                 a++;
  72.                         }
  73.                 }
  74.         }
  75. }

  76. /**********************************************************************
  77. *函 数 名         : Score
  78. *函数功能                     : 加分程序,按键执行程序
  79. *************************************************************************/
  80. void Score()
  81. {
  82.         if(KeyValue!=20)
  83.                         switch(KeyValue)//A队的计分
  84.                         {
  85.                                 case(0):        Ascore=Ascore+1;KeyValue=20;break;  
  86.                                 case(1):        Ascore=Ascore+2;KeyValue=20;break;
  87.                                 case(2):  Ascore=Ascore+3;KeyValue=20;break;
  88.                                 case(3):        Ascore=Ascore-1;KeyValue=20;break;
  89.                         }
  90.                         switch(KeyValue)//B队的计分
  91.                         {
  92.                                 case(4):        Bscore=Bscore+1;KeyValue=20;break;
  93.                                 case(5):        Bscore=Bscore+2;KeyValue=20;break;
  94.                                 case(6):  Bscore=Bscore+3;KeyValue=20;break;
  95.                                 case(7):        Bscore=Bscore-1;KeyValue=20;break;
  96.                         }
  97.                                 switch(KeyValue)
  98.                         {
  99.                                 case(8):        Period=Period+1;KeyValue=20;break;                                                           //每一节加一
  100.                                 case(9):        Period=Period-1;KeyValue=20;break;                                               //减一//
  101.                                 case(10): Change=Ascore;Ascore=Bscore;Bscore=Change;break;  //交换场地
  102.                                 case(11):        Ascore=0; Bscore=0;Period=0;KeyValue=20;break;                 //计分板复位
  103.                                 case(12): TR0 = 1;        m=12;  n=0;   KeyValue=20;break;     //定时50ms,20*50=1000msbreak;
  104.                                 case(13):        TR0 = 1;     break;                           //继续比赛
  105.                                 case(14): feng=1;TR0 = 0; KeyValue=20;break;            //暂停比赛
  106.                                 case(15):        feng=0; KeyValue=20;break;                    //关闭蜂鸣器
  107.                         }
  108. }

  109. /************************************************************
  110. *函 数 名         : fengMQ
  111. *函数功能                     : 蜂鸣器触发程序
  112. **************************************************************/
  113. void fengMQ(void)
  114. {
  115.   if(feng==1)
  116.         {
  117.                 LSD=~LSD;
  118.         }
  119. }

  120. /******************************************************************
  121. *函 数 名         : Conut
  122. *函数功能                     : 分离开送给数码管的数字
  123. *******************************************************************/
  124.    void Conut(void)
  125.         {
  126.                 Show[0]=Period%10;
  127.                 Show[1]=Ascore/100;
  128.                 Show[2]=Ascore/10%10;
  129.                 Show[3]=Ascore%10;
  130.                
  131.                 Show[4]=0;
  132.                 Show[5]=Bscore/100;
  133.                 Show[6]=Bscore/10%10;
  134.                 Show[7]=Bscore%10;
  135.                
  136.                 TShow[0]=m/10;
  137.                 TShow[1]=m%10;
  138.                 TShow[2]=n/10;
  139.                 TShow[3]=n%10;
  140.                
  141.         }

  142. /*******************************************************************************
  143. * 函 数 名         : DigDisplay
  144. * 函数功能                    : 数码管动态扫描函数,循环扫描8个数码管显示
  145. *******************************************************************************/
  146. void DigDisplay()
  147. {
  148.         u8 i,w;
  149.         for(i=0;i<8;i++)
  150.         {
  151.                 switch(i)          //位选,选择点亮的数码管,比分显示
  152.                 {
  153.                         case(0):
  154.                                 LSA=0;LSB=0;LSC=0; break;//显示第0位
  155.                         case(1):
  156.                                 LSA=1;LSB=0;LSC=0; break;//显示第1位
  157.                         case(2):
  158.                                 LSA=0;LSB=1;LSC=0; break;//显示第2位
  159.                         case(3):
  160.                                 LSA=1;LSB=1;LSC=0; break;//显示第3位
  161.                         case(4):
  162.                                 LSA=0;LSB=0;LSC=1; break;//显示第4位
  163.                         case(5):
  164.                                 LSA=1;LSB=0;LSC=1; break;//显示第5位
  165.                         case(6):
  166.                                 LSA=0;LSB=1;LSC=1; break;//显示第6位
  167.                         case(7):
  168.                                 LSA=1;LSB=1;LSC=1; break;//显示第7位        
  169.                 }
  170.                 GPIO_DIG = DIG_CODE[Show[i]];//发送段码        
  171.                 delay(10); //间隔一段时间扫描        
  172.                 P0=0x00;//消隐
  173.         }
  174.         for(w=0;w<4;w++)    //倒计时显示
  175.         {
  176.         switch(w)         //位选,选择点亮的数码管,
  177.                 {
  178.                         case(0):
  179.                                 F1=0;F2=1;S1=1;S2=1; break;//显示第1位
  180.                         case(1):
  181.                                 F1=1;F2=0;S1=1;S2=1; break;//显示第2位
  182.                         case(2):
  183.                                 F1=1;F2=1;S1=0;S2=1; break;//显示第3位
  184.                         case(3):
  185.                                 F1=1;F2=1;S1=1;S2=0; break;//显示第4位               
  186.                 }
  187.                 GPIO_TIME = DIG_CODE[TShow[w]];
  188.                 delay(10);  //间隔一段时间扫描        
  189.                 P3=0x00;    //消隐
  190.         }
  191. }

  192. /*******************************************************************************
  193. * 函 数 名         : Timer0Init
  194. * 函数功能                    : 配置定时器0,定时50ms
  195. *******************************************************************************/
  196. void Timer0Init()
  197. {
  198.           TMOD |= 0x01; //选择工作方式1
  199.     TH0 = 0x3C;         //设置初始值,定时50MS
  200.     TL0 = 0xB0;
  201.     EA = 1;                         //打开总中断
  202.     ET0 = 1;                 //打开定时器0中断
  203. // TR0 = 1;                 //启动定时器0
  204. }

  205. /*******************************************************************************
  206. * 函 数 名       : main
  207. * 函数功能                 : 主函数
  208. *******************************************************************************/
  209. void main()
  210. {        
  211.   Timer0Init();
  212.         while(1)
  213.         {        
  214.                 KeyDown();
  215.                 Score();                                       
  216.                 Conut();                    //分离出数
  217.                 fengMQ();                                //*蜂鸣器
  218.                 DigDisplay();                  //数码管显示函数        
  219.         }               
  220. }

  221. void Timer0() interrupt 1   //中断程序
  222. {
  223.         static u16 q;          //定义变量q,1s=50ms*20
  224.         TH0 = 0x3C;            //设置初始值,定时50MS
  225.   TL0 = 0xB0;
  226.         q++;
  227.         if(q==20)      //计时20次时为1秒
  228.         {
  229.         q=0;           //变量q置零
  230.         if(n==0)       //当倒计时秒针为0时,分针减一,秒针为59
  231.                 {
  232.                   n=60;
  233.                   m=m-1;
  234.                 }
  235.         n=n-1;        //每秒减一
  236.         }
  237.         if(m==0&&n==0)  //一节结束定时器停止,时间重置12:00;
  238. {
  239.          TR0 =0;
  240. }        
  241. }
复制代码


正在重新握手 ... 成功                        [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

操作成功 !


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表