基于單片機電子秒表設計的一些程序編程
- //包含頭文件
- #include <reg52.h>
- //宏定義
- #define uc unsigned char
- #define ui unsigned int
- void display(); //聲明顯示函數(shù)
- // 0 1 2 3 4 5 6 7 8 9
- uc code tab[]={0x5f,0x44,0x9d,0xd5,0xc6,0xd3,0xdb,0x45,0xdf,0xd7,0x00}; //數(shù)字對應顯示碼表
- uc code tab1[]={0x7f,0x64,0xbd,0xf5,0xe6,0xf3,0xfb,0x65,0xff,0xf7}; //帶小數(shù)點的數(shù)字碼表
- uc code index[]={0x7f,0xbf,0xdf,0xef}; //每位數(shù)字對應數(shù)碼管顯示位置
- uc num[8]; //num【0】-num【3】是計時用數(shù)組,4-7是范圍計時用(設置10s,計時到10秒報警)
- uc val[10][4]; //存儲的記錄 [10]為記錄序列,[4]為每組記錄中的數(shù)字
- char val_index; //記錄序列標志位
- uc set_index,ok_flag,timing; //set_index:設置的位。ok_flag:設置狀態(tài)標志,=0時是正常狀態(tài),=1是設置狀態(tài)。timing:顯示狀態(tài)標志:=0正常顯示,=1閃爍設置位
- bit mode=1; //運行模式,1為正向計數(shù),0為反向計數(shù)。
- bit fin_flag=0; //完成標志位,當反向計數(shù)結(jié)束時,此位為高電平,觸發(fā)蜂鳴器
- bit set_shan;
- uc count,beep_stop;
- sbit beep=P3^2; //蜂鳴器
- sbit key1=P3^3; //功能1:開始&停止計時;//功能2:倒計時數(shù)值設置位加1(倒計時數(shù)值設置模式下操作閃爍位);
- sbit key2=P3^4; //功能1:記錄時間點(計時進行中按下記錄,停止計時后按下回看);//功能2:倒計時數(shù)值設置位切換(倒計時數(shù)值設置模式下操作);
- sbit key3=P3^5; //功能:計時值歸零(隨時操作)
- sbit key4=P3^6; //功能:正/倒計時模式切換(計時停止狀態(tài)下操作)
- sbit key5=P3^7; //功能:倒計時數(shù)值設置模式(計時停止狀態(tài)下操作)
- void delay(ui z) //延時函數(shù),大約延時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; //定時開關(guān)
- ET0=1;
- TR0=0;
- EA=1; //中斷總開關(guān)
- val_index=0; //清零
- }
- void clr() //清除函數(shù)
- {
- uc i;
- for(i=0;i<8;i++) //將存儲的數(shù)據(jù)清零 for循環(huán)8次
- num[i]=0;
- }
- void setup() //設置函數(shù)
- {
- ok_flag=0xff; //ok_flag賦值1
- set_index=0; //設置位置0
- while (ok_flag) //進入設置后,循環(huán),直到ok_flag為0
- {
- display(); //調(diào)用顯示函數(shù)
- if(key1==0) //按動KEY1設置值加1
- {
- delay(5); //延時去抖
- if(key1==0)//再次判斷按鍵是否按下
- {
- if ((set_index==0)|(set_index==2)|(set_index==4)|(set_index==6))//設置個位數(shù)據(jù)時
- {
- num[set_index]++; //數(shù)據(jù)加
- if(num[set_index]==10) //加到10
- num[set_index]=0; //清零
- }
- else if((set_index==1)|(set_index==3)|(set_index==5)|(set_index==7))//設置十位數(shù)據(jù)時
- {
- num[set_index]++; //數(shù)據(jù)加
- 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設置結(jié)束
- {
- delay(5);//延時去抖
- if(key5==0)//再次判斷按鍵是否按下
- {
- ok_flag=0x00;//ok_flag清零
- if((num[4]!=0)||(num[5]!=0)||(num[6]!=0)||(num[7]!=0)) //如果計時時間上限設置數(shù)據(jù)不都為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))//如果計時時間上限設置數(shù)據(jù)都為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) //不是設置狀態(tài)時
- {
- if(timing==0)
- {
- for(i=0;i<4;i++)
- {
- P0=0xff; //清顯示
- P2=index[i]; //選中位
- if(i==2) //如果是第二位時
- P0=tab1[num[i]];//顯示有小數(shù)點的數(shù)據(jù)
- else //不是第二位時
- P0=tab[num[i]]; //正常顯示數(shù)據(jù)
- delay(2); //修改此參數(shù)可修改刷新頻率
- }
- }
- else //設置時 閃爍相應位
- {
- if(set_shan==0)
- {
- for(i=0;i<4;i++)
- {
- P0=0xff;
- P2=index[i];
- P0=tab[10]; //熄滅
- delay(2); //修改此參數(shù)可修改刷新頻率
- }
- }
- 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); //修改此參數(shù)可修改刷新頻率
- }
- }
- }
- }
- 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); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- else
- {
- P2=index[i];
- if(i==2)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- }
- }
- else if(set_index==1)
- {
- for (i=0;i<4;i++)
- {
- if(i==1)
- {
- P2=index[1];
- P0=tab[10];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- else
- {
- P2=index[i];
- P0=tab[num[i]];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- }
- }
- else if(set_index==2)
- {
- for (i=0;i<4;i++)
- {
- if(i==2)
- {
- P2=index[2];
- P0=tab[10];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- else
- {
- P2=index[i];
- if(i==2)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- }
- }
- else if(set_index==3)
- {
- for (i=0;i<4;i++)
- {
- if(i==3)
- {
- P2=index[3];
- P0=tab[10];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- else
- {
- P2=index[i];
- if(i==2)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- }
- }
- else if(set_index==4)
- {
- for (i=4;i<8;i++)
- {
- if(i==4)
- {
- P2=index[0];
- P0=tab[10];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- else
- {
- P2=index[i-4];
- if(i==6)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- }
- }
- else if(set_index==5)
- {
- for (i=4;i<8;i++)
- {
- if(i==5)
- {
- P2=index[1];
- P0=tab[10];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- else
- {
- P2=index[i-4];
- if(i==6)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- }
- }
- else if(set_index==6)
- {
- for (i=4;i<8;i++)
- {
- if(i==6)
- {
- P2=index[2];
- P0=tab[10];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- else
- {
- P2=index[i-4];
- if(i==6)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- }
- }
- else if(set_index==7)
- {
- for (i=4;i<8;i++)
- {
- if(i==7)
- {
- P2=index[3];
- P0=tab[10];
- delay(2); //修改此參數(shù)可修改刷新頻率
- P0=0xff;
- }
- else
- {
- P2=index[i-4];
- if(i==6)
- P0=tab1[num[i]];
- else
- P0=tab[num[i]];
- delay(2); //修改此參數(shù)可修改刷新頻率
- 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); //修改此參數(shù)可修改刷新頻率
- 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); //修改此參數(shù)可修改刷新頻率
- 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(); //刷屏顯示數(shù)碼管
- 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]; //低位存儲的數(shù)據(jù)向高位移一位
- }
- }
- for(h=0;h<4;h++)
- {
- val[9][h]=num[h];//將當前時間存儲
- }
- }
- else//在停止狀態(tài)下按下記錄鍵查看記錄,按動一次序列遞減一次,即查看上一次記錄
- {
- 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(); //將數(shù)據(jù)清零
- while(!key3) display(); //按鍵釋放
- }
- }
- if((key4==0)&&(TR0==0)) //模式選擇按鈕,僅在停止狀態(tài)下有效
- {
- delay(5);
- if(key4==0)
- {
- mode=~mode; //正計時倒計時切換
- while(!key4) display();
- }
- }
- if((key5==0)&&(TR0==0)) //時間設置,僅在停止狀態(tài)下有效
- {
- delay(5);
- if(key5==0)
- {
- while(!key5)
- display();
- setup(); //調(diào)用設置函數(shù)
- }
- }
- }
- }
- void T0_time() interrupt 1
- {
- uc m;
- TH0=0x3c; //12M晶振定時器定時時間為50ms
- TL0=0xb0;
- m++;
- if(m==20)
- {
- m=0;
- if(mode==1) //正向計數(shù)
- {
- 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時,該數(shù)字的最高位會變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的工作函數(shù)
- {
- uc shan,beep_stop;
- TH1=0x3c;
- TL1=0xb0; //重新賦初值
- shan++; //閃爍變量加
- if(shan==10) //加到10時(500ms)
- {
- shan=0; //清零
- set_shan=~set_shan; //設置的閃爍變量取反
- if((fin_flag)||(timing)) //當反向計數(shù)完成時 或計時時間到時
- {
- 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;
- }
- }
- }
- }
復制代碼
|