zoukankan      html  css  js  c++  java
  • 基于51单片机控制的篮球比赛计时、计分系统设计与仿真(含设计图和C语言程序源码)

    1. 设计任务:

    本次设计用由AT89C51编程控制LED七段数码管作显示的球赛计时计分系统。系统应具有赛程定时设置,赛程时间暂停,及时刷新甲、乙双方的成绩以及赛后成绩暂存等功能。
    内容包括:显示、键盘、时钟等内容

    2. 设计说明

    2.1 需求分析

    2.1.1 计分系统:

    (1)分为“A队”和“B队”的“3分”,“2分”,“1分”各六个按键输入部分,以及两队比分的LED显示部分。在每次增加分数的同时,“24秒”计时恢复为初始值,“12分钟”计时暂停,等待比赛的继续进行

    2.1.2 计时系统:

    (1)比赛开始/继续:当“比赛开始/继续”键按下后,“24s”和“12分钟”计时器开始倒计时;
    (2)手动24s复位:当“24s复位” 键按下后,“24s”倒计时恢复初始值,“12分钟”倒计时暂停,等待比赛的继续;
    (3)比赛暂停:“比赛暂停”键按下后,“24s”倒计时和“12分钟”倒计时均暂停,等待比赛的继续进行;
    (4)自动增加比赛节数:当“12分钟”倒计时完成后,判断当前节数是否为最后一节,若不是,则节数自动增加,并“12分钟”和“24s”均恢复默认值,等待下一节比赛的进行。

    2.2 原理分析

    采用单片机AT89C51作为本设计的核心元件。利用7段共阴LED作为显示器件。在此设计中共接入了6个7段共阴LED显示器,其中2个4位LED显示器用于记录AB队的分数,每队1个4位LED显示器显示范围可达到0~999分,足够满足赛程需要;2个两位LED显示器用来记录赛程时间,其中1个用于显示分钟,1个用于显示秒钟;使用1个2位LED显示器用于显示“24s”倒计时,赛程计时均采用倒计时方式。即比赛前将时间设置好,即12分钟,比赛开始时启动计时,直至计时到零为止。本设计中设立了10个按键,其中6个用于设置两队的比分,1个用于比赛开始/比赛继续,1个用于暂停,1个用于手动增加比赛节数,一个用于恢复“24s”倒计时等功能。

    2.3 总体设计

    系统主要包括单片机、LED显示电路、按键控制电路、时钟电路及复位电路等组成

    2.4 软硬件设计

    2.4.1 硬件设计

    设计思路:
    (1)按键模块设计 :
    按键接至P1口和P3口,按键按下时输入是低电平。键的设置如下:“A1”,“A2”,“A3”键是A队加1分、加2分,加3分键盘,B队同理。“比赛开始/比赛继续”是启动键,“比赛暂停”是暂停键。此外,还有两个按键, “24s”复位键,“增加比赛节数”键。
    (2) LED显示模块设计 :
    显示分为计时和计分显示两个部分,均采用共阴极LED数码管动态扫描显示,由2个四位一体和4个两位一体的共阴极数码管构成。数码管的7个段控端输出经过74HC573驱动器进行电流放大驱动接至P0口。采用动态扫描方式,在足够短的周期内,使各位数码管逐个轮流受控显示。

    设计截图:
    设计截图

    2.4.2 软件设计

    软件设计采用C语言模块设计方法,程序由主程序、T0中断程序、显示程序、外部中断0程序、按键程序、初始函数、计时函数、延时函数组成。

    C语言程序代码:

    #include<reg52.h>
    #include<absacc.h>
    
    #define uchar unsigned char 
    #define uint unsigned int
    
    sbit A8=P2^0;  
    sbit A9=P2^1;
    sbit A10=P2^2;
    sbit A11=P2^3;
    sfr P00=0x80;
    
    
    uchar code wei_1[]={0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80};
    uchar code table[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0x77,0x7c,0x39,0x5e,0x79,0x71,0X00,0X40};
    
    uchar minute=12;  //分
    uchar second=0;   //秒
    uchar key_status=0;     //按键状态值
    uchar scoreA=0;     //A队得分
    uchar scoreB=0;     //B队得分
    uchar count1=20;    //记录定时器时间
    uchar match=1;      //比赛节数
    uchar rule_time=24; //记录24秒规则
    uchar rule_flag=0;          //记录24秒规则是否启用
    
    
    /*
    初始化IO口
    */
    void IO_init(){
        A8=0;
        A9=0;
    }
    /*
    初始化时间
    */
    
    void time_init(){
        TMOD = 0x01;
        TH0 = (65536-50000)/256;
        TL0 = (65536-50000)%256; 
        EA = 1;
        ET0 = 1;
    }
    /*
    延时函数
    */
    void delay_ms(uint z){
      uint i;
        uchar j;
        for(i=0;i<z;i++){
    
            for(j=0;j<100;j++);
        }
    }
    
    /*
    计时函数
    */
    void T0_Time() interrupt 1 using 1{
        if (count1-- == 0) 
        {
            second--;
            rule_time--;
            count1 = 20; 
        }
        TH0 = (65536-50000)/256;
        TL0 = (65536-50000)%256;
    }
    
    /*
    时间显示函数
    */
    void time_display(uchar w2,uchar d2){
        uchar shi1,ge1;
        shi1=d2/10;
        ge1=d2%10;
    
        P00=wei_1[w2];
        A10=1;
        A10=0;
        P00=table[shi1];;
        A8=1;
        A8=0;
        delay_ms(5);
        P00=0;
        A10=1;
        A10=0;
        A8=1;
        A8=0;
    
        P00=wei_1[w2+1];
        A10=1;
        A10=0;
        P00=table[ge1];
        A8=1;
        A8=0;
        delay_ms(5);
        P00=0;
        A10=1;
        A10=0;
        A8=1;
        A8=0;   
    }
    
    /*
    分数显示函数
    */
    void score_dispaly(uchar w2,uchar d2){
        uchar qian2,shi2,ge2;
        qian2=d2/100;
        shi2=d2%100/10;
        ge2=d2%100%10;
    
        P00=wei_1[w2];
        A9=1;
        A9=0;
        P00=table[qian2];;
        A8=1;
        A8=0;
        delay_ms(10);
        P00=0;
        A9=1;
        A9=0;
        A8=1;
        A8=0;
    
        P00=wei_1[w2+1];
        A9=1;
        A9=0;
        P00=table[shi2];
        A8=1;
        A8=0;
        delay_ms(10);
        P00=0;
        A9=1;
        A9=0;
        A8=1;
        A8=0;   
    
        P00=wei_1[w2+2];
        A9=1;
        A9=0;
        P00=table[ge2];
        A8=1;
        A8=0;
        delay_ms(10);
        P00=0;
        A9=1;
        A9=0;
        A8=1;
        A8=0;
    }
    
    /*
    键盘输入函数
    */
    void key(){
        static uchar key_new = 0, key_l,temp;
        key_status = 0;                  
        P1 = 0x0f;
        if((P1 & 0x0f) != 0x0f)     
        {
            delay_ms(1);            
            if(((P1 & 0x0f) != 0x0f) && (key_new == 1))
            {                       
                key_new = 0;
                /*
                矩阵键盘扫描
                */
                key_l = (P1 | 0xf0);   
                P1 = key_l;
                switch(P1)
                {
                    /*
                    开始计时/比赛继续   
                    */
                    case 0x7e:  
                        TR0=1;  
                        rule_flag=1;
                        time_display(6,rule_time);
                        break;      
                    /*
                    暂停比赛
                    */
                    case 0x7d:
                        TR0=0;
                        break;  
    
                    /*
                    加分,同时24秒清零和总计时器停止计时
                    */
                    case 0xee: 
                        TR0=0; 
                        scoreA +=3;
                        rule_time=24;   
                        rule_flag=0;
                        break;
                    case 0xed: 
                        TR0=0;                  
                        scoreA +=2;
                        rule_time=24;   
                        rule_flag=0;
                        break;
                    case 0xeb:  
                        TR0=0; 
                        scoreA +=1;
                        rule_time=24;   
                        rule_flag=0;
                        break;
                    case 0xde:  
                        TR0=0; 
                        scoreB +=3;
                        rule_time=24;   
                        rule_flag=0;
                       break;
                    case 0xdd:  
                        TR0=0; 
                        scoreB +=2;
                        rule_time=24;   
                        rule_flag=0;
                        break;
                    case 0xdb:  
                        TR0=0; 
                        scoreB +=1;
                        rule_time=24;   
                        rule_flag=0;
                        break;
                    /*
                    增加比赛节数,同时24秒复位和总计时器复位
                    */
                    case 0xbd:
                        match++;
                        minute=12;
                        second=0;
                        TR0=0; 
                        rule_time=24;   
                        rule_flag=0;
                        break;
                    /*
                    手动24秒复位
                    */
                    case 0xbe:
                        if(TR0==1){
                                rule_time=0;   
                                rule_flag=0;
                        }else{
                                rule_flag=0;  
                        }
                        break;
                }   
            }           
        }
        else 
        {
            key_new = 1;
        }
    }
    
    void main()
    {
        IO_init();
        time_init();
        while(1){
            key();
    
            if(second==0){
                /*
                    判断某节比赛是否结束
                */
                if(minute==0){ 
                    /*
                    判断是否为最后一节比赛
                    */
                    if(match<4){
                        /*
                        计时系统恢复为默认值,比赛节数加一
                        */
                        second=60;
                        minute=11;
                        match++;
                        rule_time=24;   
                        rule_flag=0;
                    }   
                    TR0=0;
                }
                /*
                比赛分钟数减一
                */
                else {  
                    second=60;
                    minute--;
                }               
            }
            /*
            24秒结束,计时器暂停和24秒复位
            */
            if(rule_time<=0){
                TR0=0;
                rule_time=24;   
            }
    
            /*
            显示
            */
            time_display(0,minute);
            time_display(2,second);
            time_display(4,match);
            time_display(6,rule_time);
            score_dispaly(1,scoreA);
            score_dispaly(5,scoreB);
        }
    }

    2.5 方案论证及可行性分析

    本设计以单片机AT89C51为核心的控制电路实现了计时计分、计时的功能,设计中,使用大尺寸数码管的制造构思巧妙和软件设计,降低了整个系统的成本,实现了多用途的目的。通过仿真和实物实验验证了该系统的正确性和实用性。系统电路制造简单,显示清晰,成本低廉。

    2.6 测试结果与分析

    设计采用C语言编程,在Keil C51软件编译环境中,经过编译和连接,生成十六进制的目标代码文件.hex。在硬件上,用Proteus软件绘制出原理图,经过纯电路调试无误后,将生成的目标代码文件加载到Proteus界面的AT89C51中。接着再进行软硬件联合调试,反复调试,直至所有显示及按键功能实现,直至仿真成功。

    运行截图:

    这里写图片描述

    2.7 参考文献:

    [1] 胡辉. 单片机原理与应用[M].北京:中国水利水电出版社,2007.
    [2] 戴佳. 51单片机C语言应用程序设计实例精讲[M].北京:电子工业出版社,2006.

    3. 设计文件以及源码下载

    CSDN下载地址
    或者关注博主公众号,回复:篮球计时器即可下载,还有更多资源分享哦~

    扫码关注作者个人技术公众号,有关技术问题后台回复即可,不定期将有学习资源分享
    这里写图片描述

  • 相关阅读:
    团队里A和B吵架了,经理M该干啥?
    一个程序员的哲学思考(关于编程、关于人生)
    程序员在大学里究竟应该学习什么?
    如何检查自己是否平庸?
    关于如何读代码?
    老说技术更迭快,可十年到底可以淘汰多少知识?
    现代软件工程里的困惑
    略谈各国企业的差异
    Silverlight4Beta之操作摄像头/麦克风
    Silverlight4Beta之Binding新特性(下)
  • 原文地址:https://www.cnblogs.com/newtol/p/10159101.html
Copyright © 2011-2022 走看看