📄 clock.c
字号:
#include "reg51.h"
#define uint unsigned int
#define uchar unsigned char
sbit P2_0=P2^0;sbit P2_1=P2^1;sbit P2_2=P2^2;sbit P2_3=P2^3;
sbit P2_4=P2^4;sbit P2_5=P2^5;sbit P2_6=P2^6;sbit P2_7=P2^7;
sbit P1_0=P1^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;
bit flag=1,flag2=0, flag3=0,flashflag=0;
uint counter1=0,counter2=0;//counter1和counter2分别用来做正常时的计数和
//调试时的计数
void delay(uint i){uint j=0; for (; j<i;j++){;}}
uchar showcoder(uint i)//根据时钟各位的数字返回相应的八段编码
{ uchar tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
return tab[i];
}
timer0() interrupt 1 using 1 //中断
{//正常运行时,用counter1计数,用flag作秒标志,用flag2作秒加1操作的标志
if(flashflag==0)
{ if(counter1==49)
{counter1=0;flag=!flag;flag2=1;}
else counter1++;
}
else //调试时钟时,用counter2计数,用flag3作闪烁间隔标志
{ if(counter2==34)
{counter2=0;flag3=!flag3;}
else counter2++;
counter1=1;
}
TH0=(65535-9167)/256;//对定时器赋初值
TL0=(65535-9167)%256;
}
void main(void)
{
uchar tab1[8]= {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f},lastkey,
tab2[16]={0x7e,0xbe,0xbd,0xbb,0xde,0xdd,0xdb,0xee,0xed,
0xeb,0xe7,0xd7,0xb7,0x77,0x7b,0x7d},coder[8];
//tab1为八个数码管的扫描顺序,tab2为按下键盘时返回的代码,//coder为时钟
//各个位置所显示的数码的八段信号,lastkey为上次按键,为消抖电路设计做准备
uint i=0,s[7],flash=1;
bit keyflag=0;
TMOD=0x61; TR0=1;IP=0x02; EA=1;ET0=1;
TH0=(65535-9167)/256;
TL0=(65535-9167)%256;
for(;;)
{//如果产生秒标志,且不在调试状态,就进行秒表计时
if( flag==1 && flag2==1 && flashflag==0)
{ flag2=0;
if(s[1]==9)
{ s[1]=0;
if(s[2]==5)
{ s[2]=0;
if(s[3]==9)
{ s[3]=0;
if(s[4]==5)
{ s[4]=0;
if(s[5]==9)
{ s[5]=0;
if(s[6]==9)
{s[6]=0;}
else s[6]++;
}
else s[5]++;
}
else s[4]++;
}
else s[3]++;
}
else s[2]++;
}
else s[1]++;
}
coder[0]=showcoder(s[6]);//通过调用函数得到每个数码管的显示代码
coder[1]=showcoder(s[5]);
coder[2]=0xbf;//显示连字符
coder[3]=showcoder(s[4]);
coder[4]=showcoder(s[3]);
coder[5]=0xbf;
coder[6]=showcoder(s[2]);
coder[7]=showcoder(s[1]);
for(i=0;i<8;i++)
{ P1=tab1[i];//对数码管进行扫描
if(flashflag==1)//如果在调试状态
{ if (flag3==0)//并且产生了闪烁标志,相应的调试位进行闪烁。
{ switch(flash)
{ case 1:P1_7=0xff;break;
case 2:P1_6=0xff;break;
case 3:P1_4=0xff;break;
case 4:P1_3=0xff;break;
case 5:P1_1=0xff;break;
case 6:P1_0=0xff;break;
default :break;
}
}
}
P0=coder[i];
delay(50);
}
delay(3);
for(i=0;i<30;i++)//按键扫描程序
{
P2_4=0;P2_5=1;P2_6=1;P2_7=1;//进行行扫描,扫描到按键就返回相应代码
if (P2_0==0) {P2=tab2[7];break;}
else if (P2_1==0) {P2=tab2[8];break; }
else if (P2_2==0 ) {P2=tab2[9];break;}
else if (P2_3==0 ) {P2=tab2[10];break;}
P2_4=1;P2_5=0;P2_6=1;P2_7=1;
if (P2_0==0 ) {P2=tab2[4];break;}
else if (P2_1==0) {P2=tab2[5];break; }
else if (P2_2==0 ) {P2=tab2[6];break;}
else if (P2_3==0 ) {P2=tab2[11];break;}
P2_4=1;P2_5=1;P2_6=0;P2_7=1;
if (P2_0==0) {P2=tab2[1];break;}
else if (P2_1==0) {P2=tab2[2];break; }
else if (P2_2==0) {P2=tab2[3];break;}
else if (P2_3==0) {P2=tab2[12];break;}
P2_4=1;P2_5=1;P2_6=1;P2_7=0;
if (P2_0==0) {P2=tab2[0];break;}
else if (P2_1==0) {P2=tab2[15];break;}
else if (P2_2==0) {P2=tab2[14];break;}
else if (P2_3==0) {P2=tab2[13];break;}
}
if(P2==0xff) keyflag=0; else keyflag=1;
//消抖电路:如果连续两次扫描到有键按下,就会判断此次与上次按键是否相同,
//如果相同则屏蔽掉,如果两次按键之间有停顿,则不会屏蔽此次按键
if (P2!=lastkey && keyflag==1)
{//秒分时的个位可以接受从0到9的按键输入,十位只能接受0到5的输入
for(i=0;i<16;i++)
{ if (P2==tab2[i] && flashflag==1)
{ if (i<6) { s[flash]=i;}
else if(i>5 && i<10 && flash%2==1) {s[flash]=i; }
else if(i==10) {if (flash==6) flash=1; else flash++;}
else if(i==11) {if (flash==1) flash=6; else flash--;}
}//按下A将闪烁位左移,按下D右移。
else if(P2==tab2[12]) {flashflag=1;}//按下C进入调试模式
else if(P2==tab2[13]) {flashflag=0;flash=1;}
}//按下D退出调试模式
}
lastkey=P2;
P2=0xff;//清除按键值,为下次按键作准备。
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -