|
麻煩大佬們了
#include<reg51.h>
#include<intrins.h>
#define on 1
#define off 0
#define speed_mod 0
#define distance_mod 1
#define v_speed_mod 4
#define time_mod 2
#define v_distance_mod 3
#define uchar unsigned char
#define uint unsigned int
sbit key_n=P3^3;
uchar code dis_code[11]={0x14,0x77,0x2c,0x25,
0x47,0x85,0x84,0x37,0x04,0x05,0xff};
uchar data dis_buf[4];
uchar data dis_digit;
uchar data dis_index;
uchar dis_mod=speed_mod;//默認(rèn)顯示速度
uchar n=1;
uchar key=off;//按鍵按下標(biāo)志,默認(rèn)為關(guān)
uchar dis_key=on;//數(shù)碼管顯示開關(guān),默認(rèn)為開
uchar dis_cut=on;//數(shù)碼管顯示模式,默認(rèn)為節(jié)能模式
uchar sleep=off;//睡眠模式,默認(rèn)為關(guān)
uchar time_key=off;//計(jì)時(shí)開關(guān),默認(rèn)為關(guān)
uchar speed_n;
uchar time_check=0;//按鍵去抖動(dòng)
uchar time_wait=0;//關(guān)閉數(shù)碼管的等待時(shí)間
uchar time_sec=0;
uchar time_min=0;
uchar time_hour=0;
uchar timer0_num=0;//計(jì)時(shí)器0的50ms中斷次數(shù)
uchar timer1_num=0;//計(jì)時(shí)器1的50ms中斷次數(shù)
uchar distance_num=0;//檢測到的卡片個(gè)數(shù)
uchar dst_one_sec=0;//1s內(nèi)檢測到的卡片個(gè)數(shù)
uchar distance_10m_num=0;//10m內(nèi)檢測到的卡片個(gè)數(shù)
uchar bit1_code,bit2_code,bit3_code,bit4_code;
uint speed=0;
uint distance=0;
uint v_distance=0;//累積距離
uint time=0;
uint time_real=2;//累積時(shí)間
uint v_speed=0;//平均速度
uint dis_value;//顯示數(shù)值
void delayms(uchar ms)
{ uchar i;
while(ms--)
{
for(i=0;i<120;i++);
}
}
void main()
{ P0=0xff;
P2=0xff;
TMOD=0x11;
TH0=0x3c;
TL0=0xaf;
TH1=0x3c;
TL1=0xaf;
TR0=on;
TR1=on;
IP=0x0b;
IE=0x8f;
IT0=1;
IT1=1;
dis_index=0x00;
dis_digit=0xef;
//----------數(shù)碼管驅(qū)動(dòng)程序------------
while(1)
{ P0=0xff;
P2=0xff;
if((dis_key==on)&&(!sleep))
{if(dis_mod==speed_mod)
{dis_value=speed;}
if(dis_mod==distance_mod)
{dis_value=distance;}
if(dis_mod==v_speed_mod)
{dis_value=v_speed;}
if(dis_mod==time_mod)
{dis_value=time;}
if(dis_mod==v_distance_mod)
{dis_value=v_distance;}
bit4_code=dis_value%10;//顯示最低位
dis_value/=10;
bit3_code=dis_value%10;//顯示次低位
dis_value/=10;
bit2_code=dis_value%10;//顯示次高位
dis_value/=10;
if(dis_value!=0)//最高位滅零
{bit1_code=dis_value%10;}
else
{bit1_code=10;}
dis_buf[0]=dis_code[bit4_code];
dis_buf[1]=dis_code[bit2_code]-4;
dis_buf[2]=dis_code[bit3_code];
dis_buf[3]=dis_code[bit1_code];
P0=dis_buf[dis_index];
P2=dis_digit;
dis_digit*=2;//顯示下一位
if(dis_digit==0xf0)
{dis_digit=0xef;}
dis_index++;
dis_index&=0x03;//4個(gè)數(shù)碼管全部掃描完一遍之后,再回到第一個(gè)開始下一次掃描
delayms(1);
}
}
}
//----------等距檢測中斷函數(shù)-----------
void int0_int()interrupt 0
{distance_num++;
dst_one_sec++;}
//-----------模式切換中斷函數(shù)------------
void int1_int()interrupt 2
{ delayms(10);
if(!key_n)
{if(dis_key&&(dis_mod==time_mod))
{time_key=!time_key;}//暫停/繼續(xù)計(jì)時(shí)
key=on;//按鍵按下標(biāo)志位開啟
sleep=off;//退出睡眠模式
dis_key=on;//顯示開關(guān)開啟
time_wait=0;//開始定時(shí)
}
}
//-----------速度、里程定時(shí)刷新中斷函數(shù)------------
void timer0_int()interrupt 1
{TH0=0x3c;
TL0=0xaf;//設(shè)定50ms定時(shí)初始值
timer0_num++;
if(timer0_num==20)
{timer0_num=0;//定時(shí)1s后重新定時(shí)
distance_10m_num=distance_num/N;//求行駛了多少個(gè)10米的距離
///N=10/(3.14*R/N*dst_one_sec)
distance_num=distance_num%N;
distance=distance+distance_10m_num;
if(time_key)
{v_distance=v_distance+distance_10m_num;}//如果啟動(dòng)計(jì)時(shí)器每秒刷新一次累積距離
if(distance>=65000)
{distance=0;}
if(v_distance>=65000)
{v_distance=0;}
if(dst_one_sec<2)
{n++;
if(n>10)
{n=1;
speed=0;//10s內(nèi)檢測到卡片數(shù)小于2,速度為0
sleep=on;
}
}
else
{sleep=off;
speed=speed_n*dst_one_sec;//計(jì)算速度,speed=3.6*3.14*R/N*dst_one_sec/speed_n*100,speed n為刷新一次速度的時(shí)間
//其中,R為車輪的半徑,N為車輪內(nèi)安裝的卡片數(shù)
//3.6為m/s轉(zhuǎn)化為km/h的因子,100表示顯示到小數(shù)點(diǎn)后兩位
//最高時(shí)速為160km/h,超過此速度時(shí)dst_one_sec溢出
n=1;//每刷新一次速度重新確定刷新周期
dst_one_sec=0;//重新檢測1s內(nèi)的行車距離
}
}
}
//----------定時(shí)關(guān)閉數(shù)碼管中斷函數(shù)----------
void timer1_int()interrupt 3
{TH1=0x3c;
TL1=0xaf;//設(shè)定50ms定時(shí)初始值
timer1_num++;
if(timer1_num==20)//每秒鐘刷新一次時(shí)間值跟平均速度值
{timer1_num=0;
if(time_hour)
{time=time_hour*100+time_min;}//計(jì)時(shí)超過1小時(shí)時(shí)的計(jì)時(shí)方式
else
{time=time_min*100+time_sec;}//計(jì)時(shí)在1小時(shí)內(nèi)的計(jì)時(shí)方式
//-----------按鍵按下后判斷是否為模式切換操作-----------
if(key==on)
{time_wait++;
if(time_wait==3)
{if(!key_n)//按鍵按下超過3秒
{dis_mod++;//切換顯示模式
if(dis_mod==5)
{dis_mod=0;}//五種模式
}
}
if(time_wait==6)
{if((!key_n)&&(dis_mod==distance_mod))//在計(jì)時(shí)器模式切換到里程模式后
//繼續(xù)保持按鍵按下超過3秒
{dis_cut=off;}//關(guān)閉節(jié)能模式
if((!key_n)&&(dis_mod==time_mod))//在計(jì)時(shí)器模式切換到計(jì)時(shí)器模式后
//繼續(xù)保持按鍵按下超過3秒
{dis_cut=on;}//開啟節(jié)能模式
if((!key_n)&&(dis_mod==v_distance_mod))//在計(jì)時(shí)器模式切換到特定距離模式后
//繼續(xù)保持按鍵按下超過3秒
{time_sec=0;
time_min=0;//計(jì)時(shí)器復(fù)位
time_hour=0;
time_real=2;
time_key=off;//停止計(jì)時(shí)
v_distance=0;//重新記錄距離
}
}
if(time_wait==10)
{key=off;
dis_key=on^dis_cut;//10s后根據(jù)節(jié)省模式?jīng)Q定是否關(guān)閉數(shù)碼管
}
}
if(time_key)//計(jì)時(shí)開關(guān)開啟,開始計(jì)時(shí)
{time_sec++;//記錄秒數(shù)
if(time_sec==60)//每分鐘轉(zhuǎn)化一次時(shí)間格式
{time_sec=0;
time_min++;//記錄分鐘數(shù)
if(time_min==60)
{time_min=0;
time_hour++;//記錄小時(shí)數(shù)
if(time_hour==12)//12小時(shí)制格式
{time_hour=0;}
}
}
time_real=time_hour*3600+time_min*60+time_sec;//計(jì)算時(shí)間
}
/********************計(jì)算平均速度***************************
******平均速度v_speed=((v_distance*10)/time_real)*3.6*100***
*********其中,10為求里程的因子,3.6為m/s轉(zhuǎn)化為km/h的因子,100
為保留小數(shù)點(diǎn)后兩位******/
if(dis_mod==v_speed_mod)
{if(v_distance<=50)
//里程小于等于500m時(shí)的平均速度計(jì)算公式
{v_speed=(450*v_distance)/(time_real/2)*4;}
else if(v_distance<=150)
//里程大于500m而小于等于1.5km時(shí)的平均速度計(jì)算公式
{v_speed=(300*v_distance)/(time_real/2)*6;}
else if(v_distance<=300)
//里程大于1.5km而小于等于3km時(shí)的平均速度計(jì)算公式
{v_speed=(150*v_distance)/(time_real/4)*6;}
else if(v_distance<=600)
//里程大于3km而小于等于6km時(shí)的平均速度計(jì)算公式
{v_speed=(90*v_distance)/(time_real/5)*8;}
else if(v_distance<=1500)
//里程大于6km而小于等于15km時(shí)的平均速度計(jì)算公式
{v_speed=(40*v_distance)/(time_real/10)*9;}
else if(v_distance<=10000)
//里程大于15km而小于等于100km時(shí)的平均速度計(jì)算公式
{v_speed=(5*v_distance)/(time_real/20)*36;}
else//里程大于100km時(shí)的平均速度計(jì)算公式
{v_speed=(v_distance)/(time_real/50)*72;}
}
}
}
|
|