標(biāo)題:
帶詳細(xì)注釋的51單片機(jī)電子秒表程序
[打印本頁(yè)]
作者:
帥氣的小哥哥
時(shí)間:
2021-12-16 10:39
標(biāo)題:
帶詳細(xì)注釋的51單片機(jī)電子秒表程序
基于單片機(jī)電子秒表設(shè)計(jì)的一些程序編程
//包含頭文件
#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ù)字對(duì)應(yīng)顯示碼表
uc code tab1[]={0x7f,0x64,0xbd,0xf5,0xe6,0xf3,0xfb,0x65,0xff,0xf7}; //帶小數(shù)點(diǎn)的數(shù)字碼表
uc code index[]={0x7f,0xbf,0xdf,0xef}; //每位數(shù)字對(duì)應(yīng)數(shù)碼管顯示位置
uc num[8]; //num【0】-num【3】是計(jì)時(shí)用數(shù)組,4-7是范圍計(jì)時(shí)用(設(shè)置10s,計(jì)時(shí)到10秒報(bào)警)
uc val[10][4]; //存儲(chǔ)的記錄 [10]為記錄序列,[4]為每組記錄中的數(shù)字
char val_index; //記錄序列標(biāo)志位
uc set_index,ok_flag,timing; //set_index:設(shè)置的位。ok_flag:設(shè)置狀態(tài)標(biāo)志,=0時(shí)是正常狀態(tài),=1是設(shè)置狀態(tài)。timing:顯示狀態(tài)標(biāo)志:=0正常顯示,=1閃爍設(shè)置位
bit mode=1; //運(yùn)行模式,1為正向計(jì)數(shù),0為反向計(jì)數(shù)。
bit fin_flag=0; //完成標(biāo)志位,當(dāng)反向計(jì)數(shù)結(jié)束時(shí),此位為高電平,觸發(fā)蜂鳴器
bit set_shan;
uc count,beep_stop;
sbit beep=P3^2; //蜂鳴器
sbit key1=P3^3; //功能1:開(kāi)始&停止計(jì)時(shí);//功能2:倒計(jì)時(shí)數(shù)值設(shè)置位加1(倒計(jì)時(shí)數(shù)值設(shè)置模式下操作閃爍位);
sbit key2=P3^4; //功能1:記錄時(shí)間點(diǎn)(計(jì)時(shí)進(jìn)行中按下記錄,停止計(jì)時(shí)后按下回看);//功能2:倒計(jì)時(shí)數(shù)值設(shè)置位切換(倒計(jì)時(shí)數(shù)值設(shè)置模式下操作);
sbit key3=P3^5; //功能:計(jì)時(shí)值歸零(隨時(shí)操作)
sbit key4=P3^6; //功能:正/倒計(jì)時(shí)模式切換(計(jì)時(shí)停止?fàn)顟B(tài)下操作)
sbit key5=P3^7; //功能:倒計(jì)時(shí)數(shù)值設(shè)置模式(計(jì)時(shí)停止?fàn)顟B(tài)下操作)
void delay(ui z) //延時(shí)函數(shù),大約延時(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; //定時(shí)器0賦初值
TH1=0x3c;
TL1=0xb0; //定時(shí)器1賦初值
ET1=1; //允許中斷
TR1=1; //定時(shí)開(kāi)關(guān)
ET0=1;
TR0=0;
EA=1; //中斷總開(kāi)關(guān)
val_index=0; //清零
}
void clr() //清除函數(shù)
{
uc i;
for(i=0;i<8;i++) //將存儲(chǔ)的數(shù)據(jù)清零 for循環(huán)8次
num[i]=0;
}
void setup() //設(shè)置函數(shù)
{
ok_flag=0xff; //ok_flag賦值1
set_index=0; //設(shè)置位置0
while (ok_flag) //進(jìn)入設(shè)置后,循環(huán),直到ok_flag為0
{
display(); //調(diào)用顯示函數(shù)
if(key1==0) //按動(dòng)KEY1設(shè)置值加1
{
delay(5); //延時(shí)去抖
if(key1==0)//再次判斷按鍵是否按下
{
if ((set_index==0)|(set_index==2)|(set_index==4)|(set_index==6))//設(shè)置個(gè)位數(shù)據(jù)時(shí)
{
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è)置十位數(shù)據(jù)時(shí)
{
num[set_index]++; //數(shù)據(jù)加
if(num[set_index]==6) //加到6時(shí)
num[set_index]=0; //清零
}
while(!key1) display(); //按鍵釋放
}
}
if(key2==0) //按動(dòng)KEY2設(shè)置位置加1
{
delay(5);//延時(shí)去抖
if(key2==0)//再次按下按鍵
{
set_index++; //設(shè)置位置加
if(set_index==8)//設(shè)置位置加到最后一位時(shí)
{
set_index=0;//設(shè)置位置到0
}
while(!key2) display();//按鍵釋放
}
}
if(key5==0) //按動(dòng)KEY5設(shè)置結(jié)束
{
delay(5);//延時(shí)去抖
if(key5==0)//再次判斷按鍵是否按下
{
ok_flag=0x00;//ok_flag清零
if((num[4]!=0)||(num[5]!=0)||(num[6]!=0)||(num[7]!=0)) //如果計(jì)時(shí)時(shí)間上限設(shè)置數(shù)據(jù)不都為0時(shí)
{
num[0]=0;num[1]=0;num[2]=0;num[3]=0;mode=1;//將正計(jì)時(shí)時(shí)間清零,Mode置1,正計(jì)時(shí)
}
else if((num[4]==0)&&(num[5]==0)&&(num[6]==0)&&(num[7]==0))//如果計(jì)時(shí)時(shí)間上限設(shè)置數(shù)據(jù)都為0時(shí)
{
if((num[0]==0)&&(num[1]==0)&&(num[2]==0)&&(num[3]==0))//判斷計(jì)時(shí)時(shí)間都為0
mode=1; //正計(jì)時(shí)模式
else if((num[0]!=0)||(num[1]!=0)||(num[2]!=0)||(num[3]!=0))//判斷計(jì)時(shí)時(shí)間有不為0
mode=0; //倒計(jì)時(shí)模式
}
while(!key5) display(); //按鍵去抖
}
}
}
}
void display()
{
uc i;
if(ok_flag!=0xff) //不是設(shè)置狀態(tài)時(shí)
{
if(timing==0)
{
for(i=0;i<4;i++)
{
P0=0xff; //清顯示
P2=index[i]; //選中位
if(i==2) //如果是第二位時(shí)
P0=tab1[num[i]];//顯示有小數(shù)點(diǎn)的數(shù)據(jù)
else //不是第二位時(shí)
P0=tab[num[i]]; //正常顯示數(shù)據(jù)
delay(2); //修改此參數(shù)可修改刷新頻率
}
}
else //設(shè)置時(shí) 閃爍相應(yīng)位
{
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)
{ //點(diǎn)亮顯示
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 //設(shè)置時(shí)
{
if(set_shan==0)
{
if(set_index==0) //設(shè)置不同位時(shí),閃爍相應(yīng)位
{
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)) //計(jì)時(shí)時(shí)間到0時(shí)
{
timing=0;
}
else
{
if((num[4]==num[0])&&(num[6]==num[2])&&(num[5]==num[1])&&(num[7]==num[3])) //設(shè)置上限模式時(shí),計(jì)時(shí)時(shí)間到
{
timing=1;
TR0=0; //停止計(jì)時(shí),并閃爍顯示
}
}
}
void main()
{
uc h,g,k;
init();
clr();
while(1)
{
display(); //刷屏顯示數(shù)碼管
alarm();
if(key1==0) //開(kāi)始/暫停按鈕
{
delay(5);
if(key1==0)
{
TR0=~TR0;
while(!key1) display();
}
}
if(key2==0) //記錄按鈕
{
delay(5);
if(key2==0)
{
if(TR0==1)//當(dāng)在運(yùn)行中按下記錄鍵則存儲(chǔ)記錄
{
for(g=1;g<10;g++)
{
for(k=0;k<4;k++)
{
val[g-1][k]=val[g][k]; //低位存儲(chǔ)的數(shù)據(jù)向高位移一位
}
}
for(h=0;h<4;h++)
{
val[9][h]=num[h];//將當(dāng)前時(shí)間存儲(chǔ)
}
}
else//在停止?fàn)顟B(tài)下按下記錄鍵查看記錄,按動(dòng)一次序列遞減一次,即查看上一次記錄
{
for(h=0;h<4;h++)
num[h]=val[val_index][h];//將當(dāng)前時(shí)間存儲(chǔ)
val_index--;
if(val_index<0)
val_index=9;
}
while(!key2) display(); //按鍵釋放
}
}
if(key3==0) //復(fù)位按鈕
{
delay(5);
if(key3==0)
{
clr(); //將數(shù)據(jù)清零
while(!key3) display(); //按鍵釋放
}
}
if((key4==0)&&(TR0==0)) //模式選擇按鈕,僅在停止?fàn)顟B(tài)下有效
{
delay(5);
if(key4==0)
{
mode=~mode; //正計(jì)時(shí)倒計(jì)時(shí)切換
while(!key4) display();
}
}
if((key5==0)&&(TR0==0)) //時(shí)間設(shè)置,僅在停止?fàn)顟B(tài)下有效
{
delay(5);
if(key5==0)
{
while(!key5)
display();
setup(); //調(diào)用設(shè)置函數(shù)
}
}
}
}
void T0_time() interrupt 1
{
uc m;
TH0=0x3c; //12M晶振定時(shí)器定時(shí)時(shí)間為50ms
TL0=0xb0;
m++;
if(m==20)
{
m=0;
if(mode==1) //正向計(jì)數(shù)
{
num[0]++; //秒個(gè)位加
if(num[0]==10) //秒個(gè)位加到10時(shí)
{
num[0]=0; //個(gè)位清零
num[1]++; //秒十位加
if(num[1]==6) //秒十位加到6時(shí)
{
num[1]=0; //秒十位清零
num[2]++; //分個(gè)位加
if(num[2]==10) //分個(gè)位加到10時(shí)
{
num[2]=0; //分個(gè)位清零
num[3]++; //分十位加
if(num[3]==10)//分十位加到10時(shí)
num[3]=0; //分十位清零
}
}
}
}
else
{
num[0]--; //秒個(gè)位減
if(num[0]>9) //小于0時(shí),該數(shù)字的最高位會(huì)變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 //定時(shí)器1的工作函數(shù)
{
uc shan,beep_stop;
TH1=0x3c;
TL1=0xb0; //重新賦初值
shan++; //閃爍變量加
if(shan==10) //加到10時(shí)(500ms)
{
shan=0; //清零
set_shan=~set_shan; //設(shè)置的閃爍變量取反
if((fin_flag)||(timing)) //當(dāng)反向計(jì)數(shù)完成時(shí) 或計(jì)時(shí)時(shí)間到時(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;
}
}
}
}
復(fù)制代碼
作者:
sanye涼風(fēng)
時(shí)間:
2022-4-13 15:33
有沒(méi)有仿真圖片可以圖文來(lái)講解一下嗎?
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1