- 相關推薦
出租車計價器
南京工業(yè)大學
創(chuàng)新實踐報告
(2011 — 2012 學年 第1 學期)
課程名稱: 出租車計價器設計 班 級: 電子0805 學 號: 11 姓 名: 吾曉于 指導教師: 包亞萍
2011年 11月
一.出租車計價器概述 1.設計要求:
設計一個出租車計價器,該計價器的計費系統(tǒng):行程3公里內,起步費為6元; 3公里外以 每公里1.4元計費.
并能顯示日期和當前時間,行駛公里數(shù),總費用和暫停計價功能. 設計的主要技術指標 :
①計價范圍:0~999.9元 計價分辨率: 0.1元 ②計程范圍:0~99公里 計程分辨率: 1.0公里
本電路以SST89E58單片機為中心、附加555定時器構成多諧振蕩器,組成信號產生電路來實現(xiàn)里程計數(shù),DS1302構成時鐘電路,實現(xiàn)對出租車計價統(tǒng)計,輸出采用LCD液晶顯示器。本電路設計的計價器不但能實現(xiàn)基本的計價,同時還能作為時鐘為司機提供方便。
二.計價器硬件設計
本系統(tǒng)的硬件設計主要包括單片機SST89E58、LCD數(shù)據(jù)顯示部件、555定時器電路、DS1302時鐘電路的設計。在硬件設計過程中,充分利用各部件的功能,實現(xiàn)出租車計價器設計。 1. 系統(tǒng)的硬件構成及功能
它由以下幾個部件組成:SST89E58單片機、總金額及里程顯示、鍵盤控制,里程計算單元、時鐘電路等。
利用單片機豐富的IO端口,及其控制的靈活性,實現(xiàn)基本的里程計價功能和時鐘顯示功能。
2. 單片機及其引腳說明
SST89E58與ATMEL、PHILIPS、WINBOND等公司的8位標準8051系列單片機完全兼容,工作頻率為0~40MHZ,2.7V~5.5V,1K字節(jié)內部SRAM,三個高電流驅動端口(每端口16mA),三個16位定時器/計數(shù)器,全雙工、增強型串口,掉電檢測,低功耗。
SST89E58是一個有40
個引腳的芯片,引腳配置和仿真圖如下圖所示:
其各自引腳功能如下:
Vcc:電源電壓。 GND:地。
P0口:P0口是一組8位漏極開路型雙向I/O接口,也即地址/數(shù)據(jù)總線復用口。當訪問外部數(shù)據(jù)存儲器或程序存儲器時,這組口線分時轉換地址和數(shù)據(jù)總線復用,在訪問期間激活內部上拉電阻。在FLASH編程時,P0口接受指令字節(jié),而在程序校驗時 ,輸出指令字節(jié)。
P1口:P1口是一個帶內部上拉電阻的8位雙向I/O接口,P1的輸出緩沖級
可驅動4個TTL邏輯門電路。FLASH編程和程序校驗時,P1接收低8位地址。
P2口:P2口是一個帶有內部上拉電阻的8位雙向I/O口,P2的輸出緩沖級可驅動4個TTL邏輯門電路。在訪問外部程序存儲器或16位地址的外部數(shù)據(jù)存儲器時P2口送高8位地址數(shù)據(jù)。FLASH編程或校驗時,P2亦接收高位地址和其他控制信號。
P3口:P3口是一組帶有內部上拉電阻的8位雙向I/O接口。P3口輸出緩沖級可驅動4個TTL邏輯門電路。
RST:復位輸入。
ALE/ PROG:當訪問外部數(shù)據(jù)時,ALE(地址鎖存允許)輸出脈沖用于鎖存地址的低8位字節(jié)。
EA/VPP:外部訪問允許。
PSEN:程序儲存允許。PSEN輸出是外部程序存儲器的度選通信號。
XTAL1:振蕩器反相放大及內部是鐘發(fā)生器的輸入端。 XTAL2:振蕩器反相放大器的輸出端。
3. 按鍵單元的設計
電路共采用了六個按鍵和一個開關,S1、S2、S3、S4、S5、S6,其功能分別是:S1光標左移,S2光標右移,S3『+』,S4『-』,S5設定時間,S6暫停。開關為控制計價器工作和停止。
4. 555定時器構成多諧振蕩器
555 定時器是一種模擬和數(shù)字功能相結合的中規(guī)模集成器件。一般用雙極性工藝制作的稱為 555,用 CMOS 工藝制作的稱為 7555,除單定時器外,還有對應的雙定時器 556/7556。555 定時器的電源電壓范圍寬,可在 4.5V~16V 工作,7555 可在 3~18V 工作,輸出驅動電流約為 200mA,因而其輸出可與 TTL、CMOS 或者模擬電路電平兼容。
555構成多諧振蕩器,組成信號產生電路
振蕩周期: T=0.7(R1+2R2)C
輸出高電平時間 T=(R1+R2)Cln2 輸出低電平時間T=R2Cln2
輸出方波的占空比為D=tPH/T=(R1+R2)/(R1+2R2) R1=R2=47KΩ
f=1/T=1.43/( R1+R2)C=150Hz
5.DS1302時鐘電路
DS1302 是美國DALLAS公司推出的一種高性能、低功耗、帶RAM的實時時鐘電路,它可以對年、月、日、周日、時、分、秒進行計時,具有閏年補償功能,工作電壓為2.5V~5.5V。采用三線接口與CPU進行同步通信,并可采用突發(fā)方式一次傳送多個字節(jié)的時鐘信號或RAM數(shù)據(jù)。
DS1302的引腳排列,其中Vcc1為后備電源,VCC2為主電源。在主電源關閉的情況下,也能保持時鐘的連續(xù)運行。DS1302由Vcc1或Vcc2兩者中的較大者供電。當Vcc2大于
Vcc1+0.2V時,Vcc2給DS1302供電。當Vcc2小于Vcc1時,DS1302由Vcc1供電。X1和X2是振蕩源,外接32.768kHz晶振。RST是復位/片選線,通過把RST輸入驅動置高電平來啟動所有的數(shù)據(jù)傳送。RST輸入有兩種功能:首先,RST接通控制邏輯,允許地址/命令序列送入移位寄存器;其次,RST提供終止單字節(jié)或多字節(jié)數(shù)據(jù)的傳送手段。當RST為高電平時,所有的數(shù)據(jù)傳送被初始化,允許對DS1302進行操作。如果在傳送過程中RST置為低電平,則會終止此次數(shù)據(jù)傳送,I/O引腳變?yōu)楦咦钁B(tài)。上電運行時,在Vcc>2.0V之前,RST必須保持低電平。只有在SCLK為低電平時,才能將RST置為高電平。I/O為串行數(shù)據(jù)輸入輸出端(雙向),后面有詳細說明。SCLK為時鐘輸入端。 下圖為DS1302的引腳功能和仿真圖:
6.LCD顯示器
LM016L 的結構及功能
LM016L 液晶模塊采用 HD44780 控制器,hd44780 具有簡單而功能較強的指令集,可以實 現(xiàn)字符移動,閃爍等功能。 液晶模塊的引腳功能如下: VSS 一般接地 VDD 接電源(+5V)
V0 液晶顯示器對比度調整端,接正電源時對比度最弱,接地電源時對比度最高(對比 度過高時會產生"鬼影",使用時可以通過一個 10K 的電位器調整對比度).
RS 為寄存器選擇,高電平 1 時選擇數(shù)據(jù)寄存器,低電平 0 時選擇指令寄存器.
R/W 為讀寫信號線,高電平(1)時進行讀操作,低電平(0)時進行寫操作. E E(或 EN)端為使能(enable)端,下降沿使能. D0—D3 底4位三態(tài), 雙向數(shù)據(jù)總線0-3位 D4—D7 高4位三態(tài), 雙向數(shù)據(jù)總線4-7位
計價器流程圖
總原理圖
計價器程序
//出租車車計價器 設計
//該模擬程序折合規(guī)則:1km-1m,等待30s-1km-1m,1m-1.4元 //底層規(guī)則:若脈沖個數(shù)/秒 #include #include #include #include
uchar code univalent[2] = {1,40}; 價整數(shù)位,[1]-里程單價小數(shù)位
//保存單價的數(shù)組,[0]-里程單
uchar code time_pos[7] = {4,-1,7,10,4,7,10}; //各時間在液晶上的顯示位置
uchar code money_pos[4] = {4,7,4,7}; //計價器價格各位在液晶上的顯示位置
bit config_ok = 0; bit state = 0;
(計里程),1-低速(計時間) bit pause = 0; 價,1-暫停計價
uint pulse_count = 0;
//0-未配置完成,1-配置完成 //當前儀表的運行狀態(tài),0-全速//計價停止狀態(tài)位,0-正常計//脈沖計數(shù)器
//保存等待計時的變量,單位為
uint pulse_count_tmp = 0;
uint time_count = 0; 秒,10s-1km-1.4元
uint mileage_count_new = 0,mileage_count_old = 0; //保存里程的變量,通過差值計
算里程變化,單位為km,1km-1.4元,
uchar idata time[7] = {0x09,0x1,0x1,0x1,0x0,0x0,0x0}; //保存時間的數(shù)組 uint money[2]={6,0}; //保存車費的數(shù)組,[0]-整數(shù)位,[1]-小數(shù)位
uchar first_3_km = 0;
void INT0_init(void); void INT1_init(void); void Delay(uint); void System_init(void);
void Time_Show(uchar time_data[7]);
void Run_Show_Time(uchar time_data[7]); void Money_Show(uint money[2]); void Show_Wait_Time(uint); void Show_Mileage(void);
void Run_BackGround(void);
出現(xiàn)的
void Run_BackGround(void) { WriteChar('/', 3,0); WriteChar(':',10,0); WriteChar(':',13,0); WriteChar('.',3,1);
WriteChar('Y',6,1);
}
void Show_Mileage(void) { WriteDecimal(pulse_count / 200,0,12,1); WriteInt(pulse_count % 200 / 10,0,0,13,1); WriteChar('.',12,1); WriteString("km",14,1);
}
void Show_Wait_Time(uint time_count) { WriteChar('s',15,1); WriteChar(' ', 10,1);
WriteInt(time_count,1,4,11,1);
//運行起來后,將在LCD上一直
void Money_Show(uint money[2]) { WriteDecimal(money[0],0,3,1); WriteDecimal(money[1],1,3,1);
}
void Run_Show_Time(uchar time_data[7]) { WriteInt(BcdToInt(time_data[2]),1,2, 1,0); WriteInt(BcdToInt(time_data[3]),1,2, 4,0); WriteInt(BcdToInt(time_data[4]),1,2, 8,0); WriteInt(BcdToInt(time_data[5]),1,2,11,0); WriteInt(BcdToInt(time_data[6]),1,2,14,0);
}
void Time_Show(uchar time_data[7]) { WriteChar('/',6,0); WriteChar('/',9,0);
WriteChar(':',6,1); WriteChar(':',9,1);
WriteInt(BcdToInt(time_data[0]),1,2, 4,0); WriteInt(BcdToInt(time_data[2]),1,2, 7,0); WriteInt(BcdToInt(time_data[3]),1,2,10,0); WriteInt(BcdToInt(time_data[4]),1,2, 4,1); WriteInt(BcdToInt(time_data[5]),1,2, 7,1); WriteInt(BcdToInt(time_data[6]),1,2,10,1);
}
void System_init(void) { RstLcd(); ClrLcd(); P1 = 0x00; config_ok = 0; Time_Show(time); LcdPos(5,0);
SetCur(3); INT1_init();
while(config_ok == 0); //等待配置時間結束標志
}
SetCur(1);
WriteString("set time over...",0,0); Delay(60000); ClrLcd();
Run_BackGround(); P1= 0xff;
void Delay(uint dtime) { }
uint temp;
for(temp=0;temp
void INT0_init(void) {
EA = 0; IT0 = 1; EX0 = 1; EA = 1;
}
void INT1_init(void) { EA = 0; }
IT1 = 1; EX1 = 1; EA = 1;
void main() {
uchar time_tmp[7],i; System_init();
DS1302_GetData(time);
pulse_count_tmp = pulse_count;
mileage_count_new = mileage_count_old = 0; Money_Show(money); Run_Show_Time(time); Show_Mileage(); while(1)
{
if(config_ok == 0) System_init();
DS1302_GetData(time_tmp);
if(!(P1 & 0x04)) {
P1 &= 0xfe; P1 |= 0x02; pause = 0;
if(time[6] != time_tmp[6]) { }
Run_Show_Time(time_tmp); for(i = 0;i
time[i] = time_tmp[i];
//若設置時間未完成
first_3_km = 0; money[0] = 6; money[1] = 0;
mileage_count_new = mileage_count_old = 0; WriteString(" ",0,1); WriteString(" ",9,1); Money_Show(money); pulse_count = 0; Show_Mileage(); time_count = 0;
}
else if(pause == 0) {
INT0_init();
if(time[6] != time_tmp[6]) {
Run_Show_Time(time_tmp); for(i = 0;i
if(pulse_count - pulse_count_tmp
行駛(計時),即一秒內,脈沖數(shù)目的個數(shù)變化值若小于10,則判為低速
{
state = 1; P1 &= 0xfe; P1 |= 0x02;
time_count ++;
//等待計時加1
if(time_count % 10 == 0 && first_3_km > 2)//由等待時間換算公
里數(shù),10s折合為1km(1m) {
}
}
money[1] += 40; if(money[1] > 99) { }
money[0] += 1; money[1] %= 100;
money[0] += 1; Money_Show(money);
else if(time_count % 10 == 0 && first_3_km
mileage_count_old = mileage_count_new; Show_Wait_Time(time_count);
//否則則判為全速狀
態(tài)(計里程)
}
else {
state = 0; P1 &= 0xfd; P1 |= 0x01; time_count = 0;
//全速狀態(tài)下,把等
待時間清0
}
pulse_count_tmp = pulse_count;
if(state == 0) {
mileage_count_new = pulse_count / 200;
if(mileage_count_new != mileage_count_old && first_3_km > 2) {
Show_Mileage();
for(i = mileage_count_old;i
money[1] += 40; if(money[1] > 99) { }
money[0] += 1; money[1] %= 100;
}
}
}
}
money[0] += 1;
Money_Show(money); }
mileage_count_old = mileage_count_new;
} else if(mileage_count_new != mileage_count_old && first_3_km
first_3_km ++;
mileage_count_old = mileage_count_new; Show_Mileage();
else { }
if(time[6] != time_tmp[6]) { Run_Show_Time(time_tmp); }
for(i = 0;i
static void INT0_ser(void) interrupt 0 { }
pulse_count ++;
static void INT1_ser(void) interrupt 2 {
uchar month_day[12]={31,0,31,30,31,30,31,31,30,31,30,31}; char result; uchar i;
static uchar pos;
//配置時間
if(!(P2 & 0x20) && config_ok == 0) {
for(i = 0;i
if(!(P2 & 0x20) && config_ok == 0) {
//++
//配置到哪一項
result = BcdToInt(time[pos]) + 1;
if((pos == 0 && result == 50) || (pos == 4 && result == 24) || (pos == 5 && result == 60) || (pos == 6 && result == 60)) result = 0; else if(pos == 2 && result == 13)
result = 1; else if(pos == 3) {
month_day[1] = (time[0] % 4 == 0 && time[0] % 100 != 0) || time[0] % if(result == month_day[time[2] - 1] + 1)
result = 1;
400 == 0 ? 29:28;//判斷潤平年
}
time[pos] = IntToBcd(result);
//--
}
else;
}
else if(!(P2 & 0x40) && config_ok == 0) {
for(i = 0;i
if(!(P2 & 0x40) && config_ok == 0) {
result = BcdToInt(time[pos]) - 1; if((pos == 0 && result == -1)) result = 49; else if(pos == 2 && result == 0) result = 12;
else if(pos == 3) { month_day[1]=(time[0] % 4 == 0 && time[0] % 100 != 0) || time[0] %
400 == 0 ? 29:28;//判斷潤平年
if(result == 0)
}
result = month_day[time[2] - 1];
else if(pos == 4 && result == -1) result = 23;
else if((pos == 5 || pos == 6) && result == -1) result = 59; else
;
time[pos] = IntToBcd(result);
} }
else if(!(P2 & 0x08) && config_ok == 0)
//NEXT
{ for(i = 0;i
if(!(P2 & 0x08) && config_ok == 0) { pos++; pos %= 7; if(pos == 1)
pos = 2;
} }
else if(!(P2 & 0x10) && config_ok == 0)
{ for(i = 0;i
if(!(P2 & 0x10) && config_ok == 0) { pos--; if(pos == -1) pos = 6; if(pos == 1)
pos = 0;
}
}
else if(!(P2 & 0x80) && config_ok == 0) { for(i = 0;i
DS1302_Reset();
DS1302_SettingData(time);
}
}
else if(!(P2 & 0x80) && config_ok == 1) { for(i = 0;i
if(!(P2 & 0x80) && config_ok == 1) { config_ok = 0;
}
}
else if(!(P1 & 0x08) && config_ok == 1) {
//PREVIOUS
//ENTER
//CONFIG
}
}
for(i = 0;i
if(!(P1 & 0x08) && config_ok == 1) { pause = ~pause; EX0 = 0; }
if(config_ok == 0) { }
WriteInt(BcdToInt(time[pos]),1,2,time_pos[pos],pos > 3 ?1:0 ); LcdPos(time_pos[pos]+1,pos > 3 ?1:0);
【出租車計價器】相關文章:
出租車計價器作弊與預防05-02
出租車計價器抗干擾問題分析05-01
出租車多功能計價器安裝與調測05-02
計價器外圍故障的調修04-27
出租汽車計價器的發(fā)展與車載GPS04-27
出租汽車計價器檢定應注意的問題04-27
出租汽車計價器抗干擾硬件設計05-02
指紋識別技術在出租汽車計價器的應用04-30