|
这些是我自己做的
这张是应该成功后的
我自己做的C和仿真
新建文件夹 (3).rar
(17.83 KB, 下载次数: 27)
这是我自己照着打出来的
单片机源程序:
- #include<reg51.h>
- #define uint unsigned int
- #define uchar unsigned char
- code unsigned seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- int m=1,n=60,x=0,y=0,i=0,jie=2,zidong=1,bujin=1,zanting=0,chuzanting=0;
- sbit P1_1=P1^1;
- sbit P1_2=P1^2;
- sbit P1_3=P1^3;
- sbit P1_4=P1^4;
- sbit P1_5=P1^5;
- sbit P1_6=P1^6;
- sbit P1_7=P1^7;
- sbit k1=P3^0; //A+1
- sbit k2=P3^1; //B+1
- sbit k3=P3^2; //回表按键
- sbit k4=P3^3; //时间快进
- sbit k5=P3^4; //A-1
- sbit k6=P3^5; //B-1
- sbit P1_0=P1^0; //暂停、启动
- //#include <REGX51.H>为头文件P1口各位分别用P1_0等表示
- void delay(int t) // 延时子程序 通过参数t,可以调整暂停时间
- {
- while(t--)
- {
- unsigned int i;
- for(i=0;i<200;i++);
- }
- }
-
- void display(int i,int j,int x,int y) // 数码管动态刷新显示程序
- {
- if(jie==1&&bujin!=2) //中间变量jie==1时,为上半场,对P1赋值
- P1=0xbf; //P1=0xbf, 即P1=1011 1111B,点亮对应上半场指示灯
-
- P2=0xfe; //数码管动态刷新显示程序 P2=1111 1110,i为分钟
- P0=seg[i%100/10]; //刷新显示时间显示分钟十位,调用延时程序,
- delay(1); //延时数码管的点亮
- P2=0xff;
- P0=0;
- P2=0xfd; //同理,动态刷新时分钟个位并延时点亮
- P0=seg[i%10];
- delay(1);
- P2|=0xff;
- P0=0;
- P2=0xfb; //同理,动态刷新时秒钟十位并延时点亮
- P0=seg[j%100/10];
- delay(1);
- P0=0;
- P2=0xff;
- P2=0xf7; //同理,动态刷新时秒钟个位并延时点亮
- P0=seg[j%10];
- delay(1);
- P0=0;
- P2=0xff;
- P2=0xef; //同理,动态刷新甲队分数十位并延时点亮
- P0=seg[x%100/10];
- delay(1);
- P2=0xff;
- P0=0;
- P2=0xdf; //同理,动态刷新甲队分数个位并延时点亮
- P0=seg[x%10];
- delay(1);
- P2=0xff;
- P0=0;
-
- P2=0xbf; //同理,动态刷新乙队分数十位并延时点亮
- P0=seg[y%100/10];
- delay(1);
- P0=0;
- P2=0xff;
- P2=0x7f; //同理,动态刷新乙队分数十位并延时点亮
- P0=seg[y%10];
- delay(1);
- P0=0;
- P2=0xff;
- }
- void t0(void) interrupt 1 //调用定时器T0 基本计时单位秒
- { TH0=0xb1; //利用定时器T0,送入计数初值TH0=0xb1; TL0=0x10;
- TL0=0x10; //定时器定时单位为20毫秒
- if(n==0)
- { //分钟与秒时间调整 当秒减到0以后分钟减1
- n=60;m--;
- }
- i++;
- if(i==50)
- { //利用中间变量i 令i值为50 50*20毫秒=1秒
- n--; //以实现一秒计时
- i=0;
- }
- display(m,n-1,x,y); //调用动态刷新显示程序
- }
- void keyjiafen1() //加分按键子程序,在主程序中不断调用该子程序
- { //当检测到甲队加分按键按下时,对应加分
- if(k1==0)
- { //调用延时子程序 实现消除按键抖动功能,即,当
- delay(1); //检测到按键按下时候,延时,按键仍按下,说明按键
- if(k1==0) //确实按下,非抖动,甲队对应加分
- {
- while(k1==0);
- x++;
- }
- }
- if(k2==0) //同理,检测乙队加分按键时候按下,并加分
- {
- delay(1);
- if(k2==0)
- {
- while(k2==0);
- y++;
- }
- }
- }
- void keyjianfen1() //减分按键检测子程序,其基本算法及功能与加
- {
- if(k5==0) //相同
- {
- delay(1);
- if(k5==0)
- {
- while(k5==0);
- x--;
- }
- }
- if(k6==0)
- {
- delay(1);
- if(k6==0)
- {
- while(k6==0);
- y--;
- }
- }
- }
- void key2() //显示时间调整程序,即回表和快表
- {
- if(k3==0)
- { //在比赛中有时经常需要回表,故写此程序
- delay(10);
- if(k3==0) //回表子程序,检测到INT0按下时,使时间回倒
- {
- chuzanting==0; // chuzanting==0; zanting=1;为附加变量,当回表按键
- zanting=1; //松开时,表暂停,这两个变量用来调用暂停
- n++;
- if(n==60)
- {
- m++;
- n=1;
- }
- }
- }
- if(k4==0) //快表子程序,检测到INT1按下时,使倒计加快,
- { //通常情况下与回表子程序配合使用,即当回表
- //回过的时候,按此键调整时间
- delay(10); // chuzanting==0; zanting=1;作用同上
- if(k4==0)
- {
- chuzanting==0;
- zanting=1;
- n--;
- }
- }
- }
- void shijian() //该程序使回表和快表按键松开时候能自动暂停
- {
- if(zanting==1&&k3==1&&k4==1&&chuzanting==0 )
- {
- EA=0; // zanting==1&&k3==1&&k4==1&&chuzanting==0作用为
- zanting=0; //当按键松开的时候,调用暂停程序条件
- chuzanting=0; //zanting=0;chuzanting=0,初始化,以便下次回表和快表
- while(1) //按键松开时候仍能调用暂停程序
- {
- display(m,n,x,y);
- if(P1_0==0) //检测暂停键按下,开中断,跳出暂停
- {
- delay(1);
- if(P1_0==0)
- {
- while(P1_0==0);
- EA=1;
- break;
- }
- }
- }
- }
- }
- void key3()
- { //半场交换场地时自动交换双方比赛分数子程序{
- int temp; //定义中间变量temp,检测到有按键按下时候
- if(zidong==1&&jie==1) //交换甲队,乙队比赛分数
- {
- temp=x; // zidong==1&&jie==1是判断半场的条件 //
- y=temp;
- display(m,n,x,y);
- zidong=0;
- bujin=0;
- }
-
- }
- void key4() //比赛暂停子程序
- {
- if(P1_0==0) //检测到暂停按键按下时候,令EA=0关闭中断
- {
- delay(1); //同通过死循环程序while(1),不断刷新数码管
- if(P1_0==0) //当暂停键再次按下时候,开中断,以使比赛时间
- { //继续倒计时,由于在暂停的时候,程序处于死循
- while(P1_0==0);
- EA=0; //无法回到主程序,故主程序中检测按键按下的
- while(1) //无法回到主程序,即实现了暂停时,除了暂停键
- { //其他按键按下均无效
- display(m,n,x,y);
- if(P1_0==0)
- { //当暂停键再次按下时候,EA=1开中断,计时数码管
- delay(1); //继续倒计时,同时通过break语句,跳出死循环
- if(P1_0==0)
- {
- while(P1_0==0);
- EA=1;
- break;
- }
- }
-
- }
- }
- }
- }
- void over() //比赛结束及及点亮下半场指示灯程序
- {
- if((m==0)&&(n==0)) //当m,n均为0的时候,通过变量jie的值判断比赛
- { //是否结束
- if(jie>1) //如果jie>1,说明半场到了,比赛没有结束, {
- { //jie--,关中断,再次按下暂停键时候继续倒计时
- m=2;
- n=0;
- EA=0;
- T1=1;
- delay(400);
- T1=0;
- while(1)
- {
- display(m,n,x,y);
- if(P1_0==0)
- {
- delay(1);
- if(P1_0==0)
- {
- while(P1_0==0);
- EA=1;
- break;
- }
- }
- }
- jie--;
- }
- if(jie==1&&bujin==2) //如果jie==1&&bujin==2,说明比赛结束了,令EA=0,
- { //比关闭中断,比赛秒表不再走动,同时不短刷新数码管,
- EA=0; //全场比赛结束蜂鸣器开始报警
- m=0;
- n=0;
- T1=1;
- delay(400);
- T1=0;
- P1=0x3f; // P1=0x3f上下半场指示灯同时点亮,比赛结束
- while(1)
- display(m,n,x,y); //不断刷新数码管
- }
- }
- }
- void main() // 主程序
- { TMOD=0x01; //设置定时器工作方式
- EA=1;
- ET0=1;
- TH0=0xb1; //定时器送计数初值,EA=1,开中断,P3口电平拉高
- TL0=0x10; // P1=0x7f, 上半场指示灯点亮
- TR0=1;
- P3=0xff;
- P1=0x7f;
- T1=0;
- while(1)
- { //通过 while(1),反复调用循环体内的子程序
- keyjiafen1(); //执行相应的功能
- keyjianfen1();
- key2();
- if(zidong==1) //zidong==1为key3()执行条件,仅当半场结束时候执行
- key3();
- if(n==18&&bujin==0)
- {
- bujin=2; //修改变量bujin的值,设定over()中第二个if语句的执行条件
- }
- shijian();
-
- key4();
- over();
- }
- }
- 下面的是我看的原来的程序
- #include <REGX51.H> //#include <REGX51.H>为头文件P1口各位分别用P1_0等表示
- code unsignedseg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- //其中{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}
- //分别对应数码管显示的字形0到9
- intm=1,n=60,x=0,y=0,i=0,jie=2,zidong=1,bujin=1,zanting=0,chuzanting=0;
- //定义全局变量m,n,x,y,i,jie,zidong,bujin,zanting,chuzanting
- //并初始化,其中m,n分别表示分钟与秒计时,x,y分别表示甲乙//两队的分数,其余中间变量
- void delay(int t) // 延时子程序 通过参数t,可以调整暂停时间
- {
- while(t--)
- {
- unsigned int i;
- for(i=0;i<200;i++);
- }
- }
-
- void display(int i,int j,int x,int y) // 数码管动态刷新显示程序
- {
- if(jie==1&&bujin!=2) //中间变量jie==1时,为上半场,对P1赋值
- P1=0xbf; //P1=0xbf, 即P1=1011 1111B,点亮对应上半场指示灯
-
- P2=0xfe; //数码管动态刷新显示程序 P2=1111 1110,i为分钟
- P0=seg[i%100/10]; //刷新显示时间显示分钟十位,调用延时程序,
- delay(1); //延时数码管的点亮
- P2=0xff;
- P0=0;
- P2=0xfd; //同理,动态刷新时分钟个位并延时点亮
- P0=seg[i%10];
- delay(1);
- P2|=0xff;
- P0=0;
- P2=0xfb; //同理,动态刷新时秒钟十位并延时点亮
- P0=seg[j%100/10];
- delay(1);
- P0=0;
- P2=0xff;
- P2=0xf7; //同理,动态刷新时秒钟个位并延时点亮
- P0=seg[j%10];
- delay(1);
- P0=0;
- P2=0xff;
- P2=0xef; //同理,动态刷新甲队分数十位并延时点亮
- P0=seg[x%100/10];
- delay(1);
- P2=0xff;
- P0=0;
- P2=0xdf; //同理,动态刷新甲队分数个位并延时点亮
- P0=seg[x%10];
- delay(1);
- P2=0xff;
- P0=0;
-
- P2=0xbf; / /同理,动态刷新乙队分数十位并延时点亮
- P0=seg[y%100/10];
- delay(1);
- P0=0;
- P2=0xff;
- P2=0x7f; //同理,动态刷新乙队分数十位并延时点亮
- P0=seg[y%10];
- delay(1);
- P0=0;
- P2=0xff;
- }
- void t0(void) interrupt 1 //调用定时器T0 基本计时单位秒
- { TH0=0xb1; //利用定时器T0,送入计数初值TH0=0xb1; TL0=0x10;
- TL0=0x10; //定时器定时单位为20毫秒
- if(n==0)
- { //分钟与秒时间调整 当秒减到0以后分钟减1
- n=60;m--;
- }
- i++;
- if(i==50)
- { //利用中间变量i 令i值为50 50*20毫秒=1秒
- n--; //以实现一秒计时
- i=0;
- }
- display(m,n-1,x,y); //调用动态刷新显示程序
- }
- void keyjiafen1() //加分按键子程序,在主程序中不断调用该子程序
- { //当检测到甲队加分按键按下时,对应加分
- if(RXD==0)
- { //调用延时子程序 实现消除按键抖动功能,即,当
- delay(1); //检测到按键按下时候,延时,按键仍按下,说明按键
- if(RXD==0) //确实按下,非抖动,甲队对应加分
- {
- while(RXD==0);
- x++;
- }
- }
- if(TXD==0) //同理,检测乙队加分按键时候按下,并加分
- {
- delay(1);
- if(TXD==0)
- {
- while(TXD==0);
- y++;
- }
- }
- }
- void keyjianfen1() //减分按键检测子程序,其基本算法及功能与加{
- if(WR==0) //相同
- {
- delay(1);
- if(WR==0)
- {
- while(WR==0);
- x--;
- }
- }
- if(RD==0)
- {
- delay(1);
- if(RD==0)
- {
- while(RD==0);
- y--;
- }
- }
- }
- void key2() //显示时间调整程序,即回表和快表
- {
- if(INT0==0)
- { //在比赛中有时经常需要回表,故写此程序
- delay(10);
- if(INT0==0) //回表子程序,检测到INT0按下时,使时间回倒
- {
- chuzanting==0; // chuzanting==0; zanting=1;为附加变量,当回表按键
- zanting=1; //松开时,表暂停,这两个变量用来调用暂停
- n++;
- if(n==60)
- {
- m++;
- n=1;
- }
- }
- }
- if(INT1==0) //快表子程序,检测到INT1按下时,使倒计加快,
- { //通常情况下与回表子程序配合使用,即当回表
- //回过的时候,按此键调整时间
- delay(10); // chuzanting==0; zanting=1;作用同上
- if(INT1==0)
- {
- chuzanting==0;
- zanting=1;
- n--;
- }
- }
- }
- void shijian() / /该程序使回表和快表按键松开时候能自动暂停
- {
- if(zanting==1&&INT0==1&&INT1==1&&chuzanting==0 )
- {
- EA=0; //zanting==1&&INT0==1&&INT1==1&&chuzanting==0作用为
- zanting=0; //当按键松开的时候,调用暂停程序条件
- chuzanting=0; //zanting=0;chuzanting=0,初始化,以便下次回表和快表 while(1) //按键松开时候仍能调用暂停程序
- {
- display(m,n,x,y);
- if(P1_0==0) //检测暂停键按下,开中断,跳出暂停
- {
- delay(1);
- if(P1_0==0)
- {
- while(P1_0==0);
- EA=1;
- break;
- }
- }
- }
- }
- }
- void key3() //半场交换场地时自动交换双方比赛分数子程序{
- inttemp; //定义中间变量temp,检测到有按键按下时候
- if(zidong==1&&jie==1) //交换甲队,乙队比赛分数
- {
- temp=x; //zidong==1&&jie==1是判断半场的条件 //
- y=temp;
- display(m,n,x,y);
- zidong=0;
- bujin=0;
- }
-
- }
- void key4() //比赛暂停子程序
- {
- if(P1_0==0) //检测到暂停按键按下时候,令EA=0关闭中断
- {
- delay(1); //同通过死循环程序while(1),不断刷新数码管
- if(P1_0==0) //当暂停键再次按下时候,开中断,以使比赛时间
- { //继续倒计时,由于在暂停的时候,程序处于死循
- while(P1_0==0);
- EA=0; //无法回到主程序,故主程序中检测按键按下的
- while(1) //无法回到主程序,即实现了暂停时,除了暂停键
- { //其他按键按下均无效
- display(m,n,x,y);
- if(P1_0==0)
- { //当暂停键再次按下时候,EA=1开中断,计时数码管
- delay(1); //继续倒计时,同时通过break语句,跳出死循环
- if(P1_0==0)
- {
- while(P1_0==0);
- EA=1;
- break;
- }
- }
-
- }
- }
- }
- }
- void over() //比赛结束及及点亮下半场指示灯程序
- {
- if((m==0)&&(n==0)) //当m,n均为0的时候,通过变量jie的值判断比赛
- { //是否结束
- if(jie>1) //如果jie>1,说明半场到了,比赛没有结束, {
- { //jie--,关中断,再次按下暂停键时候继续倒计时
- m=2;
- n=0;
- EA=0;
- T1=1;
- delay(400);
- T1=0;
- while(1)
- {
- display(m,n,x,y);
- if(P1_0==0)
- {
- delay(1);
- if(P1_0==0)
- {
- while(P1_0==0);
- EA=1;
- break;
- }
- }
- }
- jie--;
- }
- if(jie==1&&bujin==2) //如果jie==1&&bujin==2,说明比赛结束了,令EA=0, { //比关闭中断,比赛秒表不再走动,同时不短刷新数码管, EA=0;
- //全场比赛结束蜂鸣器开始报警
- m=0;
- n=0;
- T1=1;
- delay(400);
- T1=0;
- P1=0x3f; // P1=0x3f上下半场指示灯同时点亮,比赛结束
- while(1)
- display(m,n,x,y); //不断刷新数码管
- }
- }
- }
- void main() // 主程序
- { TMOD=0x01; //设置定时器工作方式
- EA=1;
- ET0=1;
- TH0=0xb1; //定时器送计数初值,EA=1,开中断,P3口电平拉高
- TL0=0x10; // P1=0x7f, 上半场指示灯点亮
- TR0=1;
- P3=0xff;
- P1=0x7f;
- T1=0;
- while(1)
- { //通过 while(1),反复调用循环体内的子程序
- keyjiafen1(); //执行相应的功能
- keyjianfen1();
- key2();
- if(zidong==1) //zidong==1为key3()执行条件,仅当半场结束时候执行
- key3();
- if(n==18&&bujin==0)
- {
- bujin=2; //修改变量bujin的值,设定over()中第二个if语句的执行条件
- }
- shijian();
-
- key4();
- over();
- }
- }
复制代码
|
|