找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机比赛计分器Proteus仿真与代码

[复制链接]
跳转到指定楼层
楼主
1、总设计框图

2、硬件仿真图

3、主函数和定时器代码

数码管倒计时设计

中断控制程序


单片机源程序如下:
  1. #include<reg51.h>
  2. typedef unsigned char uchar;
  3. typedef unsigned int  uint;
  4. uchar code seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};  
  5. //对应数码管显示数字0-9
  6. int u_m=20,u_n=0,u_x=0,u_y=0,u_i=0,h=0,k;
  7. //定义全局变量并初始化,m,n表示分钟与秒,x,y表示A,B两队分数
  8. sbit P1_0=P1^0;
  9. sbit P1_1=P1^1;
  10. sbit P1_2=P1^2;
  11. sbit P1_3=P1^3;
  12. sbit P3_2=P3^2;
  13. sbit P3_3=P3^3;
  14. sbit P3_6=P3^6;
  15. sbit P3_7=P3^7;
  16. void delay(uint x)//定义延时程序,通过设置参数x,改变延时时间长度
  17. {
  18.         while(x--)
  19.         {
  20.                 uint y;
  21.                 for(y=0;y<200;y++);
  22.         }
  23. }
  24. /*显示子程序,变量i,j分别是分秒,变量x,y是A,B两队的分数*/
  25. void display(int u_i,int u_j,int u_x,int u_y)
  26. {               
  27.         P2=~0xfe;   //刷新数码管显示时间的分钟十位,调用延时程序                              
  28.         P0=~seg[u_i%100/10];
  29.         delay(1);                        //延时数码管点亮               
  30.         P2=0x00;
  31.         P0=0xff;
  32.         P2=~0xfd;        //刷新刷管分钟位的个位                                
  33.         P0=~seg[u_i%10];
  34.         delay(1);
  35.         P2=0x00;
  36.         P0=0xff;
  37.         P2=~0xfb;        //刷新数码管秒位的十位               
  38.         P0=~seg[u_j%100/10];
  39.         delay(1);
  40.         P2=0x00;
  41.         P0=0xff;
  42.         P2=~0xf7;        //刷新数码管秒位的个位               
  43.         P0=~seg[u_j%10];
  44.         delay(1);
  45.         P2=0x00;
  46.         P0=0xff;
  47.         P2=~0xef;        //刷新数码管A对分数的十位                        
  48.         P0=~seg[u_x%100/10];
  49.         delay(1);
  50.         P2=0x00;
  51.         P0=0xff;
  52.         P2=~0xdf;        //刷新数码管A对分数的个位                        
  53.         P0=~seg[u_x%10];
  54.         delay(1);
  55.         P2=0x00;
  56.         P0=0xff;
  57.         P2=~0xbf;        //刷新数码管B队分数的十位               
  58.         P0=~seg[u_y%100/10];
  59.         delay(1);
  60.         P2=0x00;
  61.         P0=0xff;
  62.         P2=~0x7f;        //刷新数码管B队分数的个位        
  63.         P0=~seg[u_y%10];
  64.         delay(1);
  65.         P2=0x00;
  66.         P0=0xff;
  67. }
  68. void t0() interrupt 1 //定义中断程序,调用定时器T0
  69. {  
  70.         TH0=0xb1;                                //对定时器T0送入初值,TH0=0xb1   
  71.         TL0=0x10;                                //TL0=0X10定时器定时为20ms
  72.         if(u_n<0)                                        //每20ms调用一次
  73.         {
  74.                 u_n=59;
  75.                 u_m--;
  76.                
  77.         }
  78.         u_i++;
  79.         if(u_i==50)                        //定义I为50,50*20ms=1s
  80.         {
  81.                 u_n--;
  82.                 u_i=0;
  83.         }
  84.         display(u_m,u_n,u_x,u_y);//调用数码管显示程序,每20ms刷新
  85. }
  86. void int0() interrupt 0 //外部中断0的控制程序,每次按键按下,加2操作
  87. {u_x+=2;if(u_x>98)u_x=98;}
  88. void int1() interrupt 2 //外部中断1的控制程序,每次按键按下,加2操作
  89. {u_y+=2;if(u_y>98)u_y=98;}
  90. void timing()                                                        //定义调时程序
  91. {
  92. if(P1_2==0)                                                //当按下P1_2时
  93. {
  94. delay(1);                                        //延时消抖
  95. if(P1_2==0)
  96. {
  97. u_n++;                        //秒位加1
  98. if(u_n==60)//当秒位到60时
  99. {
  100. u_m++;//分位加1,秒变1
  101. u_n=1;
  102. }
  103. }
  104. }if(P1_3==0)                                                //当按下P1_3时
  105. {
  106. delay(1);        
  107. if(P1_3==0)
  108. {
  109. u_n--;//秒位减1
  110. if(u_n<0)                  //当秒位减到0时,分位减1,秒位变59
  111. { u_n=59;
  112.         u_m--;        
  113.         
  114. }}}}
  115. void exchange()                                                  //定义比分交换程序
  116. {
  117.         int u_t;                                                          //定义中间变量
  118.         if(P1_1==0)                                                  //当P1_1按下时
  119.         {
  120.                 delay(1);                                          //延时消抖
  121.                 while(P1_1==0);
  122.                 u_t=u_x;                                        //利用中间变量t,将A,B两队比分交换
  123.                 u_x=u_y;
  124.                 u_y=u_t;
  125.                 display(u_m,u_n,u_x,u_y);                        //刷新数码管
  126.         }
  127. }
  128. void suspend()                                                        //定义暂停程序
  129. {
  130.         if(P1_0==0)                                                                //当按下P1_0时
  131.         {
  132.         delay(1);                                                  //延时消抖
  133.         while(P1_0==0);
  134.         EA=0;                                                          //关中断,进入死循环
  135.         while(1)
  136.         {
  137.         display(u_m,u_n,u_x,u_y);
  138.         if(P1_0==0)                //当再次按下P1_0时,跳出死循环
  139.         {        
  140.         delay(1);
  141.         while(P1_0==0)
  142.         EA=1;
  143.         break;        
  144.         }}}}
  145. void alertor()                                                 //定义报警程序
  146. {  
  147.         if(((u_m==0)&&(u_n==0))|(P3_2==0)|(P3_3==0)|(P1_0==0)|(P1_1==0)|(P1_2==0)|(P1_3==0))
  148.         {
  149.                 P3_7=1;                                
  150.                 P3_6=1;//P3_7和P3_6间隔输出高低电平,使蜂鸣器响
  151.                 delay(5);
  152.                 P3_7=0;
  153.                 P3_6=0;
  154.                 delay(5);
  155.         }
  156. }
  157. void conclude()                                                //定义结束子程序
  158. {
  159.         M:        if(h==1)                        //当时间条件满足时,关闭中断,使数码管保持状态显示
  160. {
  161.         EA=0;
  162.         delay(20);
  163.   u_m=0;
  164.         u_n=0;
  165.         P3_6=1;
  166.         P3_7=1;
  167.         delay(200);
  168.         P3_7=0;
  169.         P3_6=0;
  170.         while(1)
  171.         {
  172.          display(u_m,u_n,u_x,u_y);
  173.          exchange();
  174.          if(P1_0==0)                        //当P1_0再次按下时,跳出循环
  175.         {                     
  176.                 delay(1);
  177.                 while(P1_0==0)  
  178.         {
  179.                 EA=1;
  180.                 u_m=20;    //重新赋予初始值,开始比赛
  181.                 u_n=0;
  182.                 h=0;
  183.                 goto M ;
  184.         }               
  185.         }
  186.         }
  187. }
  188. }
  189. void main()                                                                //定义主程序
  190. {
  191. EX0=1;//外部中断0的分开关打开
  192. EX1=1;//外部中断1的分开关打开
  193. IT0=1;//外部中断0为下降沿触发
  194. IT1=1;//外部中断1为下降沿触发
  195. PX1=1;//外部中断1为高优先级
  196. PX0=0;//外部中断0为低优先级
  197.         TMOD=0x01;                                                         //初始化程序
  198.         EA=1;        //开关总中断打开                        
  199.         ET0=1;
  200.         P3_7=0;
  201.         P0=0xff;
  202.         P2=0x00;
  203.         if(P1_0==0)                //第一次按下P1_0,单片机启动,显示初始值
  204.         {                                                          //由于调用了一次暂停功能,会显示初始值
  205.                 TH0=0xb1;
  206.                 TL0=0x10;
  207.                 TR0=1;                                                                //启动定时器
  208.                 P3=0xff;         
  209.                 P1=0x7f;
  210.                 P3_7=0;
  211.                 while(1)
  212.                 {                        
  213.                         timing();                            //调时子程序
  214.                         exchange();                       //比分交换程序
  215.                         suspend();                           //暂停程序
  216.                         alertor();                           //报警程序
  217.                         if((u_m==0)&&(u_n==1))           //判断子程序结束调用条件
  218.                         {
  219.                                 h=1;
  220.                         }
  221.                         conclude();                              //结束子程序
  222.                 }
  223.         }
  224. }
复制代码

仿真代码51hei附件下载:
仿真程序.7z (61.93 KB, 下载次数: 47)

评分

参与人数 1黑币 +30 收起 理由
admin + 30 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:986694 发表于 2021-12-2 15:16 | 只看该作者
此帖仅作者可见

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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