【51单片机】汽车里程表之测速功能
生活随笔
收集整理的這篇文章主要介紹了
【51单片机】汽车里程表之测速功能
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
文章目錄
- 設(shè)計說明
- 流程圖
- 主要代碼
設(shè)計說明
以通用MCS-51單片機為處理核心,用傳感器將車輪的轉(zhuǎn)數(shù)轉(zhuǎn)換為電脈沖,進行處理后送入單片機。里程及速度的測量,是經(jīng)過MCS-51的定時/計數(shù)器測出總的脈沖數(shù)和每轉(zhuǎn)一圈的時間,再經(jīng)過單片機的計算得出,其結(jié)果通過LED顯示器顯示出來。
里程表可以在淘寶上買到成品,我的思路是在成品的基礎(chǔ)上,把電機的電流引到里程表上;除了測速功能外,還可以再加上控速功能,在速度超過某一個固定值后,蜂鳴器響,提示需要減速,同時通過串口發(fā)送標志位給汽車模塊,汽車模塊根據(jù)標志位,控制汽車的PWM占空比,進行減速。
流程圖
計算速度和里程模塊:
報警和測速模塊:
主要代碼
/***********計算速度函數(shù)**************/ void menu_dis() //計算速度函數(shù) {static uchar value;if(menu_1 == 0){ if(flag_1s == 1) { flag_1s = 0; if(flag_en == 0){value ++;if(value >= 3) //2秒{ speed_km = 0; //速度為0shudu = (uint)speed_km; value = 0; }}if((flag_en == 1)){ value = 0; flag_en = 0; //1s = 1 / 1000000us; // 1m/s=0.001km除以1/3600h=3.6km/h f_hz = 1/(t2_num * 65536.0 + TH11 * 256 + TL11) / 1000000 ; //算出來就是秒t2_num = 0; //把變量清零TH11 = 0;TL11 = 0; speed_m = f_hz * zhijing * 3.14 ; //算出來的是m/sjuli_z = (juli_z + (uint)speed_m) ; //總路程m speed_km = speed_m * 3.6 ; //(帶個小數(shù)點) km/s shudu = (uint)speed_km;zong_lc += speed_m;} write_sfm2(1,3,shudu); write_sfm4(2,3,juli_z); }} }/********************獨立按鍵程序*****************/ uchar key_can; //按鍵值void key() //獨立按鍵程序 {static uchar key_new;key_can = 20; //按鍵值還原P3 |= 0x78; //對應(yīng)的按鍵IO口輸出為1if((P3 & 0x78) != 0x78) //按鍵按下{delay_1ms(1); //按鍵消抖動if(((P3 & 0x78) != 0x78) && (key_new == 1)){ //確認是按鍵按下key_new = 0;switch(P3 & 0x78){case 0x70: key_can = 4; break; //得到按鍵值case 0x68: key_can = 3; break; //得到按鍵值case 0x58: key_can = 2; break; //得到按鍵值case 0x38: key_can = 1; break; //得到按鍵值}} }else key_new = 1; }/**********************設(shè)置函數(shù)************************/ void key_with() {if(key_can == 1) //設(shè)置鍵{menu_1++;if(menu_1 == 1) //設(shè)置時間{menu_2 = 1;write_string(1,0," : : W: "); write_string(2,0," 20 - - "); }if(menu_1 == 2) //設(shè)置報警速度{menu_2 = 1;write_string(1,0,"set-sd:00km/h "); write_string(2,0,"zlc: "); }if(menu_1 == 3) //設(shè)置直徑{menu_2 = 1;write_string(1,0," Set Zhijing "); write_string(2,0," "); }menu_2 = 1;if(menu_1 > 3) //回到正常顯示{menu_1 = 0;write_guanbiao(1,2,0); //關(guān)閉光標init_1602(); //1602初始化 //初始化液晶顯示 }}if(key_can == 2) //選擇鍵{if(menu_1 == 1) //設(shè)置時間{menu_2 ++;if(menu_2 > 7)menu_2 = 1;}if(menu_1 == 2) //設(shè)置{menu_2 ++;if(menu_2 > 2)menu_2 = 1; }}if(menu_1 == 1){if(menu_2 == 1) //設(shè)置時{if(key_can == 3) //加{shi+=0x01;if((shi & 0x0f) >= 0x0a)shi = (shi & 0xf0) + 0x10;if(shi >= 0x24)shi = 0;} if(key_can == 4) //減{if(shi == 0x00)shi = 0x24;if((shi & 0x0f) == 0x00)shi = (shi | 0x0a) - 0x10;shi -- ; } }if(menu_2 == 2) //設(shè)置分{if(key_can == 3) //加{fen+=0x01;if((fen & 0x0f) >= 0x0a)fen = (fen & 0xf0) + 0x10;if(fen >= 0x60)fen = 0;} if(key_can == 4) //減 {if(fen == 0x00)fen = 0x5a;if((fen & 0x0f) == 0x00)fen = (fen | 0x0a) - 0x10;fen -- ;} }if(menu_2 == 3) //設(shè)置秒{if(key_can == 3) //加{miao+=0x01;if((miao & 0x0f) >= 0x0a)miao = (miao & 0xf0) + 0x10;if(miao >= 0x60)miao = 0;} if(key_can == 4) //減 {if(miao == 0x00)miao = 0x5a;if((miao & 0x0f) == 0x00)miao = (miao | 0x0a) - 0x10;miao -- ; }}if(menu_2 == 4) //設(shè)置星期{if(key_can == 3) //加{week+=0x01;if((week & 0x0f) >= 0x0a)week = (week & 0xf0) + 0x10;if(week >= 0x08)week = 1;} if(key_can == 4) //減 {if(week == 0x01)week = 0x08;if((week & 0x0f) == 0x00)week = (week | 0x0a) - 0x10;week -- ;} }if(menu_2 == 5) //設(shè)置年{if(key_can == 3) //加{nian+=0x01;if((nian & 0x0f) >= 0x0a)nian = (nian & 0xf0) + 0x10;if(nian >= 0x9a)nian = 1;} if(key_can == 4) //減 {if(nian == 0x01)nian = 0x9a;if((nian & 0x0f) == 0x00)nian = (nian | 0x0a) - 0x10;nian -- ; } }if(menu_2 == 6) //設(shè)置月{if(key_can == 3) //加{yue+=0x01;if((yue & 0x0f) >= 0x0a)yue = (yue & 0xf0) + 0x10;if(yue >= 0x13)yue = 1;} if(key_can == 4) //減 {if(yue == 0x01)yue = 0x13;if((yue & 0x0f) == 0x00)yue = (yue | 0x0a) - 0x10;yue -- ; } }if(menu_2 == 7) //設(shè)置日{if(key_can == 3) //加{ri+=0x01;if((ri & 0x0f) >= 0x0a)ri = (ri & 0xf0) + 0x10;if(ri >= 0x32)ri = 0; } if(key_can == 4) //減 {if(ri == 0x01)ri = 0x32;if((ri & 0x0f) == 0x00)ri = (ri | 0x0a) - 0x10;ri -- ; } }write_sfm2_ds1302(1,2,shi); //顯示時write_sfm2_ds1302(1,5,fen); //顯示分write_sfm2_ds1302(1,8,miao); //顯示秒write_sfm1(1,14,week); //顯示星期 write_sfm2_ds1302(2,3,nian); //顯示年write_sfm2_ds1302(2,6,yue); //顯示月write_sfm2_ds1302(2,9,ri); //顯示日switch(menu_2) // 光標顯示{case 1: write_guanbiao(1,2,1); break;case 2: write_guanbiao(1,5,1); break;case 3: write_guanbiao(1,8,1); break;case 4: write_guanbiao(1,14,1); break;case 5: write_guanbiao(2,3,1); break;case 6: write_guanbiao(2,6,1); break;case 7: write_guanbiao(2,9,1); break;}write_time(); //把時間寫進去} if(menu_1 == 2){ if(menu_2 == 1) //設(shè)置速度{if(key_can == 3) //加{bj_shudu++;if(bj_shudu >= 99)bj_shudu = 99;} if(key_can == 4) //減 {if(bj_shudu != 0)bj_shudu -- ; }} if(menu_2 == 2) //把總量程清零{if(key_can == 3) {zong_lc= 0;} if(key_can == 4) {zong_lc= 0; }} write_sfm2(1,7,bj_shudu); //顯示報警速度write_sfm7(2,4,zong_lc); //顯示switch(menu_2) // 光標顯示{case 1: write_guanbiao(1,6,1); break;case 2: write_guanbiao(2,3,1); break;}}if(menu_1 == 3){ if(key_can == 3) //加{s_zhijing++;if(s_zhijing >= 999)s_zhijing = 999;} if(key_can == 4) //減 {if(s_zhijing != 0)s_zhijing -- ; }zhijing = s_zhijing ;write_sfm2(2,5,s_zhijing); //顯示} }/****************報警函數(shù)***************/ void clock_h_l() {static uchar value; if((shudu >= bj_shudu)){value ++; //消除實際距離在設(shè)定距離左右變化時的干擾{beep = ~beep; //蜂鳴器報警 } }else{beep = 1; } }/******************主程序**********************/ void main() {init_1602(); //1602初始化init_int0();time_init(); //定時器0初始化程序 while(1){ // shudu = 11;key(); //按鍵程序if(key_can < 10){key_with(); }if(flag_200ms == 1){flag_200ms = 0;read_time(); //讀時間init_1602_ds1302(); //顯示時鐘menu_dis(); //計算速度函數(shù)clock_h_l(); //報警函數(shù)}} }/*********************外部中斷0中斷服務(wù)程序************************/ void int0() interrupt 0 {static uchar value=1;switch(value){case 0: t1_num = 0; //第一次就把變量清零TH1 = 0;TL1 = 0;break;case 1: t2_num = t1_num; //保存TH11 = TH1;TL11 = TL1;flag_en = 1;break;} }/*************定時器0中斷服務(wù)程序***************/ void time0_int() interrupt 1 { static uchar value=1;TH0 = 0x3c;TL0 = 0xb0; // 50msvalue++;if(value % 4 == 0)flag_200ms = 1;if(value >= 20) //1秒 才是一秒鐘的速度{value = 0;flag_1s = 1;} }/*************定時器1中斷服務(wù)程序***************/ void time1_int() interrupt 3 {t1_num++; }總結(jié)
以上是生活随笔為你收集整理的【51单片机】汽车里程表之测速功能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 拼多多大数据开发工程师SQL实战解析
- 下一篇: 【代码调试】《FSCE: Few-Sho