基于单片机电子秒表设计的一些程序编程
- //包含头文件
- #include <reg52.h>
- //宏定义
- #define uc unsigned char
- #define ui unsigned int
- void display(); //声明显示函数
- // 0 1 2 3 4 5 6 7 8 9
- uc code tab[]={0x5f,0x44,0x9d,0xd5,0xc6,0xd3,0xdb,0x45,0xdf,0xd7,0x00}; //数字对应显示码表
- uc code tab1[]={0x7f,0x64,0xbd,0xf5,0xe6,0xf3,0xfb,0x65,0xff,0xf7}; //带小数点的数字码表
- uc code index[]={0x7f,0xbf,0xdf,0xef}; //每位数字对应数码管显示位置
- uc num[8]; //num【0】-num【3】是计时用数组,4-7是范围计时用(设置10s,计时到10秒报警)
- uc val[10][4]; //存储的记录 [10]为记录序列,[4]为每组记录中的数字
- char val_index; //记录序列标志位
- uc set_index,ok_flag,timing; //set_index:设置的位。ok_flag:设置状态标志,=0时是正常状态,=1是设置状态。timing:显示状态标志:=0正常显示,=1闪烁设置位
- bit mode=1; //运行模式,1为正向计数,0为反向计数。
- bit fin_flag=0; //完成标志位,当反向计数结束时,此位为高电平,触发蜂鸣器
- bit set_shan;
- uc count,beep_stop;
- sbit beep=P3^2; //蜂鸣器
- sbit key1=P3^3; //功能1:开始&停止计时;//功能2:倒计时数值设置位加1(倒计时数值设置模式下操作闪烁位);
- sbit key2=P3^4; //功能1:记录时间点(计时进行中按下记录,停止计时后按下回看);//功能2:倒计时数值设置位切换(倒计时数值设置模式下操作);
- sbit key3=P3^5; //功能:计时值归零(随时操作)
- sbit key4=P3^6; //功能:正/倒计时模式切换(计时停止状态下操作)
- sbit key5=P3^7; //功能:倒计时数值设置模式(计时停止状态下操作)
- void delay(ui z) //延时函数,大约延时z ms
- {
- ui i,j;
- for(i=0;i<z;i++)
- for(j=0;j<121;j++);
- }
- void init() //初始化
- {
- TMOD=0x11; //工作方式
- TH0=0x3c;
- TL0=0xb0; //定时器0赋初值
- TH1=0x3c;
- TL1=0xb0; //定时器1赋初值
- ET1=1; //允许中断
- TR1=1; //定时开关
- ET0=1;
- TR0=0;
- EA=1; //中断总开关
- val_index=0; //清零
- }
- void clr() //清除函数
- {
- uc i;
- for(i=0;i<8;i++) //将存储的数据清零 for循环8次
- num[i]=0;
- }
- void setup() //设置函数
- {
- ok_flag=0xff; //ok_flag赋值1
- set_index=0; //设置位置0
- while (ok_flag) //进入设置后,循环,直到ok_flag为0
- {
- display(); //调用显示函数
- if(key1==0) //按动KEY1设置值加1
- {
- delay(5); //延时去抖
- if(key1==0)//再次判断按键是否按下
- {
- if ((set_index==0)|(set_index==2)|(set_index==4)|(set_index==6))//设置个位数据时
- {
- num[set_index]++; //数据加
- if(num[set_index]==10) //加到10
- num[set_index]=0; //清零
- }
- else if((set_index==1)|(set_index==3)|(set_index==5)|(set_index==7))//设置十位数据时
- {
- num[set_index]++; //数据加
- if(num[set_index]==6) //加到6时
- num[set_index]=0; //清零
- }
- while(!key1) display(); //按键释放
- }
- }
- if(key2==0) //按动KEY2设置位置加1
- {
- delay(5);//延时去抖
- if(key2==0)//再次按下按键
- {
- set_index++; //设置位置加
- if(set_index==8)//设置位置加到最后一位时
- {
- set_index=0;//设置位置到0
- }
- while(!key2) display();//按键释放
- }
- }
- if(key5==0) //按动KEY5设置结束
- {
- delay(5);//延时去抖
- if(key5==0)//再次判断按键是否按下
- {
- ok_flag=0x00;//ok_flag清零
- if((num[4]!=0)||(num[5]!=0)||(num[6]!=0)||(num[7]!=0)) //如果计时时间上限设置数据不都为0时
- {
- num[0]=0;num[1]=0;num[2]=0;num[3]=0;mode=1;//将正计时时间清零,Mode置1,正计时
- }
- else if((num[4]==0)&&(num[5]==0)&&(num[6]==0)&&(num[7]==0))//如果计时时间上限设置数据都为0时
- {
- if((num[0]==0)&&(num[1]==0)&&(num[2]==0)&&(num[3]==0))//判断计时时间都为0
- mode=1; //正计时模式
- else if((num[0]!=0)||(num[1]!=0)||(num[2]!=0)||(num[3]!=0))//判断计时时间有不为0
- mode=0; //倒计时模式
- }
- while(!key5) display(); //按键去抖
- }
- }
- }
- }
- void display()
- {
- uc i;
- if(ok_flag!=0xff) //不是设置状态时
- {
- if(timing==0)
- {
- for(i=0;i<4;i++)
- {
- P0=0xff; //清显示
- P2=index[i]; //选中位
- if(i==2) //如果是第二位时
- P0=tab1[num[i]];//显示有小数点的数据
- else //不是第二位时
- P0=tab[num[i]]; //正常显示数据
- delay(2); //修改此参数可修改刷新频率
- }
- }
- else //设置时 闪烁相应位
- {
- if(set_shan==0)
- {
- for(i=0;i<4;i++)
- {
- P0=0xff;
- P2=index[i];
- P0=tab[10]; //熄灭
- delay(2); //修改此参数可修改刷新频率
- }
- }
- else if(set_shan==1)
- { //点亮显示
- for(i=0;i<4;i++)
- {
- P0=0xff;
- P2=index[i];
- if(i==2)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此参数可修改刷新频率
- }
- }
- }
- }
- else //设置时
- {
- if(set_shan==0)
- {
- if(set_index==0) //设置不同位时,闪烁相应位
- {
- for(i=0;i<4;i++)
- {
- if(i==0)
- {
- P2=index[0];
- P0=tab[10];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- else
- {
- P2=index[i];
- if(i==2)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- }
- }
- else if(set_index==1)
- {
- for (i=0;i<4;i++)
- {
- if(i==1)
- {
- P2=index[1];
- P0=tab[10];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- else
- {
- P2=index[i];
- P0=tab[num[i]];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- }
- }
- else if(set_index==2)
- {
- for (i=0;i<4;i++)
- {
- if(i==2)
- {
- P2=index[2];
- P0=tab[10];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- else
- {
- P2=index[i];
- if(i==2)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- }
- }
- else if(set_index==3)
- {
- for (i=0;i<4;i++)
- {
- if(i==3)
- {
- P2=index[3];
- P0=tab[10];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- else
- {
- P2=index[i];
- if(i==2)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- }
- }
- else if(set_index==4)
- {
- for (i=4;i<8;i++)
- {
- if(i==4)
- {
- P2=index[0];
- P0=tab[10];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- else
- {
- P2=index[i-4];
- if(i==6)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- }
- }
- else if(set_index==5)
- {
- for (i=4;i<8;i++)
- {
- if(i==5)
- {
- P2=index[1];
- P0=tab[10];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- else
- {
- P2=index[i-4];
- if(i==6)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- }
- }
- else if(set_index==6)
- {
- for (i=4;i<8;i++)
- {
- if(i==6)
- {
- P2=index[2];
- P0=tab[10];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- else
- {
- P2=index[i-4];
- if(i==6)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- }
- }
- else if(set_index==7)
- {
- for (i=4;i<8;i++)
- {
- if(i==7)
- {
- P2=index[3];
- P0=tab[10];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- else
- {
- P2=index[i-4];
- if(i==6)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- }
- }
- }
- else
- {
- if(set_index<4)
- {
- for (i=0;i<4;i++)
- {
- P2=index[i];
- if(i==2)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- }
- else
- {
- for (i=4;i<8;i++)
- {
- P2=index[i-4];
- if(i==6)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此参数可修改刷新频率
- P0=0xff;
- }
- }
- }
- }
- }
- void alarm()
- {
- if((num[4]==0)&&(num[5]==0)&&(num[6]==0)&&(num[7]==0)) //计时时间到0时
- {
- timing=0;
- }
- else
- {
- if((num[4]==num[0])&&(num[6]==num[2])&&(num[5]==num[1])&&(num[7]==num[3])) //设置上限模式时,计时时间到
- {
- timing=1;
- TR0=0; //停止计时,并闪烁显示
- }
- }
- }
- void main()
- {
- uc h,g,k;
- init();
- clr();
- while(1)
- {
- display(); //刷屏显示数码管
- alarm();
- if(key1==0) //开始/暂停按钮
- {
- delay(5);
- if(key1==0)
- {
- TR0=~TR0;
- while(!key1) display();
- }
- }
- if(key2==0) //记录按钮
- {
- delay(5);
- if(key2==0)
- {
- if(TR0==1)//当在运行中按下记录键则存储记录
- {
- for(g=1;g<10;g++)
- {
- for(k=0;k<4;k++)
- {
- val[g-1][k]=val[g][k]; //低位存储的数据向高位移一位
- }
- }
- for(h=0;h<4;h++)
- {
- val[9][h]=num[h];//将当前时间存储
- }
- }
- else//在停止状态下按下记录键查看记录,按动一次序列递减一次,即查看上一次记录
- {
- for(h=0;h<4;h++)
- num[h]=val[val_index][h];//将当前时间存储
- val_index--;
- if(val_index<0)
- val_index=9;
- }
- while(!key2) display(); //按键释放
- }
- }
- if(key3==0) //复位按钮
- {
- delay(5);
- if(key3==0)
- {
- clr(); //将数据清零
- while(!key3) display(); //按键释放
- }
- }
- if((key4==0)&&(TR0==0)) //模式选择按钮,仅在停止状态下有效
- {
- delay(5);
- if(key4==0)
- {
- mode=~mode; //正计时倒计时切换
- while(!key4) display();
- }
- }
- if((key5==0)&&(TR0==0)) //时间设置,仅在停止状态下有效
- {
- delay(5);
- if(key5==0)
- {
- while(!key5)
- display();
- setup(); //调用设置函数
- }
- }
- }
- }
- void T0_time() interrupt 1
- {
- uc m;
- TH0=0x3c; //12M晶振定时器定时时间为50ms
- TL0=0xb0;
- m++;
- if(m==20)
- {
- m=0;
- if(mode==1) //正向计数
- {
- num[0]++; //秒个位加
- if(num[0]==10) //秒个位加到10时
- {
- num[0]=0; //个位清零
- num[1]++; //秒十位加
- if(num[1]==6) //秒十位加到6时
- {
- num[1]=0; //秒十位清零
- num[2]++; //分个位加
- if(num[2]==10) //分个位加到10时
- {
- num[2]=0; //分个位清零
- num[3]++; //分十位加
- if(num[3]==10)//分十位加到10时
- num[3]=0; //分十位清零
- }
- }
- }
- }
- else
- {
- num[0]--; //秒个位减
- if(num[0]>9) //小于0时,该数字的最高位会变1,所以判断是否大于9 下同
- {
- num[0]=9;
- num[1]--;
- if(num[1]>5)
- {
- num[1]=5;
- num[2]--;
- if(num[2]>9)
- {
- num[2]=9;
- num[3]--;
- if(num[3]>9)
- {
- num[3]=0;
- TR0=0;
- fin_flag=1;
- clr();
- }
- }
- }
- }
- }
- }
- }
- void T1_time() interrupt 3 //定时器1的工作函数
- {
- uc shan,beep_stop;
- TH1=0x3c;
- TL1=0xb0; //重新赋初值
- shan++; //闪烁变量加
- if(shan==10) //加到10时(500ms)
- {
- shan=0; //清零
- set_shan=~set_shan; //设置的闪烁变量取反
- if((fin_flag)||(timing)) //当反向计数完成时 或计时时间到时
- {
- beep_stop++;
- beep=~beep; //蜂鸣器闪烁响
- if(beep_stop==10) //蜂鸣器响五声停止
- {
- fin_flag=0;
- timing=0;
- num[4]=0;num[5]=0;num[6]=0;num[7]=0;
- beep_stop=0;
- beep=1;
- }
- }
- }
- }
复制代码
|