|
這是我做的一個(gè)車租車計(jì)費(fèi)作品,用了兩個(gè)星期,附件里包含作品源代碼和芯片資料,清大家多多指教
電路原理圖如下:
多功能出租車計(jì)價(jià)器設(shè)計(jì)原理圖.png (158.8 KB, 下載次數(shù): 116)
下載附件
2018-3-26 17:29 上傳
0.png (44.03 KB, 下載次數(shù): 91)
下載附件
2018-3-27 01:48 上傳
單片機(jī)源程序如下:
- /*************************************************************
- 多功能出租車計(jì)價(jià)系統(tǒng)
- 補(bǔ)充說(shuō)明:
- ***************************************************************/
- #include<reg52.h> //頭文件
- #include<LCD1602.h>
- #include<AT24C02.h>
- #include<INTERRUPT.h>
- #include<SC8065.h>
- #include<DS1302.h>
- /*****************燈、蜂鳴器、按鍵引腳定義*******************/
- sbit led =P3^0; //紅色LED燈
- sbit led2 =P3^1; //綠色LED燈
- sbit key_start =P1^0; //開(kāi)始/結(jié)束計(jì)價(jià)
- sbit key_Wait =P1^1; //電機(jī)開(kāi)始/結(jié)束
- sbit key_set =P1^2; //設(shè)置
- sbit key_jia =P1^3; //加值
- sbit key_jian =P1^4; //減值
- /************************變量定義***********************/
- uint start_price; //起步價(jià)
- uint white_price; //白天單價(jià)
- uint white_Wait; //白天等待超10分鐘后每分鐘價(jià)錢。
- bit start; //開(kāi)始計(jì)價(jià)標(biāo)志,=0非計(jì)價(jià)模式,=1計(jì)價(jià)模式
- double price1; //應(yīng)收總價(jià)錢(帶小數(shù))
- uint mil,Wait,price2; //里程數(shù)、等待時(shí)間、總價(jià)
- uchar set_f; //設(shè)置選擇標(biāo)記,=0未設(shè)置,=1設(shè)置起步價(jià),=2設(shè)置白天公里價(jià),=3設(shè)置時(shí),=4設(shè)置分,=5設(shè)置秒
- bit strat_f; //初始界面顯示標(biāo)志,=0顯示初始界面,=1可能計(jì)價(jià)、設(shè)置、總價(jià)顯示
- uchar num; //循環(huán)計(jì)數(shù)變量
- bit moto_f=0; //電機(jī)控制標(biāo)志,=0關(guān)閉電機(jī),1打開(kāi)電機(jī)
- /********************************************************
- 函數(shù)名稱:void baojia()
- 函數(shù)作用:乘坐結(jié)束進(jìn)行報(bào)價(jià)
- 參數(shù)說(shuō)明:
- ********************************************************/
- void baojia()
- {
- uint temp;
- SC_Speech(1); //先播放一次空的內(nèi)容,防止語(yǔ)音混亂
- //以下里程播報(bào)
- SC_Speech(55); //播放【本次】
- SC_Speech(56); //播放【行程】
- if(mil>=1000) //里程【大于100KM】
- {
- SC_Speech(10+mil/1000); //播放 里程的百位
- SC_Speech(21); //播放【百】
- }
- if(mil>=100) //里程【大于10KM】
- {
- if(mil%1000/100!=0) //如果 里程十位 不為0
- {
- if(mil<1000&&mil%1000/100==1);//只有十幾的時(shí)候不用報(bào)【一】
- else
- SC_Speech(10+mil%1000/100);//播放 里程的十位
- SC_Speech(20); //播放【十】
- }
- else //否則 里程十位 為0
- {
- if(mil%100/10!=0) //如果 里程個(gè)位 不為0
- SC_Speech(10); //播放【零】
- }
- }
- if(mil>=10) //里程【大于1KM】
- {
- if(mil%100/10!=0) //如果 里程個(gè)位 不為0
- SC_Speech(10+mil%100/10); //播放 里程的個(gè)位
- }
- else
- SC_Speech(10); //播放【零】
- if(mil%10!=0) //如果 里程小數(shù) 不為0
- {
- SC_Speech(24); //播放【點(diǎn)】
- SC_Speech(10+mil%10); //播放 里程的小數(shù)位
- }
- SC_Speech(4); //播放【千米】
-
- //以下價(jià)格播報(bào)
- temp=price2/10;
- SC_Speech(58); //播放【共計(jì)】
- if(temp>=1000) //總價(jià)【大于100元】
- {
- SC_Speech(10+temp/1000); //播放 總價(jià)的百位
- SC_Speech(21); //播放【百】
- }
- if(temp>=100) //總價(jià)【大于10元】
- {
- if(temp%1000/100!=0) //如果 總價(jià)十位 不為0
- {
- if(temp<1000&&temp%1000/100==1);//只有十幾的時(shí)候不用報(bào)【一】
- else
- SC_Speech(10+temp%1000/100);//播放 總價(jià)的十位
- SC_Speech(20); //播放【十】
- }
- else //否則 總價(jià)十位 為0
- {
- if(temp%100/10!=0) //如果 總價(jià)個(gè)位 不為0
- SC_Speech(10); //播放【零】
- }
- }
- if(temp>=10) //總價(jià)【大于1元】
- {
- if(temp%100/10!=0) //如果 總價(jià)個(gè)位 不為0
- SC_Speech(10+temp%100/10); //播放 總價(jià)的個(gè)位
- }
- else
- SC_Speech(10); //播放【零】
- if(temp%10==0) //如果 總價(jià)小數(shù)位 為0
- {
- SC_Speech(6); //播放【元】
- SC_Speech(38); //播放【整】
- }
- else //否則 總價(jià)小數(shù)位 不為0
- {
- SC_Speech(24); //播放【點(diǎn)】
- SC_Speech(10+temp%10); //播放 總價(jià)的小數(shù)位
- SC_Speech(6); //播放【元】
- }
- SC_Speech(64); //播放【謝謝】
- }
- /********************************************************
- 函數(shù)名稱:void display()
- 函數(shù)作用:計(jì)價(jià)時(shí)顯示里程、等待時(shí)間函數(shù)
- 參數(shù)說(shuō)明:
- ********************************************************/
- void display()
- {
- if(mil_f==1) //檢測(cè)到一次信號(hào)
- {
- mil_f=0;
- //顯示里程數(shù)
- //LCD_disp_char(9,1,ASCII[mil/1000]); 最大里程為99.9公里
- LCD_disp_char(10,1,ASCII[mil%1000/100]);
- LCD_disp_char(11,1,ASCII[mil%100/10]);
- LCD_disp_char(12,1,'.');
- LCD_disp_char(13,1,ASCII[mil%10]);
- lcd1602_write_character(14,1,"KM");
- if(mil>30) //里程超3公里
- {
- if(time[2]>=7&&time[2]<22) //在白天時(shí)間段
- price1=price1+white_price; //計(jì)算白天總價(jià)【white_price/10=公里價(jià)】
- else //在晚上時(shí)間段
- price1=price1+white_price*1.5; //計(jì)算晚上總價(jià)
- }
- else //小于三公里只收起步價(jià)
- price1=start_price; //計(jì)算總價(jià)【price1/100=總價(jià)】
- }
- if(wait_f==1) //計(jì)時(shí)一秒到
- {
- wait_f=0;
- //顯示等待時(shí)間
- LCD_disp_char(11,2,ASCII[Wait%3600/60/10]);
- LCD_disp_char(12,2,ASCII[Wait%3600/60%10]);
- LCD_disp_char(13,2,':');
- LCD_disp_char(14,2,ASCII[Wait%60/10]);
- LCD_disp_char(15,2,ASCII[Wait%60%10]);
- if(Wait>600&&Wait%60==0) //等待時(shí)間超過(guò)10分鐘后每1分鐘計(jì)費(fèi)
- price1=price1+10; //每分鐘+0.1元
- }
- price2=price1;
- //顯示應(yīng)付金額
- LCD_disp_char(0,1,ASCII[price2/10000]); //顯示應(yīng)付金額百位
- LCD_disp_char(1,1,ASCII[price2%10000/1000]); //顯示應(yīng)付金額十位
- LCD_disp_char(2,1,ASCII[price2%1000/100]); //顯示應(yīng)付金額個(gè)位【price2/100=應(yīng)付金額】
- LCD_disp_char(3,1,'.');
- LCD_disp_char(4,1,ASCII[price2%100/10]);
- LCD_disp_char(5,1,0X01); //顯示字符¥
- //顯示當(dāng)前時(shí)間
- LCD_disp_char(0,2,ASCII[time[2]/10]);
- LCD_disp_char(1,2,ASCII[time[2]%10]);
- LCD_disp_char(2,2,':');
- LCD_disp_char(3,2,ASCII[time[1]/10]);
- LCD_disp_char(4,2,ASCII[time[1]%10]);
- LCD_disp_char(5,2,':');
- LCD_disp_char(6,2,ASCII[time[0]/10]);
- LCD_disp_char(7,2,ASCII[time[0]%10]);
- }
- /********************************************************
- 函數(shù)名稱:void display2()
- 函數(shù)作用:計(jì)價(jià)結(jié)束時(shí)顯示總價(jià)函數(shù)
- 參數(shù)說(shuō)明:
- ********************************************************/
- void display2()
- {
- lcd1602_write_character(3,1,"A total of"); //顯示字符串
-
- LCD_disp_char(5,2,ASCII[price2/10000]);
- LCD_disp_char(6,2,ASCII[price2%10000/1000]);
- LCD_disp_char(7,2,ASCII[price2%1000/100]);
- LCD_disp_char(8,2,'.');
- LCD_disp_char(9,2,ASCII[price2%100/10]);
- LCD_disp_char(10,2,0X01); //顯示字符¥
- }
- /********************************************************
- 函數(shù)名稱:void display3()
- 函數(shù)作用:設(shè)置收費(fèi)參數(shù)時(shí)顯示函數(shù)
- 參數(shù)說(shuō)明:
- ********************************************************/
- void display3()
- {
- if(set_f==1) //顯示起步價(jià)的設(shè)置
- {
- lcd1602_write_character(0,1,"Starting price:"); //顯示字符串
- LCD_disp_char(6,2,ASCII[start_price%1000000/100000]); //起步價(jià)百位
- LCD_disp_char(7,2,ASCII[start_price%10000/1000]); //起步價(jià)十位
- LCD_disp_char(8,2,ASCII[start_price%1000/100]); //起步價(jià)個(gè)位
- LCD_disp_char(9,2,0x01); //顯示字符¥
- }
- if(set_f==2) //顯示設(shè)置每加一公里價(jià)格
- {
- lcd1602_write_character(0,1,"Set unit price:");
- LCD_disp_char(4,2,ASCII[white_price/100]); //顯示公里價(jià)十位【white_price/10=公里價(jià)】
- LCD_disp_char(5,2,ASCII[white_price%100/10]); //顯示公里價(jià)個(gè)位
- LCD_disp_char(6,2,'.');
- LCD_disp_char(7,2,ASCII[white_price%10]); //顯示公里價(jià)十分位
- lcd1602_write_character(9,2,"/KM");
- lcd1602_write_character(8,2,0x01); //顯示字符¥
- }
- }
- /********************************************************
- 函數(shù)名稱:void display4(void)
- 函數(shù)作用:顯示校準(zhǔn)時(shí)間函數(shù)
- 參數(shù)說(shuō)明:
- ********************************************************/
- void display4()
- {
- num++;
- lcd1602_write_character(4,1,"Set Time:");
- if(num%2==0) //偶數(shù)次顯示,奇數(shù)次不顯示。這樣就會(huì)有閃爍效果,可以清楚看到當(dāng)前設(shè)置的是哪個(gè)值
- {
- LCD_disp_char(4,2,ASCII[time[2]/10]); //顯示設(shè)置時(shí)
- LCD_disp_char(5,2,ASCII[time[2]%10]);
- LCD_disp_char(6,2,':');
- LCD_disp_char(7,2,ASCII[time[1]/10]); //顯示設(shè)置分
- LCD_disp_char(8,2,ASCII[time[1]%10]);
- LCD_disp_char(9,2,':');
- LCD_disp_char(10,2,ASCII[time[0]/10]);//顯示設(shè)置秒
- LCD_disp_char(11,2,ASCII[time[0]%10]);
- }
- else //奇數(shù)次不顯示
- {
- switch(set_f)//根據(jù)當(dāng)前設(shè)置的內(nèi)容,對(duì)應(yīng)位置閃爍
- {
- case 3:lcd1602_write_character(4,2," "); break; //按三下設(shè)置時(shí)
- case 4:lcd1602_write_character(7,2," "); break; //按四下設(shè)置分
- case 5:lcd1602_write_character(10,2," "); break; //按五下設(shè)置秒
- default: break;
- }
- }
- }
- /********************************************************
- 函數(shù)名稱:void scan(void)
- 函數(shù)作用:按鍵檢測(cè)函數(shù)
- 參數(shù)說(shuō)明:
- ********************************************************/
- void scan(void)
- {
- //開(kāi)始/結(jié)束計(jì)價(jià)鍵
- if(key_start==0&&set_f==0) //在設(shè)置模式下無(wú)效
- {
- delayms(7); //延時(shí)消抖
- if(key_start==0) //再次確認(rèn)開(kāi)始計(jì)價(jià)按鍵按下
- {
- LCD_write_command(0x01);//清除屏幕顯示
- delay_n40us(100); //延時(shí)等待清除完成
- start=~start; //切換開(kāi)始/結(jié)束計(jì)價(jià)
- strat_f=1; //顯示計(jì)價(jià)界面
- if(start==0) //非計(jì)價(jià)模式下,計(jì)價(jià)結(jié)束。計(jì)算價(jià)格
- {
- led=1; //關(guān)閉紅色指示燈
- led2=0; //開(kāi)啟綠色指示燈
- EX0=0; //關(guān)閉外部中斷
- TR1=1; //開(kāi)啟定時(shí)20S左右自動(dòng)回到初始界面
- moto=1; //關(guān)閉電機(jī)轉(zhuǎn)動(dòng)
- moto_f=0; //關(guān)閉電機(jī)控制標(biāo)志
- display2(); //顯示總價(jià)
- baojia(); //播報(bào)行駛里程和總價(jià)
- mil=0; //清除里程數(shù)
- Wait=0; //清除等待時(shí)間
- TR0=0; //關(guān)閉等待計(jì)時(shí)的定時(shí)器
- }
- else //計(jì)價(jià)開(kāi)始
- {
- led=0; //開(kāi)啟紅色指示燈
- led2=1; //關(guān)閉綠色指示燈
- TR1=0; //關(guān)閉定時(shí)1
- T1_num=0; //重置定時(shí)計(jì)數(shù)變量
- mil_f=1; //計(jì)價(jià)時(shí)顯示里程
- wait_f=1; //計(jì)價(jià)時(shí)顯示等待時(shí)間
- TR0=1; //開(kāi)啟計(jì)等待時(shí)間的定時(shí)器
- EX0=0; //此時(shí)電機(jī)未開(kāi)啟,關(guān)閉外部中斷0,不進(jìn)行里程檢測(cè)
- moto_f=0; //標(biāo)記電機(jī)關(guān)閉
- }
- }
- while(!key_start); //檢測(cè)按鍵松開(kāi)
- }
- if(start==0) //非計(jì)價(jià)模式下
- {
- //設(shè)置鍵
- if(key_set==0) //只有在結(jié)束計(jì)價(jià)才有效
- {
- delayms(7); //延時(shí)消抖
- if(key_set==0) //再次確認(rèn)按鍵按下
- {
- Writeds1302 (WRITE_PROTECT,0X00);//DS1302禁止寫(xiě)保護(hù)
- if(set_f<3)
- {
- TR1=1; //開(kāi)啟定時(shí)1
- T1_num=0; //重置定時(shí)計(jì)數(shù)變量
- LCD_write_command(0x01);//清除屏幕顯示
- delay_n40us(100); //延時(shí)等待清除完成
- }
- set_f++; //設(shè)置選擇變量+1
- strat_f=1; //進(jìn)入設(shè)置界面
- if(set_f==6) //全部參數(shù)設(shè)置完成,退出設(shè)置
- {
- TR1=0; //關(guān)閉定時(shí)器1
- T1_num=0; //重置定時(shí)計(jì)數(shù)變量
- f=1; //標(biāo)記設(shè)置操作完成
- strat_f=0; //退出設(shè)置顯示初始界面
- }
- }
- while(!key_set); //檢測(cè)按鍵松開(kāi)
- }
-
- //加值鍵
- if(key_jia==0)
- {
- delayms(7); //延時(shí)消抖
- T1_num=0; //重置定時(shí)計(jì)數(shù)變量,防止定時(shí)恢復(fù)初始界面
- if(key_jia==0) //再次確認(rèn)按鍵按下
- {
- if(set_f==1) //設(shè)置起步價(jià)
- {
-
- if(start_price<3000) //最大值可設(shè)置3000/100=30元【start_price/100=起步價(jià)】
- start_price+=100; //起步價(jià)+1元
- }
- if(set_f==2) //設(shè)置白天每加一公里價(jià)格
- {
- if(white_price<100) //最大值可設(shè)置100/10=10元【white_price/10=公里價(jià)】
- white_price++; //白天公里價(jià)+0.1元
- }
- if(set_f==3) //設(shè)置小時(shí)
- {
- time[2]++; //小時(shí)+1
- time[2]=(time[2]/10)*16+time[2]%10;//將小時(shí)轉(zhuǎn)換成16進(jìn)制
- if(time[2]>0x23) //判斷是否達(dá)到最大小時(shí)23時(shí)
- time[2]=0x00; //重新回到00時(shí)
- Writeds1302 (WRITE_HOUR,time[2]); //將設(shè)置好的小時(shí)寫(xiě)入到DS1302存儲(chǔ)起來(lái)
- time[2]=Read1302(0x85); //讀取當(dāng)前小時(shí)
- }
- if(set_f==4) //設(shè)置分
- {
- time[1]++;
- time[1]=(time[1]/10)*16+time[1]%10;
- if(time[1]>0x59)
- time[1]=0x00;
- Writeds1302 (WRITE_MINUTE,time[1]);
- time[1]=Read1302(0x83);
- }
- if(set_f==5) //設(shè)置秒
- {
- time[0]++;
- time[0]=(time[0]/10)*16+time[0]%10;
- if(time[0]>0x59)
- time[0]=0x00;
- Writeds1302 (WRITE_SECOND,time[0]);
- time[0]=Read1302(0x81);
- }
- }
- }
- //減值鍵
- if(key_jian==0)
- {
- delayms(7); //延時(shí)消抖
- T1_num=0; //重置定時(shí)計(jì)數(shù)變量
- if(key_jian==0) //再次確認(rèn)按鍵按下
- {
- if(set_f==1) //設(shè)置起步價(jià)
- {
- if(start_price>=100) //最小值可設(shè)置0元
- start_price-=100; //起步價(jià)-1元
- }
- if(set_f==2) //設(shè)置白天每加一公里價(jià)格
- {
- if(white_price!=0) //最小值可設(shè)置0元
- white_price--; //白天公里價(jià)-0.1元
- }
- if(set_f==3) //設(shè)置小時(shí)
- {
- if(time[2]==0) //判斷小時(shí)是否到達(dá)最小小時(shí)0時(shí)
- time[2]=23; //重新回到23時(shí)
- else
- time[2]--; //否則小時(shí)-1
- time[2]=(time[2]/10)*16+time[2]%10;//將小時(shí)轉(zhuǎn)換成16進(jìn)制
- Writeds1302 (WRITE_HOUR,time[2]); //將設(shè)置好的小時(shí)寫(xiě)入到DS1302存儲(chǔ)起來(lái)
- time[2]=Read1302(0x85); //重新讀取小時(shí)
- }
- if(set_f==4) //設(shè)置分
- {
- if(time[1]==0)
- time[1]=59;
- else
- time[1]--;
- time[1]=(time[1]/10)*16+time[1]%10;
- Writeds1302 (WRITE_MINUTE,time[1]);
- time[1]=Read1302(0x83);
- }
- if(set_f==5) //設(shè)置秒
- {
- if(time[0]==0)
- time[0]=59;
- else
- time[0]--;
- time[0]=(time[0]/10)*16+time[0]%10;
- Writeds1302 (WRITE_SECOND,time[0]);
- time[0]=Read1302(0x81);
- }
- }
- }
- }
- else //計(jì)價(jià)模式下
- {
- if(key_Wait==0) //開(kāi)啟/關(guān)閉電機(jī)
- {
- delayms(7); //延時(shí)消抖
- if(key_Wait==0) //再次確認(rèn)按鍵按下
- {
- if(TR0==0) //當(dāng)TR0=0時(shí)moto_f=1,此時(shí)電機(jī)為開(kāi)啟狀態(tài)
- {
- TR0=1; //打開(kāi)定時(shí)器0,開(kāi)始計(jì)等待時(shí)間
- EX0=0; //禁止外部中斷0,不進(jìn)行里程檢測(cè)
- moto_f=0; //標(biāo)記電機(jī)關(guān)閉
- }
- else //當(dāng)TR0=1時(shí)moto_f=0,此時(shí)電機(jī)為關(guān)閉狀態(tài)
- {
- TR0=0; //關(guān)閉定時(shí)器0,停止計(jì)等待時(shí)間
- EX0=1; //INT0中斷允許,檢測(cè)霍爾信號(hào)
- moto_f=1; //標(biāo)記電機(jī)打開(kāi)
- }
- }
- while(!key_Wait); //檢測(cè)按鍵松開(kāi)
- }
- if(key_jia==0) //電機(jī)加速
- {
- delayms(7); //延時(shí)消抖
- if(key_jia==0&&vs<9)//再次確認(rèn)按鍵按下,并且速度還沒(méi)最大9擋
- {
- vs++; //速度等級(jí)+1
- }
- while(!key_jia); //檢測(cè)按鍵松開(kāi)
- }
- if(key_jian==0) //電機(jī)減速
- {
- delayms(7); //延時(shí)消抖
- if(key_jian==0&&vs>4)//再次確認(rèn)按鍵按下,并且速度還沒(méi)最小4擋
- {
- vs--; //速度等級(jí)-1
- }
- while(!key_jian); //檢測(cè)按鍵松開(kāi)
- }
- }
- }
- /********************************************************
- 函數(shù)名稱:void main()
- 函數(shù)作用:主函數(shù)
- 參數(shù)說(shuō)明:
- ********************************************************/
- void main()
- {
- led=1; //紅燈關(guān)閉
- led2=0; //綠燈點(diǎn)亮
- LCD_init(); //LCD1602初始化
- T0_init(); //定時(shí)器0初始化
- Int0_init(); //外部中斷初始化
- if(key_jian==0) //手動(dòng)復(fù)位初始默認(rèn)價(jià)格
- {
- delayms(100);
- if(key_jian==0)
- {
- AT24C02_write_date(1,18); //寫(xiě)入【公里價(jià)】數(shù)據(jù)保存,地址0~255均可
- AT24C02_write_date(5,10); //寫(xiě)入【起步價(jià)】數(shù)據(jù)保存
- }
- }
-
- white_price=AT24C02_read_date(1); //讀取存儲(chǔ)的【公里價(jià)】數(shù)據(jù)
- start_price=AT24C02_read_date(5)*100;//讀取存儲(chǔ)的【起步價(jià)】數(shù)據(jù)
- lcd1602_write_pic(0x01,pic2); //將自定義字符“¥”寫(xiě)入LCD1602
- while(1) //死循環(huán)
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
程序+原理圖.7z
(3.35 MB, 下載次數(shù): 302)
2022-11-15 18:14 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|