用AT89C52芯片作为主控芯片实现计时/定时的功能,使用单片机内置的定时器以中断的方式产生以秒为单位的时间信号,产生的时间数据通过计算分成四位在数码管上以逐位扫描的方式显示出来,由于扫描速度足够快,因此看上去四位数字是同时显示的,另外还用了七个io口对应七个功能按键,按下去时可以拉低引脚电平,通过检测电平变化来判断按键是否被按下,七个按键可以实现时间的调整以及计时暂停继续清零等功能。
- #include<reg52.h>
- sbit w1 = P3 ^ 6;
- sbit w2 = P1 ^ 5;
- sbit w3 = P1 ^ 4;
- sbit w4 = P1 ^ 3;
- sbit a = P3 ^ 5;
- sbit b = P1 ^ 2;
- sbit c = P1 ^ 7;
- sbit d = P3 ^ 2;
- sbit e = P3 ^ 3;
- sbit f = P3 ^ 4;
- sbit g = P1 ^ 6;
- sbit h = P3 ^ 1;
- sbit set = P2 ^ 5;
- sbit stop = P2 ^ 7;
- sbit clear = P2 ^ 6;
- sbit up = P2 ^ 2;
- sbit down = P2 ^ 1;
- sbit right = P2 ^ 3;
- sbit left = P2 ^ 0;
- sbit led = P3 ^ 7; //各io口设置
- bit settime = 0; //是否进入时间设定模式的判断变量
- bit pause = 0; //是否暂停的标志变量
- int time = 3599; //时间数据,初始值为59:59
- unsigned char num; //定时器中断次数记录变量
- unsigned char bj1 = 0, bj2 = 0, bj3 = 1,bj4=0; //标记变量
- void xianshi( int i ) { //数码管位选函数,显示0~9
- switch ( i ) {
- case 0:
- a = b = c = d = e = f = g = h = 0;
- a = b = c = e = d = f = 1;
- break;
- case 1:
- a = b = c = d = e = f = g = h = 0;
- b = c = 1;
- break;
- case 2:
- a = b = c = d = e = f = g = h = 0;
- a = b = g = e = d = 1;
- break;
- case 3:
- a = b = c = d = e = f = g = h = 0;
- a = b = g = c = d = 1;
- break;
- case 4:
- a = b = c = d = e = f = g = h = 0;
- f = g = b = c = 1;
- break;
- case 5:
- a = b = c = d = e = f = g = h = 0;
- a = f = g = c = d = 1;
- break;
- case 6:
- a = b = c = d = e = f = g = h = 0;
- a = f = e = g = c = d = 1;
- break;
- case 7:
- a = b = c = d = e = f = g = h = 0;
- a = b = c = 1;
- break;
- case 8:
- a = b = c = d = e = f = g = h = 0;
- a = b = c = d = e = f = g = 1;
- break;
- case 9:
- a = b = c = d = e = f = g = h = 0;
- a = b = c = d = g = f = 1;
- break;
- }
- }
- void delay( int i ) //延时函数大概延时ims
- {
- int j;
- for ( i; i >= 0; i-- ) {
- for ( j = 110; j >= 0; j-- );
- }
- }
- void zijiang( void ) //数码管自检函数
- {
- int i;
- w1 = w2 = w3 = w4 = 0;
- a = b = c = d = e = f = g = h = 1;
- delay( 800 );
- a = b = c = d = e = f = g = h = 0;
- for ( i = 0; i <= 9; i++ ) {
- w1 = w2 = w3 = w4 = 0;
- xianshi( i );
- delay( 500 );
- }
- w1 = w2 = w3 = w4 = 1;
- bj3 = 0;
- }
- void display( int i ) //数码管时间显示函数
- {
- int w, x, y, z;
- w = ( ( i / 60 ) / 10 );
- x = ( ( i / 60 ) % 10 );
- y = ( ( i % 60 ) / 10 );
- z = ( ( i % 60 ) % 10 );
- w1 = w2 = w3 = w4 = 1;
- w1 = 0;
- xianshi( w );
- delay( 5 );
- w1 = 1;
- w2 = 0;
- xianshi( z );
- delay( 5 );
- w2 = 1;
- w3 = 0;
- xianshi( x );
- delay( 5 );
- w3 = 1;
- w4 = 0;
- xianshi( y );
- delay( 5 );
- w4 = 1;
- }
- void setdisplay( int i,int j ) //设置时间时数码管时间显示函数,带有闪烁功能
- {
- int w, x, y, z;
- w = ( ( i / 60 ) / 10 );
- x = ( ( i / 60 ) % 10 );
- y = ( ( i % 60 ) / 10 );
- z = ( ( i % 60 ) % 10 );
- w1 = w2 = w3 = w4 = 1;
- w1 = 0;
- if(j==1)
- {
- bj4++;
- if(bj4>=50)
- {
- w1=1;
- if(bj4>=100)
- bj4=0;
- }
- }
- xianshi( w );
- delay( 5 );
- w1 = 1;
- w2 = 0;
- if(j==4)
- {
- bj4++;
- if(bj4>=50)
- {
- w2=1;
- if(bj4>=100)
- bj4=0;
- }
- }
- xianshi( z );
- delay( 5 );
- w2 = 1;
- w3 = 0;
- if(j==2)
- {
- bj4++;
- if(bj4>=50)
- {
- w3=1;
- if(bj4>=100)
- bj4=0;
- }
- }
- xianshi( x );
- delay( 5 );
- w3 = 1;
- w4 = 0;
- if(j==3)
- {
- bj4++;
- if(bj4>=50)
- {
- w4=1;
- if(bj4>=100)
- bj4=0;
- }
- }
- xianshi( y );
- delay( 5 );
- w4 = 1;
- }
- void T0_time()interrupt 1 //中断产生时间信号
- {
- TH0 = 59;
- TL0 = 114; //重装初值
- num++;
- }
- void main()
- {
- int j = 1;
- w1 = w2 = w3 = w4 = 1;
- TH0 = 59;
- TL0 = 146; //定时器设置及装填初值
- EA = 1;
- ET0 = 1;
- led=0;
- while ( 1 )
- {
- if ( bj3 == 1 )
- zijiang(); //自检函数,只运行一次
- while(bj2==1)
- {
- if ( set == 0 ) //设置函数,按下设置键进入函数
- {
- delay( 10 );
- if ( set == 0 )
- {
- while(!set); //按键防抖,并且防止按一次重复多次
- settime = 1;
- }
- }
- if ( settime == 1 )
- {
- setdisplay( time,j );
- if ( right == 0 ) //时间设置右移
- {
- delay( 10 );
- if ( right == 0 )
- {
- while ( !right );
- j++;
- if ( j == 5 )
- j = 1;
- }
- }
- setdisplay( time,j );
- if ( left == 0 ) //时间设置左移
- {
- delay( 10 );
- if ( left == 0 )
- {
- while ( !left );
- j--;
- if ( j == 0 )
- j = 4;
- }
- }
- setdisplay( time,j );
- if ( up == 0 ) //时间加
- delay( 10 );
- {
- if ( up == 0 )
- {
- while ( !up );
- switch ( j )
- {
- case 1:
- time = time + 600;
- if ( ( time / 600 ) > 5 )
- time = time - 3600;
- break;
- case 2:
- time = time + 60;
- if ( ( ( time / 60 ) % 10 ) == 0 )
- time = time - 600;
- break;
- case 3:
- time = time + 10;
- if ( ( ( time % 60 ) / 10 ) > 5 )
- time = time - 60;
- break;
- case 4:
- time++;
- if ( ( ( time % 60 ) / 10 ) == 0 )
- time = time - 10;
- break;
- }
- }
- }
- setdisplay( time,j );
- if ( down == 0 ) //时间减
- {
- delay( 10 );
- if ( down == 0 )
- {
- while ( !down );
- switch ( j )
- {
- case 1:
- if ( time / 600 == 0 )
- time = time + 3600;
- time = time - 600;
- break;
- case 2:
- if ( ( ( time / 60 ) % 10 ) == 0 )
- time = time + 600;
- time = time - 60;
- break;
- case 3:
- if ( ( ( time % 60 ) / 10 ) == 0 )
- time = time + 60;
- time = time - 10;
- break;
- case 4:
- if ( ( ( time % 60 ) % 10 ) == 0 )
- time = time + 10;
- time--;
- break;
- }
- }
- }
- setdisplay( time,j );
- if ( stop == 0 ) //开始按钮,按下开始计时
- {
- delay( 10 );
- if ( stop == 0 )
- while ( !stop );
- bj2 = 0;
- }
- if ( clear == 0 ) //清零按钮,按下时间清零
- {
- delay( 10 );
- if ( clear == 0 )
- {
- while ( !clear );
- time = 0;
- }
- }
- }
- }
- while ( bj2 == 0 ) //计时部分从59:59开始倒计时
- {
- TR0 = 1;
- display( time );
- if ( num >= 160 )
- {
- num = 0;
- time--;
- }
- if(time==0) //判断即使是否结束
- led=1;
- TR0=0;
- if ( set == 0 ) //设置按钮,按下进入设置模式
- {
- delay(10);
- if ( set == 0 )
- {
- while ( !set );
- bj2 = 1;
- TR0 = 0;
- }
- }
- if ( stop == 0 ) //暂停/开始按钮,按下暂停或者开始计时
- {
- delay( 10 );
- if ( stop == 0 )
- { while(!stop);
- bj2=1-bj2;
- }
- }
- if ( bj2 == 0 )
- TR0 = 1;
- else
- TR0 = 0;
- }
- }
- }
复制代码
|