找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 144|回复: 0
打印 上一主题 下一主题
收起左侧

篮球计分器 单片机程序

[复制链接]
跳转到指定楼层
楼主
ID:918728 发表于 2025-4-10 09:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include<reg51.h>//51单片机头文件
  2. typedef unsigned char uchar;
  3. typedef unsigned int  uint;
  4. sbit K1=P3^2;//比赛倒计时开始/暂停
  5. sbit K2=P3^3;//24s倒计时重新开始
  6. sbit K3=P1^3;//乙队+1按键
  7. sbit K4=P1^2;//乙队+2按键
  8. sbit K5=P1^1;//甲队+1按键
  9. sbit K6=P1^0;//甲队+2按键
  10. sbit K7=P1^4;//乙队+3按键
  11. sbit K8=P1^5;//甲队+3按键
  12. sbit K9=P1^6;//半场积分互换
  13. sbit K10=P1^7;//分数清0
  14. sbit K11=P2^1;//乙队-1按键
  15. sbit K12=P2^2;//甲队-1按键

  16. sbit K13=P2^3;//乙队犯规按键
  17. sbit K14=P2^4;//甲队犯规按键
  18. sbit LED1=P2^6;//乙队犯规灯
  19. sbit LED2=P3^4;//乙队犯规灯

  20. sbit LED3=P3^0;//甲队犯规灯
  21. sbit LED4=P3^1;//甲队犯规灯

  22. sbit K15=P3^5;//乙队犯规清0按键
  23. sbit K16=P3^6; //甲队犯规清0按键


  24. sbit beep=P2^0;//蜂鸣器接口  
  25. sbit RS=P2^7;
  26. sbit E=P2^5;
  27. char miao,fen,num,time,aa;
  28. uchar bb,cc,tt;
  29. uchar code table1[]={"H.T 000:000 R.T "};
  30. uchar code table2[]={"10:00  SEC-1  24"};

  31. bit key_pressed = 0;              // 按键按下标志
  32. bit key_pressed1 = 0;              // 按键按下标志
  33. unsigned char led_state = 0; // LED状态: 0=都灭, 1=LED1亮, 2=都亮
  34. unsigned char led_state1 = 0; // LED状态: 0=都灭, 1=LED1亮, 2=都亮
  35. //延时子函数
  36. void delay(uint z)  
  37. {
  38.         uint x;
  39.         uchar y;
  40.         for(x=z;x>0;x--)
  41.                   for(y=110;y>0;y--);
  42. }

  43. //LCD1602液晶写指令子函数
  44. void write_com(uchar com)
  45. {
  46.         RS=0;
  47.         P0=com;
  48.         delay(5);
  49.         E=1;
  50.         delay(5);
  51.         E=0;
  52. }

  53. //LCD1602液晶写数据子函数
  54. void write_date(uchar date)
  55. {
  56.         RS=1;
  57.         P0=date;
  58.         delay(5);
  59.         E=1;
  60.         delay(5);
  61.         E=0;
  62. }

  63. //LCD1602液晶初始化子函数
  64. void LCD1602_init()
  65. {
  66.         uchar i;
  67.         bb=0;    //H.T分数初始化
  68.         cc=0;    //R.T分数初始化
  69.         time=0;
  70.         TMOD=0x10;    //定时器1初始化
  71.         TL1=0x00;
  72.         TH1=0x4c;
  73.         EA=1;     //开总中断
  74.         ET1=1;     //开定时器1
  75.         TR1=0;     //定时器1不工作
  76.         EX0=1;     //开中断0
  77.         EX1=1;     //开中断1
  78.         IT0=1;     //中断0为边沿触发
  79.         IT1=1;     //中断1为边沿触发
  80.         E=0;
  81.         beep=0;
  82.         miao=0;
  83.         fen=10;
  84.         num=1;
  85.         aa=24;
  86.         write_com(0x38);  //LCD设置初始化
  87.         write_com(0x0c);
  88.         write_com(0x06);
  89.         write_com(0x01);
  90.         write_com(0x80);  //LCD显示初始化
  91.         for(i=0;i<16;i++)
  92.         {
  93.                   write_date(table1[i]);
  94.         }
  95.         write_com(0x80+0x40);
  96.         for(i=0;i<16;i++)
  97.         {
  98.                   write_date(table2[i]);
  99.         }
  100. }
  101. //分数更新子函数
  102. void point_lcd(uchar add,uchar dat)
  103. {
  104.         write_com(0x80+add);
  105.         write_date(0x30+dat/100);
  106.         write_date(0x30+(dat%100)/10);
  107.         write_date(0x30+dat%10);
  108.         write_com(0x80+add);
  109. }
  110. //按键扫描子函数
  111. void keyscan()
  112. {
  113.         if(K3==0)     //K3按下H.T分数加一
  114.         {
  115.                   while(K3==0);
  116.                 bb++;
  117.                   point_lcd(0x04,bb);  //分数显示更新
  118.                   if(K3==0)    //松手检测
  119.                   {
  120.                            while(K3==0);
  121.                            delay(20);
  122.                   }
  123.         }

  124.         else if(K4==0)    //K4按下H.T分数加二
  125.         {
  126.                   while(K4==0);
  127.                 bb=bb+2;
  128.                   point_lcd(0x04,bb);
  129.                   if(K4==0)
  130.                   {
  131.                            while(K4==0);
  132.                            delay(20);
  133.                   }
  134.         }
  135.         else if(K7==0)          //K7按下H.T分数加3
  136.         {
  137.                 while(K7==0);
  138.                 bb=bb+3;
  139.                   point_lcd(0x04,bb);
  140.                   if(K7==0)
  141.                   {
  142.                            while(K7==0);
  143.                            delay(20);
  144.                   }
  145.         }

  146.         else if(K5==0)    //K5按下R.T分数加一
  147.         {
  148.                   while(K5==0);
  149.                 cc++;
  150.                   point_lcd(0x08,cc);
  151.                   if(K5==0)
  152.                   {
  153.                            while(K5==0);
  154.                            delay(20);
  155.                   }
  156.         }
  157.         else if(K6==0)    //K6按下R.T分数加2
  158.         {
  159.                   while(K6==0);
  160.                 cc=cc+2;
  161.                   point_lcd(0x08,cc);
  162.                   if(K6==0)
  163.                   {
  164.                            while(K6==0);
  165.                            delay(20);
  166.                   }
  167.         }
  168. else if(K8==0)          //K9按下R.T分数加3
  169.         {
  170.                 while(K8==0);
  171.                 cc=cc+3;
  172.                   point_lcd(0x08,cc);
  173.                   if(K8==0)
  174.                   {
  175.                            while(K8==0);
  176.                            delay(20);
  177.                   }
  178.         }

  179. else if(K10==0)          //K10按下分数清0
  180.         {
  181.                 while(K10==0);
  182.                 bb=0;
  183.                 cc=0;
  184.                   point_lcd(0x04,bb);               
  185.                   point_lcd(0x08,cc);
  186.                   if(K10==0)
  187.                   {
  188.                            while(K10==0);
  189.                            delay(20);
  190.                   }
  191.         }        
  192.         else if(K9==0)    //K9半场场地互换,积分互换
  193.         {                                          
  194.                                 while(K9==0);
  195.                 {
  196. //                        uchar code table3[]={"R.T 000:000 H.T "};
  197.                         tt=bb;bb=cc;cc=tt;
  198.                 }
  199.                         point_lcd(0x04,bb);
  200.                   point_lcd(0x08,cc);
  201.                 if(K9==0)
  202.                 {
  203.                         while(K9==0);
  204.                         delay(20);
  205.                 }
  206.         }

  207.         if(K13 == 0)       //K13乙队犯规按键
  208.         {
  209.                         delay(10);  // 消抖延时
  210.                         if(K13 == 0 && !key_pressed) {
  211.                                         key_pressed = 1;  // 设置按键按下标志
  212.                                        
  213.                                         // 根据当前状态切换LED
  214.                                         if(led_state == 0) {
  215.                                                         LED1 = 1;     // 点亮第一个LED
  216.                                                         led_state = 1;
  217.                                         }
  218.                                         else if(led_state == 1) {
  219.                                                         LED2 = 1;    // 点亮第二个LED
  220.                                                         led_state = 2;
  221.                                         }
  222.                                         // 当led_state == 2时不做任何操作
  223.                         }
  224.         } else {
  225.                         key_pressed = 0;  // 按键释放,清除标志
  226.         }

  227.         if(K14 == 0)       //K13甲队犯规按键
  228.         {
  229.                         delay(10);  // 消抖延时
  230.                         if(K14 == 0 && !key_pressed1) {
  231.                                         key_pressed1 = 1;  // 设置按键按下标志
  232.                                        
  233.                                         // 根据当前状态切换LED
  234.                                         if(led_state1 == 0) {
  235.                                                         LED3 = 1;     // 点亮第一个LED
  236.                                                         led_state1 = 1;
  237.                                         }
  238.                                         else if(led_state1 == 1) {
  239.                                                         LED4 = 1;    // 点亮第二个LED
  240.                                                         led_state1 = 2;
  241.                                         }
  242.                                         // 当led_state == 2时不做任何操作
  243.                         }
  244.         } else {
  245.                         key_pressed1 = 0;  // 按键释放,清除标志
  246.         }

  247.         if(K15==0)     //K15按下乙队犯规清0
  248.         {
  249.                   while(K15==0);
  250.       LED1=0;
  251.       LED2=0;               
  252.                   if(K15==0)    //松手检测
  253.                   {
  254.                            while(K15==0);
  255.                            delay(20);
  256.                   }
  257.         }

  258.         if(K16==0)     //K15按下乙队犯规清0
  259.         {
  260.                   while(K16==0);
  261.       LED3=0;
  262.       LED4=0;               
  263.                   if(K16==0)    //松手检测
  264.                   {
  265.                            while(K16==0);
  266.                            delay(20);
  267.                   }
  268.         }        
  269.         
  270. }

  271. //比赛倒计时/24s倒计时
  272. void counter_down()
  273. {
  274.         uchar i;
  275.         if(time>=20)     //每1s倒计时做减一操作
  276.         {
  277.                   miao--;
  278.                   aa--;
  279.                   write_com(0x80+0x4e);  //24s倒计时显示
  280.                   write_date(0x30+aa/10);
  281.                   write_date(0x30+aa%10);
  282.                 write_com(0x80+0x4e);
  283.                   if(aa==0)    //24s结束发出3s连续报警
  284.                   {
  285.                            beep=1;
  286.                            delay(3000);
  287.                            beep=0;
  288.                            aa=24;
  289.                   }
  290.                   if((miao==0)&&(fen==0))  //检测一节比赛是否结束
  291.                   {
  292.                            TR1=0;     //定时器1暂停
  293.                            write_com(0x80+0x44);
  294.                            write_date(0x30);
  295.                            num++;
  296.                            aa=24;    //24s计时复位
  297.                            write_com(0x80+0x4e);  //24s倒计时显示
  298.                            write_date(0x30+aa/10);
  299.                            write_date(0x30+aa%10);
  300.                         write_com(0x80+0x4e);
  301.                            if(num<5)    //每节结束蜂鸣器发出8s的间断报警
  302.                            {
  303.                             for(i=80;i>0;i--)
  304.                             {
  305.                                      beep=1;
  306.                                      delay(500);
  307.                                      beep=0;
  308.                                      delay(500);
  309.                             }
  310.                            }
  311.                            if(num==5)    //终场结束,蜂鸣器发出10s的连续警报声
  312.                            {
  313.                              beep=1;
  314.                              delay(10000);
  315.                              num=0;
  316.                            }        


  317.                            beep=0;     //蜂鸣器关闭
  318.                         write_com(0x80+0x4b); //更新"SEC-?"
  319.                         write_date(0x30+num);
  320.                         write_com(0x80+0x4b);
  321.                         miao=0;     //倒计时复位
  322.                         fen=10;
  323.                   }
  324.                   if(miao<=0)
  325.                   {
  326.                            miao=59;
  327.                            fen--;
  328.                   }
  329.                   write_com(0x80+0x40);  //更新倒计时显示
  330.                   write_date(0x30+fen/10);
  331.                   write_date(0x30+fen%10);
  332.                   write_com(0x80+0x43);
  333.                   write_date(0x30+miao/10);
  334.                   write_date(0x30+miao%10);
  335.                 write_com(0x80+0x43);
  336.                   time=0;
  337.         }
  338. }

  339. //主函数
  340. void main()
  341. {
  342.         LCD1602_init();
  343.         LED1 = 0;  // 初始关闭LED1
  344.         LED2 = 0;  // 初始关闭LED2        
  345.         LED3 = 0;  // 初始关闭LED1
  346.         LED4 = 0;  // 初始关闭LED2                        
  347.         while(1)
  348.         {
  349.                   keyscan();  //分数按键检测
  350.         }
  351. }

  352. //外部0中断子函数
  353. void wb0() interrupt 0  //比赛时间开始/暂停
  354. {
  355.         TR1=~TR1;     //定时器1工作/暂停
  356.         if(TR1==1)  //当倒计时工作时,S1按下定时器立即停止工作
  357.         {
  358.                   PT1=0;
  359.         }
  360.         else   //倒计时不工作时,S1按下倒计时立即工作
  361.         {
  362.                   PT1=1;
  363.         }
  364.         if(K1==0)     //松手检测
  365.         {
  366.                   while(K1==0);
  367.                    counter_down();
  368.           //        delay(20);
  369.         }
  370. }

  371. //外部1中断子函数
  372. void wb1() interrupt 2   //24s倒计时重新开始
  373. {
  374.         aa=24;
  375.         write_com(0x80+0x4e);   //24s倒计时显示
  376.         write_date(0x30+aa/10);
  377.         write_date(0x30+aa%10);
  378.         write_com(0x80+0x4e);
  379.         if(K2==0)      //松手检测
  380.         {
  381.                   while(K2==0)
  382.                   {
  383.                            counter_down();
  384.                   }
  385.                   delay(20);
  386.         }
  387. }
  388. //定时器1中断子函数
  389. void t1() interrupt 3   //定时器1中断20次为1s
  390. {
  391.         time++;
  392.         TL1=0x00;
  393.         TH1=0x4c;
  394.         counter_down();     //倒计时
  395. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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