本帖最后由 1五湖四海1 于 2011-8-1 20:38 編輯
上班以后,路程比較遠就很少騎車了,最近單位發(fā)了一臺自行車。周末休息時上公園騎了幾圈;貋砗笙肴绻袀速度表就好了,看看自己能騎到多少Km/h。自己是個愛制作DIY的電子愛好者,坐著想了一個設(shè)計方案。這個要有里程表有速度顯示和行駛時間顯示。這些功能只要一個功能強大的單片機就可以完成要求。 功能上采用6個數(shù)碼管做顯示,打開后左邊三位顯示里程數(shù)單位為Km,右邊兩位顯示速度單位為Km/h。當(dāng)按下轉(zhuǎn)換按鈕后,顯示內(nèi)容切換到顯示行駛時間,左邊兩位顯示小時,右邊兩位顯示分鐘,秒信號用中間小數(shù)點閃爍顯示。再次按下轉(zhuǎn)換按鈕時,所以數(shù)碼管關(guān)閉以節(jié)省電能,再按下轉(zhuǎn)換按鈕回到顯示里程速度。 那天坐公交車,汽車突然啟動時,這時有個加速度到勻速行駛。這讓我想起水銀開關(guān),利用水銀開關(guān)成45度角放置在垂直平面水銀開關(guān)頭朝后。這樣就可以完成加速度檢測了。如果車停止或勻速前進時水銀開關(guān)閉合。一旦汽車啟動或加速后水銀開關(guān)斷開,等到勻速后水銀開關(guān)再次閉合。只有計算出從閉合到斷開再到閉合的時間就可以知道加速度大小了。同樣原理可以制成減速檢測。我利用這一原理將加速度檢測加到了自行車速度里程表。我還利用555制作了一個1KHz的頻率信號輸入到揚聲器做提示音,如果超速時發(fā)出提示音。 我制作這個自行車速度里程表出于自己對DIY單片機興趣愛好,我認為在實用性上也很方便可以測速度,里程,行駛時間和加速度而且還帶揚聲器超速時提示,用起來蠻好的。 自行車速度里程表由硬件和軟件組成,硬件是由單片機最小系統(tǒng)加六位掃描數(shù)碼管和霍爾速度傳感器構(gòu)成。軟件用C語言編寫的下面是源程序還有單片機原理圖
8952.jpg (218.02 KB, 下載次數(shù): 167)
下載附件
2011-8-1 19:04 上傳
PIC110801162634.jpg (350.57 KB, 下載次數(shù): 156)
下載附件
2011-8-1 19:22 上傳
PIC110801162524.jpg (419.19 KB, 下載次數(shù): 148)
下載附件
2011-8-1 19:23 上傳
///////////2010.08.09.21:00/////////////////// #include<reg52.h> #include<absacc.h> #include <intrins.h> #define uint unsigned int #define uchar unsigned char #define shum P1 //數(shù)碼 #define saom P2 //數(shù)碼掃描 unsigned char code xsjs[]={~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F ,~0x00}; char disp[4]={0,0,0,0}; uchar T0count; //從T0的計數(shù)單元中讀取計數(shù)的數(shù)值 uchar timecount; // bit flag; bit d_05s=0; uchar set=0; uchar sp=30; //標(biāo)志位 unsigned long x; unsigned long z; unsigned long y; unsigned long a; unsigned long d; uchar hour=0,min=0,sec=0; uchar xPos,yPos; uchar i; uchar she=30; V[7]; uint j=0; sbit P0_1=P0^1; sbit P2_1=P2^1; sbit P1_7=P1^7; sbit P3_1=P3^1; sbit P3_2=P3^2; sbit P3_4=P3^4; sbit P3_5=P3^5; sbit P3_6=P3^6; sbit P3_7=P3^7; void delay(uint k) { uint i,j; for(i=0;j<k;i++) { for(j=0;j<121;j++); } } void scan_key() { delay(1); if(P3_2==0)set++; if(set>=3)set=0; if(set==1)flag=0x55; F0:if(P3_2==0)goto F0; } void display_led()//數(shù)碼管模塊 {char e,scan; disp[0]=hour/10; disp[1]=hour%10; disp[2]=min/10; disp[3]=min%10; P0=0xff; scan=0xdf; for(e=0;e<4;e++) { shum=0xff; saom=scan; if(d_05s==1) {if(e==1)P1_7=0;else P1_7=1;}
P1=xsjs[disp[e]]; delay(4); scan>>=1; } } void lidisp() { d=a/7;
P1=xsjs[y/10000]; P2=0xdf;delay(1); P1=xsjs[y%10000/1000]; P1_7=0; P2=0xef; delay(1); P1=xsjs[y%1000/100]; P2=0xf7;delay(1); P1=xsjs[10]; P2=0xfb;delay(1); P1=xsjs[d/10]; P2=0xfd;delay(1); P1=xsjs[d%10]; P2=0xfe;delay(1); }
void main(void) {
TMOD=0x15; //T0工作為16位計數(shù)器(方式1),T1工作方式為16位定時器 TH0=0; //計數(shù)為65536 TL0=0; // TH1=(65536-12000)/256; //定時器采用定時4ms. 初值為12000 TL1=(65536-12000)%256; TR1=1; //TR1=1,控制開關(guān)閉合,計數(shù)脈沖進入T1計數(shù)器,啟動定時 TR0=1; //TR0=1,控制開關(guān)閉合,計數(shù)脈沖進入T1計數(shù)器,啟動計數(shù) ET0=1; //定時器0開中斷 ET1=1; //定時器1開中斷 EA=1; //CPU開中斷 y=0; while(1) { if(P3_1==1) {
if(P3_2==0)scan_key(); switch(set) { case 0: lidisp(); break; case 1: display_led(); break; case 2: P1=0xff; break; default:break; }
if(flag==1) // { flag=0; //清標(biāo)志位 z=2*(T0count*65536+TH0*256+TL0); //取得時間寬度參數(shù) x=z*36/10; y=z+y;
if(j==0)
{ V[0]=x; V[1]=x; V[2]=x; V[3]=x; V[4]=x; V[5]=x; V[6]=x; j++; } if(0<j<=7) { V[j]=x; j++; } if(j>7) { j=0;V[j]=x; j++; } a=V[0]+V[1]+V[2]+V[3]+V[4]+V[5]+V[6];
timecount=0; T0count=0; TH0=0; TL0=0; TR0=1; //TR0=1,控制開關(guān)閉合,計數(shù)脈沖進入T1計數(shù)器,啟動計數(shù) } } else {if(P3_6==0)she++;if(P3_5==0)she--; P1=xsjs[she/10]; P2=0xfd;delay(5); P1=xsjs[she%10]; P2=0xfe;delay(5); } } } //;================================================================================== void t0() interrupt 1 using 0 //T0中斷服務(wù) { T0count++; //對P3。4口的脈沖進行計數(shù) } //;================================================================================== void t1(void) interrupt 3 using 0 //T1中斷服務(wù) { TH1=(65536-12000)/256; //計數(shù)初值重裝載 TL1=(65536-12000)%256; timecount++; if(timecount==250) { sec++; TR0=0; timecount=0; flag=1; // 置標(biāo)志 } if(timecount<=125)d_05s=0; else d_05s=1; if(sec==60){min++;sec=0;} if(min==60){hour++;min=0;} if(hour==24){hour=0;} }
|