基于單片機的自行車里程表設計(有原理圖 仿真電路 源程序 pcb) - 單片機DIY制作 (51hei.com)
上面帖子上的這段程序沒看懂,有人可以幫忙講解下嗎,尤其是下面兩句,速度和里程是怎么計算的呢,速度除以40 的意思是?
count參數(shù)是500ms產(chǎn)生的脈沖數(shù),是這個意思嗎,希望幫忙解釋下,謝謝或者有別的里程速度計算公式可以用在這個程序中實現(xiàn)功能的嗎?
Mileage=Mileage+10*(Velocity/3.6)/2; //里程m=里程+速度km/h/3.6/2
Velocity=count *2*3.14*RADIUS /100000*2*3600 /40;//將500ms的距離經(jīng)過運算得到km/h,將速度/100,方便顯示
完整程序如下:
#include<reg52.h> #define uchar unsigned char #define uint unsigned int #include "Data.h" #include "DS1302.h" #include "AT24C02.h" sbit COUNT_IN=P3^2; //定義1602相關管腳 sbit rs=P1^4; //寄存器選擇位 sbit en=P1^0; //使能信號位 //鍵盤定義 sbit K1=P3^4; //設置時間 sbit K3=P3^6; //減按鍵 sbit K2=P3^5; //加按鍵 sbit K4=P3^7; //設置半徑安全距離 sbit BEEP=P3^0; uint count; unsigned long Velocity,Mileage; uchar code tab1[]={" / / : "}; uchar code tab2[]={" 0.000km 00km/h"}; uchar code tab3[]={"Wheel Radius cm"}; uchar code tab4[]={"Safe Speed km/h"}; uchar code tab5[]={"Sec : "}; uchar Mode=0; uchar bike_set=0; uchar a; char RADIUS,SAFE_SPEED; bit LED_SEC; uchar before_sec; uchar code num[]={ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//1 0x1f,0x01,0x01,0x1f,0x10,0x10,0x1f,0x00,//2 0x1f,0x01,0x01,0x1f,0x01,0x01,0x1f,0x00,//3 0x11,0x11,0x11,0x1f,0x01,0x01,0x01,0x00,//4 0x1f,0x10,0x10,0x1f,0x01,0x01,0x1f,0x00,//5 0x1f,0x10,0x10,0x1f,0x11,0x11,0x1f,0x00,//6 0x1f,0x01,0x01,0x01,0x01,0x01,0x01,0x00,//7 //自定義字符 }; void READS(); void SETS(); void delay(uint x) { uint i,j; for(i=0;i<x;i++) for(j=0;j<110;j++);//延時 } void init() { IT0=1; //INT0負跳變觸發(fā) TMOD=0x01;//定時器工作于方式1 TH0=0x3c; //50ms TL0=0xb0; EA=1; //CPU開中斷總允許 ET0=1;//開定時中斷 EX0=1;//開外部INTO中斷 TR0=1;//啟動定時 } /********液晶寫入指令函數(shù)與寫入數(shù)據(jù)函數(shù),以后可調用**************/ void write_1602com(uchar com)//****液晶寫入指令函數(shù)**** { rs=0;//數(shù)據(jù)/指令置為指令 P0=com;//送入數(shù)據(jù) delay(1); en=1;//拉高使能端,為制造有效的下降沿做準備 delay(1); en=0;//en由高變低,產(chǎn)生下降沿,液晶執(zhí)行命令 } void write_1602dat(uchar dat)//***液晶寫入數(shù)據(jù)函數(shù)**** { rs=1;//數(shù)據(jù)/指令置為數(shù)據(jù) P0=dat;//送入數(shù)據(jù) delay(1); en=1; //en置高電平,為制造下降沿做準備 delay(1); en=0; //en由高變低,產(chǎn)生下降沿,液晶執(zhí)行命令 } void Lcd_ram() //自定義字符集 { uint i,j,k=0,temp=0x40; for(i=0;i<7;i++) { for(j=0;j<8;j++) { write_1602com(temp+j); //寫地址 write_1602dat(num[k]); //寫數(shù)據(jù) k++; } temp=temp+8; } } void lcd_init()//***液晶初始化函數(shù)**** { Lcd_ram(); write_1602com(0x38);//設置液晶工作模式,意思:16*2行顯示,5*7點陣,8位數(shù)據(jù) write_1602com(0x0c);//開顯示不顯示光標 write_1602com(0x06);//整屏不移動,光標自動右移 write_1602com(0x01);//清顯示 write_1602com(0x80);//顯示固定符號從第一行第1個位置之后開始顯示 for(a=0;a<16;a++) { write_1602dat(tab1[a]);//向液晶屏寫固定符號部分 } write_1602com(0x80+0x40);//顯示固定符號寫入位置,從第2個位置后開始顯示 for(a=0;a<16;a++) { write_1602dat(tab2[a]);//寫顯示固定符號 } } void display() { // 1km/h=100m/0.1h 360s // 10km/h=100m/0.01h 36s // 100km/h=100m/0.001h 3.6s if(Mode==0&&bike_set==0) { //讀時間 Ds1302_Read_Time(); //顯示時間 write_1602com(0x80); write_1602dat(0x30+time_buf1[1]/10); write_1602dat(0x30+time_buf1[1]%10); write_1602com(0x80+3); write_1602dat(0x30+time_buf1[2]/10); write_1602dat(0x30+time_buf1[2]%10); write_1602com(0x80+6); write_1602dat(0x30+time_buf1[3]/10); write_1602dat(0x30+time_buf1[3]%10); write_1602com(0x80+9); write_1602dat(0x30+time_buf1[4]/10); write_1602dat(0x30+time_buf1[4]%10); write_1602com(0x80+12); write_1602dat(0x30+time_buf1[5]/10); write_1602dat(0x30+time_buf1[5]%10); write_1602com(0x80+15); write_1602dat(time_buf1[7]-1); if(before_sec!=time_buf1[6]) { before_sec=time_buf1[6]; write_1602com(0x80+11); write_1602dat(':'); LED_SEC=1; } if(LED_SEC==0) { write_1602com(0x80+11); write_1602dat(' '); } write_1602com(0x80+0x40); if(Mileage/1000000==0) write_1602dat(' '); else write_1602dat(0x30+Mileage/1000000);//數(shù)字+0x30得到該數(shù)字LCD顯示碼 if(Mileage%1000000/100000==0) write_1602dat(' '); else write_1602dat(0x30+Mileage%1000000/100000);//數(shù)字+0x30得到該數(shù)字LCD顯示碼 write_1602dat(0x30+Mileage%1000000%100000/10000); write_1602com(0x80+0x40+4); write_1602dat(0x30+Mileage%1000000%100000%10000/1000); write_1602dat(0x30+Mileage%1000000%100000%10000%1000/100); write_1602dat(0x30+Mileage%1000000%100000%10000%1000%100/10); SETS(); write_1602com(0x80+0x40+10); write_1602dat(0x30+Velocity/10); write_1602dat(0x30+Velocity%10);//數(shù)字+30得到該數(shù)字的LCD1602顯示碼 } else if(Mode!=0) { switch(Mode) { case 1: write_1602com(0x80+0x40);//顯示固定符號寫入位置 for(a=0;a<16;a++) { write_1602dat(tab5[a]);//寫顯示固定符號 } write_1602com(0x80+0x40+14); write_1602dat(0x30+time_buf1[6]/10); write_1602dat(0x30+time_buf1[6]%10); write_1602com(0x0F); //打開閃爍 write_1602com(0x80+1); break; case 2: write_1602com(0x80+4); break; case 3: write_1602com(0x80+7); break; case 4: write_1602com(0x80+10); break; case 5: write_1602com(0x80+13); break; case 6: write_1602com(0x80+0x40+15); break; case 7: write_1602com(0x80+15); break; case 8: write_1602com(0x0c); write_1602com(0x80);//顯示固定符號第1行第1個位置后顯示 for(a=0;a<16;a++) { write_1602dat(tab1[a]);//向液晶屏寫固定符號部分 } write_1602com(0x80+0x40);//顯示固定符號寫入位置,從第2個位置后開始顯示 for(a=0;a<16;a++) { write_1602dat(tab2[a]);//寫顯示固定符號 } break; } } else if(bike_set!=0) { switch(bike_set) { case 1: write_1602com(0x80);//顯示固定符號寫入位置 for(a=0;a<16;a++) { write_1602dat(tab3[a]);//寫顯示固定符號 } write_1602com(0x80+0x40);//顯示固定符號寫入位置 for(a=0;a<16;a++) { write_1602dat(tab4[a]);//寫顯示固定符號 } write_1602com(0x80+12); write_1602dat(0x30+RADIUS/10); //車輪半徑 write_1602dat(0x30+RADIUS%10); write_1602com(0x80+0x40+10); write_1602dat(0x30+SAFE_SPEED/10); //安全速度 write_1602dat(0x30+SAFE_SPEED%10); write_1602com(0x0F); //打開閃爍 write_1602com(0x80+13); break; case 2: write_1602com(0x80+0x40+11); break; case 3: write_1602com(0x0c); write_1602com(0x80);/ for(a=0;a<16;a++) { write_1602dat(tab1[a]);//向液晶屏寫固定符號部分 } write_1602com(0x80+0x40);//從第2個位置后顯示 for(a=0;a<16;a++) { write_1602dat(tab2[a]);//寫顯示固定符號 } break; } } } void KEY() { if(bike_set==0&&K1==0) { delay(20); if(bike_set==0&&K1==0) { BEEP=0; delay(50); BEEP=1; Mode++; display(); if(Mode>=8) { Mode=0; Ds1302_Write_Time(); } } while(bike_set==0&&K1==0); } if(K4==0&&Mode==0) { delay(20); if(K4==0&&Mode==0) { BEEP=0; delay(50); BEEP=1; bike_set++; display(); if(bike_set>=3) { bike_set=0; SETS(); } } while(Mode==0&&K4==0); } //+ if(K2==0&&(Mode!=0||bike_set!=0)) { delay(20); //調時 if(K2==0&&(Mode!=0||bike_set!=0)) { BEEP=0; delay(50); BEEP=1; switch(Mode) { case 1: time_buf1[1]++; if(time_buf1[1]>=100) time_buf1[1]=0; write_1602com(0x80); write_1602dat(0x30+time_buf1[1]/10); write_1602dat(0x30+time_buf1[1]%10); write_1602com(0x80+1); break; case 2: time_buf1[2]++; if(time_buf1[2]>=13) time_buf1[2]=1; write_1602com(0x80+3); write_1602dat(0x30+time_buf1[2]/10); write_1602dat(0x30+time_buf1[2]%10); write_1602com(0x80+4); break; case 3: time_buf1[3]++; if(time_buf1[3]>=YDay(time_buf1[1],time_buf1[2])+1) time_buf1[3]=1; write_1602com(0x80+6); write_1602dat(0x30+time_buf1[3]/10); write_1602dat(0x30+time_buf1[3]%10); write_1602com(0x80+7); break; case 4: time_buf1[4]++; if(time_buf1[4]>=24) time_buf1[4]=0; write_1602com(0x80+9); write_1602dat(0x30+time_buf1[4]/10); write_1602dat(0x30+time_buf1[4]%10); write_1602com(0x80+10); break; case 5: time_buf1[5]++; if(time_buf1[5]>=60) time_buf1[5]=0; write_1602com(0x80+12); write_1602dat(0x30+time_buf1[5]/10); write_1602dat(0x30+time_buf1[5]%10); write_1602com(0x80+13); break; case 6: time_buf1[6]++; if(time_buf1[6]>=60) time_buf1[6]=0; write_1602com(0x80+0x40+14); write_1602dat(0x30+time_buf1[6]/10); write_1602dat(0x30+time_buf1[6]%10); write_1602com(0x80+0x40+15); break; case 7: time_buf1[7]++; if(time_buf1[7]>=8) time_buf1[7]=1; write_1602com(0x80+15); write_1602dat(time_buf1[7]-1); write_1602com(0x80+15); break; } switch(bike_set) { case 1: RADIUS++; if(RADIUS>=71) RADIUS=0; write_1602com(0x80+12); write_1602dat(0x30+RADIUS/10); write_1602dat(0x30+RADIUS%10); write_1602com(0x80+13); break; case 2: SAFE_SPEED++; if(SAFE_SPEED>=100) SAFE_SPEED=0; write_1602com(0x80+0x40+10); write_1602dat(0x30+SAFE_SPEED/10); write_1602dat(0x30+SAFE_SPEED%10); write_1602com(0x80+0x40+11); break; } } while(K2==0); } if(K3==0&&(Mode!=0||bike_set!=0)) { delay(20); //調時 if(K3==0&&(Mode!=0||bike_set!=0)) { BEEP=0; delay(50); BEEP=1; switch(Mode) { case 1: time_buf1[1]--; if(time_buf1[1]<0) time_buf1[1]=99; write_1602com(0x80); write_1602dat(0x30+time_buf1[1]/10); write_1602dat(0x30+time_buf1[1]%10); write_1602com(0x80+1); break; case 2: time_buf1[2]--; if(time_buf1[2]<=0) time_buf1[2]=12; write_1602com(0x80+3); write_1602dat(0x30+time_buf1[2]/10); write_1602dat(0x30+time_buf1[2]%10); write_1602com(0x80+4); break; case 3: time_buf1[3]--; if(time_buf1[3]<=0) time_buf1[3]=YDay(time_buf1[1],time_buf1[2]); write_1602com(0x80+6); write_1602dat(0x30+time_buf1[3]/10); write_1602dat(0x30+time_buf1[3]%10); write_1602com(0x80+7); break; case 4: time_buf1[4]--; if(time_buf1[4]<0) time_buf1[4]=23; write_1602com(0x80+9); write_1602dat(0x30+time_buf1[4]/10); write_1602dat(0x30+time_buf1[4]%10); write_1602com(0x80+10); break; case 5: time_buf1[5]--; if(time_buf1[5]<0) time_buf1[5]=59; write_1602com(0x80+12); write_1602dat(0x30+time_buf1[5]/10); write_1602dat(0x30+time_buf1[5]%10); write_1602com(0x80+13); break; case 6: time_buf1[6]--; if(time_buf1[6]<0) time_buf1[6]=59; write_1602com(0x80+0x40+14); write_1602dat(0x30+time_buf1[6]/10); write_1602dat(0x30+time_buf1[6]%10); write_1602com(0x80+0x40+15); break; case 7: time_buf1[7]--; if(time_buf1[7]<1) time_buf1[7]=7; write_1602com(0x80+15); write_1602dat(time_buf1[7]-1); write_1602com(0x80+15); break; } switch(bike_set) { case 1: RADIUS--; if(RADIUS<0) RADIUS=70; write_1602com(0x80+12); write_1602dat(0x30+RADIUS/10); write_1602dat(0x30+RADIUS%10); write_1602com(0x80+13); break; case 2: SAFE_SPEED--; if(SAFE_SPEED<0) SAFE_SPEED=99; write_1602com(0x80+0x40+10); write_1602dat(0x30+SAFE_SPEED/10); write_1602dat(0x30+SAFE_SPEED%10); write_1602com(0x80+0x40+11); break; } } while(K3==0); } if(K2==0&&K3==0&&Mode==0&bike_set==0) { BEEP=0; delay(100); BEEP=1; delay(100); BEEP=0; delay(100); BEEP=1; delay(100); Mileage=0; SETS(); while(K2==0&&K3==0); } } void BJ_SAFE() { if(Velocity>SAFE_SPEED) { BEEP=0; } else { BEEP=1; } } void main() { //初始化 Ds1302_Init(); lcd_init(); initeeprom(); //讀取初始參數(shù) READS(); //定時器初始化 // InitTimer0(); init(); lcd_init(); before_sec=time_buf1[6]; while(1) { if(Mode==0&&bike_set==0) { display(); BJ_SAFE(); } KEY(); } void EXINT0() interrupt 0 { count++; } void time0() interrupt 1 { uchar m,n; TH0=0x3c; TL0=0xb0; //50ms m++; if(LED_SEC==1) { n++; if(n>=10) { n=0; LED_SEC=0; } } if(m>=10) { m=0; Mileage=Mileage+10*(Velocity/3.6)/2; //里程m=里程+速度km/h/3.6/2 Velocity=count *2*3.14*RADIUS /100000*2*3600 /40;//將500ms的距離經(jīng)過運算得到km/h,將速度/100,方便顯示 count=0; } } //讀初值 void READS() { uchar Mileage_H,Mileage_M,Mileage_L; delay(10); RADIUS=read_add(0x01); delay(10); SAFE_SPEED=read_add(0x02);
delay(10); Mileage_H=read_add(0x03); delay(10); Mileage_M=read_add(0x04); delay(10); Mileage_L=read_add(0x05); Mileage=Mileage_H*100000+Mileage_M*1000+Mileage_L*10; } //寫初值 void SETS() { delay(10); write_add(0x01,RADIUS); delay(10); write_add(0x02,SAFE_SPEED); /* Mileage_H=Mileage/10000; //123.4560 Mileage_M=Mileage%10000/100; Mileage_L=Mileage%10000%100; */ delay(10); write_add(0x03,Mileage/100000); delay(10); write_add(0x04,Mileage%100000/1000); delay(10); write_add(0x05,Mileage%100000%1000/10);
|