第一篇:出租車計(jì)價(jià)器信息
霍市質(zhì)監(jiān)局集中對(duì)全市出租車計(jì)價(jià)器進(jìn)行安裝檢定
切實(shí)規(guī)范運(yùn)營(yíng)行為
近期,霍市質(zhì)監(jiān)局下屬檢測(cè)中心對(duì)全市范圍內(nèi)具有交通主管部門頒發(fā)經(jīng)營(yíng)許可證的500余輛出租車計(jì)價(jià)器進(jìn)行統(tǒng)一更換、安裝和檢定。
目前,我市城區(qū)共有出租車546臺(tái),均未安裝計(jì)價(jià)器,出租車運(yùn)營(yíng)過程中多是約定俗成定價(jià)或協(xié)議運(yùn)價(jià),由于出租車運(yùn)價(jià)不規(guī)范,乘客和營(yíng)運(yùn)車輛之間關(guān)于計(jì)費(fèi)的分歧爭(zhēng)論不斷,拒載現(xiàn)象時(shí)有發(fā)生。隨著我市城區(qū)規(guī)模不斷擴(kuò)大,市區(qū)出租車行駛距離逐漸增加,安裝出租車計(jì)價(jià)器已勢(shì)在必行。為切實(shí)加強(qiáng)我市出租車行業(yè)的規(guī)范管理,規(guī)范出租車行業(yè)的有序運(yùn)營(yíng),保障乘客和出租車經(jīng)營(yíng)者的合法權(quán)益,市質(zhì)監(jiān)局、工商局、交通局等多個(gè)部門聯(lián)合舉行了聽證會(huì),并對(duì)出租車計(jì)價(jià)器更換等相關(guān)事宜進(jìn)行了協(xié)調(diào),由質(zhì)監(jiān)局統(tǒng)一負(fù)責(zé)對(duì)全市出租車計(jì)價(jià)器的安裝和檢定任務(wù),確保2015年1月1日后,全市所有的出租車均實(shí)行計(jì)價(jià)打表收費(fèi)。
為保證按時(shí)完成工作任務(wù),霍市質(zhì)監(jiān)局計(jì)量所自接到安裝、檢定計(jì)價(jià)器任務(wù)后,該所全體同志不分工作性質(zhì),不論職務(wù)高低,團(tuán)結(jié)一致、齊心協(xié)力,發(fā)揚(yáng)吃苦耐勞、連續(xù)作戰(zhàn)的工作作風(fēng),頂著嚴(yán)寒,加班加點(diǎn),以扎實(shí)高效的工作作風(fēng),贏得了出租車經(jīng)營(yíng)者的一致好評(píng)。(韓君燕)
第二篇:出租車計(jì)價(jià)器
基于單片機(jī)的出租車計(jì)價(jià)器設(shè)計(jì)
摘要
出租車計(jì)價(jià)器的數(shù)字系統(tǒng)的設(shè)計(jì)正是基于一些專用的芯片,才發(fā)揮其有效特性,從而實(shí)現(xiàn)出租車的計(jì)價(jià)功能。此數(shù)字系統(tǒng)主要分為三個(gè)單元,即里程計(jì)數(shù)及顯示單元、價(jià)格計(jì)數(shù)及顯示單元、脈沖產(chǎn)生。本設(shè)計(jì)是一個(gè)基于單片機(jī)AT89C51的出租車自動(dòng)計(jì)費(fèi)設(shè)計(jì),附有復(fù)位電路,時(shí)鐘電路等。關(guān)鍵詞:出租車計(jì)費(fèi)器;單片機(jī);控制
Abstract Taximeter design digital system is based on some special chip, to play their effective characteristics, thus realizing the taxi valuation function.This system is mainly divided into there modules, namely the mileage counting and display unit, and display unit price counting, pulsing.The design is based on a single chip AT89C51taxis design, a reset circuit, clock circuit.Keywords:taximeter,a single-chip microcomputer,control
1引言
1.1 設(shè)計(jì)目的
近幾年來,出租汽車行業(yè)在各地得以蓬勃發(fā)展,但采用模擬電路和數(shù)字電路設(shè)計(jì)的計(jì)價(jià)器整體電路的規(guī)模較大,用到的器件多,造成故障率高,難調(diào)試。而采用單片機(jī)進(jìn)行的設(shè)計(jì),相對(duì)來說功能強(qiáng)大,用較少的硬件和適當(dāng)?shù)能浖嗷ヅ浜峡梢院苋菀椎貙?shí)現(xiàn)設(shè)計(jì)要求,且靈活性強(qiáng)。
1.2 功能要求
(1)用前4位數(shù)碼管實(shí)時(shí)顯示里程數(shù),單位為千米,最后一位為小數(shù)位;用后4位數(shù)碼管時(shí)時(shí)顯示金額數(shù),單位為元,最后一位為小數(shù)位。
(2)規(guī)定出租車?yán)锍绦∮?千米收費(fèi)5元,超過2千米收費(fèi)為8*(way-20)/5。
1.3 設(shè)計(jì)方法
本設(shè)計(jì)采用AT89C51單片機(jī)為主控器,并用頻率信號(hào)發(fā)生器模擬車速,利用AT89C51的定時(shí)器工作在方式1下定時(shí)實(shí)現(xiàn)對(duì)出租車的計(jì)價(jià)設(shè)計(jì),輸出采用共陰極的集成8位7段數(shù)碼顯示管。設(shè)計(jì)方案及原理
2.1 設(shè)計(jì)方案
采用AT89C51單片機(jī)為主控器,并用頻率信號(hào)發(fā)生器模擬車速,利用AT89C51的定時(shí)器/定時(shí)器T1工作在方式1下定時(shí)實(shí)現(xiàn)對(duì)出租車的計(jì)價(jià)設(shè)計(jì),輸出采用共陰極的集成8位7段數(shù)碼顯示管。本電路設(shè)計(jì)的計(jì)價(jià)器不但能實(shí)現(xiàn)基本的計(jì)價(jià),而且
單片機(jī)原理及系統(tǒng)課程設(shè)計(jì)報(bào)告
還能根據(jù)里程來調(diào)節(jié)單價(jià)。
2.2 設(shè)計(jì)原理
出租車計(jì)價(jià)是根據(jù)車所行駛的路程以及乘客乘車的里程綜合決定的。出租車行駛總路程可以通過車輪的周長(zhǎng)乘車輪旋轉(zhuǎn)圈數(shù)得到。即可計(jì)算得到車輪旋轉(zhuǎn)幾周出租車能行駛一公里的路程。通過計(jì)數(shù)接收到的脈沖個(gè)數(shù),計(jì)算出當(dāng)前所行駛的路程。同時(shí),通過數(shù)碼管顯示當(dāng)前的行駛里程和需支付的車費(fèi)。出租車計(jì)價(jià)器用于記錄里程、起步公里數(shù)與價(jià)格的關(guān)系。模擬出租車計(jì)價(jià)器能根據(jù)總里程數(shù)、起步公里數(shù)的情況作出相應(yīng)報(bào)價(jià)等。這個(gè)系統(tǒng)以AT89C51單片機(jī)為主控器,單片機(jī)的計(jì)數(shù)器/定時(shí)器T1工作在方式1下來對(duì)外部脈沖計(jì)數(shù),最后通過集成的8位7段LED數(shù)碼管顯示里程數(shù)和價(jià)錢。總體模塊框圖如圖1所示。
總金額顯示單價(jià)顯示AT89C51脈沖產(chǎn)生動(dòng)態(tài)掃描數(shù)碼管顯示
圖1 總體框圖 硬件設(shè)計(jì)
對(duì)于AT89C51的計(jì)數(shù)器/定時(shí)器T1,通過對(duì)寄存器TCON的設(shè)置,即使它的M1M0=01,計(jì)數(shù)器/定時(shí)器T1工作在方式1下,構(gòu)成16位計(jì)數(shù)器/定時(shí)器。此時(shí)TH0、TL0都是8位加法計(jì)數(shù)器。此設(shè)計(jì)中,T1為計(jì)數(shù)工作方式,計(jì)數(shù)范圍為1~2^16=1~65536(個(gè)外部脈沖)。當(dāng)計(jì)數(shù)溢出時(shí)則置位并申請(qǐng)中斷,進(jìn)入中斷服務(wù) 執(zhí)行中斷程序。
通過74HC138接P20、P21、P22輸出來對(duì)8位7段的智能掃描LED進(jìn)行段選,并且通過P1口對(duì)LED進(jìn)行位選,最后將結(jié)果顯示在LED上。硬件設(shè)計(jì)圖如圖2所示。
74HC138是三八譯碼器,在工作之前,使74HC138的使能端有效,再使74HC138的A、B、C接P20、P21、P22的輸出達(dá)到對(duì)LED位選線的控制,使相應(yīng)的位顯示相應(yīng)的結(jié)果。硬件總設(shè)計(jì)圖如圖2所示。
第三篇:出租車計(jì)價(jià)器調(diào)試報(bào)告
出租車計(jì)價(jià)器調(diào)試報(bào)告
本設(shè)計(jì)可分為單片機(jī)主控模塊、鍵盤、顯示器、溫度檢測(cè)、狀態(tài)指示、時(shí)鐘日歷、語音收錄播報(bào)、分頻器電路、脈沖信號(hào)發(fā)生器等9部分。仔細(xì)分析系統(tǒng)的工作原理,分別按照模塊在系統(tǒng)中的作用,對(duì)各個(gè)模塊分別單獨(dú)調(diào)試,最后形成該系統(tǒng)的用戶程序,實(shí)現(xiàn)功能要求。
一、接通電源
調(diào)試要求:1.首先仔細(xì)檢查該系統(tǒng)板的電源和地是否有短路問題,在未接入電源輕快下,使用萬用表檢驗(yàn)電源和地檢查是否短路,如果沒有短路,再仔細(xì)核查電源極性后予以通電,觀察電源指示燈D1是否點(diǎn)亮。如果電源指示的燈不亮應(yīng)立即關(guān)閉電源,并用手觸摸各個(gè)芯片,檢查是否用某芯片發(fā)熱。如果沒有發(fā)熱的器件,很可能是電源指示二極管極性安裝錯(cuò)誤,或者是該發(fā)光二極管的串聯(lián)電阻阻值偏大。
2.黑板上調(diào)試要求:(1)焊接好電路板加電前,用萬用表測(cè)量板上Vcc 和
GND之間的電阻,應(yīng)大于1KΩ
(2)加電后測(cè)量電路板上各電壓,應(yīng)大于4.2V 調(diào)試結(jié)果:1.經(jīng)萬用表檢驗(yàn),電路板無短路問題。
2.通電后,D1指示燈點(diǎn)亮。
3.測(cè)量Vcc 與 地之間的電阻,1.14KΩ > 1KΩ
4.測(cè)量Vcc與 地之間的電壓:4.28V > 4.20V
二、測(cè)試狀態(tài)指示
本系統(tǒng)中狀態(tài)指示二極管共有3個(gè),它們分別是D1、D2、D3。D1是指示電源的,可以在電源接通時(shí)直接看到,D2用于指示語音芯片的工作狀態(tài),留作語音模塊調(diào)試時(shí)觀察。D3是可以由單片機(jī)的引腳控制的。
編寫測(cè)試D3的程序: #include
sbit a_c=P1^0;extern serial_initial();
main(){ serial_initial();a_c=0;while(1);}
測(cè)試結(jié)果: 1.2.三、脈沖信號(hào)發(fā)生器測(cè)試
測(cè)試要求:該模塊由5G555芯片構(gòu)成一個(gè)多諧振蕩器,使用示波器觀察該芯片的第3引腳的波形,并調(diào)節(jié)電位器W1,觀察輸出波形及頻率變化。
測(cè)試結(jié)果:
調(diào)整W1前,f=147.1Hz
調(diào)整W1后,f=130.5Hz
四、分頻電路測(cè)試
測(cè)試要求:該模塊由一個(gè)4位二進(jìn)制計(jì)數(shù)器74HC161和一個(gè)多路選擇器74HC153構(gòu)成。調(diào)試時(shí)可以利用由5G555芯片構(gòu)成一個(gè)多諧振蕩器的輸出,或信號(hào)發(fā)生器作為計(jì)數(shù)器74HC161的計(jì)數(shù)輸入信號(hào)。值得注意的是控制多路選擇器74HC153的S0、S1與單片機(jī)調(diào)試時(shí)所使用的引腳復(fù)用,要采取特殊措施才能正確試驗(yàn)檢測(cè)。
測(cè)試結(jié)果:利用函數(shù)信號(hào)發(fā)生器生成一個(gè)方波,周期/頻率如圖:
其在輸出端輸出的波形為:
f1=3.881kHz
f2 =1.235kHz 分頻功能無誤。
五、鍵盤測(cè)試
測(cè)試要求:本系統(tǒng)相對(duì)比較簡(jiǎn)單,僅有5個(gè)按鍵,其中4個(gè)為系統(tǒng)功能鍵,它們分別是S1、S2、S3、S4,另一個(gè)是系統(tǒng)復(fù)位按鍵S6。對(duì)于系統(tǒng)復(fù)位按鍵S6可以在上電之后,使用萬用表予以檢查,按下該按鍵,單片機(jī)的第9腳應(yīng)該為高電平,釋放后應(yīng)該為點(diǎn)電平。
對(duì)于系統(tǒng)功能鍵,編寫如下程序予以測(cè)試檢查:
#include
#define BIT_LED XBYTE[0x0a000] void display();sbit k1=P1^0;sbit k2=P1^1;sbit k3=P1^2;sbit k4=P1^3;unsigned char a;unsigned
char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x40,0x00,0x63,0x39,};void delay(unsigned int i);main(){ while(1){ if(k1==0)a=0x06;if(k2==0)a=0x5b;if(k3==0)a=0x4f;if(k4==0)a=0x66;display();} } 測(cè)試結(jié)果:對(duì)于復(fù)位鍵S6,按下前應(yīng)為低電平,按下后應(yīng)為高電平
按下前
按下后
對(duì)于S1—S4,按下前為高電平,按下后為低電平。其測(cè)試結(jié)果均符合預(yù)期。
六、動(dòng)態(tài)數(shù)碼管測(cè)試
測(cè)試要求:本系統(tǒng)中的數(shù)碼管的原理采用的是動(dòng)態(tài)掃描方式,即某一時(shí)刻只用一個(gè)數(shù)碼管在顯示,利用人的視覺暫留特性,讓數(shù)碼管高速輪流顯示,達(dá)到完整顯示的目的。
編寫如下程序進(jìn)行測(cè)試: #include
#define BIT_LED XBYTE[0x0a000] void displayhello();sbit k1=P1^0;sbit k2=P1^1;sbit k3=P1^2;sbit k4=P1^3;unsigned char a;unsigned char table[]={0x06,0x06,0x3f,0x3e,0x79,0x6e,0x3f,0x3e,0x7f,0x67,0x40,0x00,0x63,0x39,};void delayms(unsigned int i);main(){ while(1){ displayhello();} }
void displayhello(){
unsigned char BIT=1;
unsigned int i;
BIT_LED=1;
for(i=0;i<=7;i++)
{
SEGMENT=table[i];
BIT_LED=BIT;
BIT=BIT<<1;
delayms(1);
}
} void delayms(unsigned int i){ unsigned int n;while(i--){
for(n=0;n<125;n++);
} }
測(cè)試結(jié)果:顯示“I love you”
由于是動(dòng)態(tài)顯示,所以按下復(fù)位鍵后,只有一個(gè)數(shù)碼管點(diǎn)亮
七、溫度傳感器測(cè)試
測(cè)試要求:本系統(tǒng)使用的是一款單線溫度傳感器(DS18B20),可將溫度穿換成12的數(shù)字量,以表示溫度。
編寫如下程序予以測(cè)試檢查: #include
//段碼寄存器地址 #define BIT_LED XBYTE[0x0a000]
//位碼寄存器地址 #define fosc 11.0592
unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x40,0x00,0x63,0x39,};//分別顯示0 1 2 3 4 5 6 7 8 9-o C
unsigned char table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//分別顯示0.1.2.3.4.5.6.7.8.9.unsigned char table2[]={0x76,0x79,0x38,0x38,0x3f};sbit k1=P1^0;sbit k2=P1^1;sbit k3=P1^2;unsigned char data display_buffer[13];unsigned char bdata data_ds1302;
unsigned char disbuf[]={0,0,0,0};sbit k4=P1^3;
sbit TMDAT=P3^4;
//溫度入口
void dmsec(unsigned int count);void tmreset(void);
//ds18b20 reset void tmstart(void);
// void tmrtemp(void);void Disbuf(unsigned int temper);void displaytemper();void delay(unsigned int);main(){ display_buffer[0]=0x01;
display_buffer[1]=0x00;
display_buffer[2]=0x00;display_buffer[3]=0x08;
display_buffer[4]=0x05;
display_buffer[5]=0x00;display_buffer[6]=0x01;
display_buffer[7]=0x04;
display_buffer[8]=0x00;display_buffer[9]=0x05;
display_buffer[10]=0x00;
display_buffer[11]=0x01;
display_buffer[12]=0x04;while(1){ tmstart();
tmrtemp();
displaytemper();} }
void tmreset(void){
unsigned int i;
TMDAT = 0;
i = 103;while(i>0)i--;
TMDAT = 1;
i = 4;while(i>0)i--;}
void tmpre(void){
unsigned int i;
while(TMDAT);
while(~TMDAT);
i = 4;while(i>0)i--;}
bit tmrbit(void){
// ds1820
// Reset TX
unsigned int i;
bit dat;
TMDAT = 0;i++;
TMDAT = 1;i++;i++;
dat = TMDAT;
i = 8;while(i>0)i--;
return(dat);}
unsigned char tmrbyte(void){
unsigned char i,j,dat;
dat = 0;
for(i=1;i<=8;i++){
j = tmrbit();
dat =(j << 7)|(dat >> 1);
}
return(dat);}
void tmwbyte(unsigned char dat){
unsigned int i;
unsigned char j;
bit testb;
for(j=1;j<=8;j++){
testb = dat & 0x01;
dat = dat >> 1;
if(testb){
TMDAT = 0;
i++;i++;
TMDAT = 1;
i = 8;while(i>0)i--;
}
else {
TMDAT = 0;
i = 8;while(i>0)i--;
TMDAT = 1;
i++;i++;
}
} }
void tmstart(void){
tmreset();
tmpre();
// ds1820
displaytemper();//delay(100);
tmwbyte(0xcc);
tmwbyte(0x44);
}
void tmrtemp(void){
unsigned char a,xiao,b,y1,y2,y3;
tmreset();
tmpre();
delay(1);
tmwbyte(0xcc);
tmwbyte(0xbe);
a = tmrbyte();
b = tmrbyte();
xiao=a&0x0f;//小數(shù)部分
y1=a>>4;
y2=b<<4;
y3=y1|y2;if((b&0x0f8)==0x0f8)
{y3=~y3+1;
disbuf[0]=10;//顯示符號(hào)
disbuf[1]=y3/10;
disbuf[2]=y3%10;
disbuf[3]=xiao*10*0.0625;} else
disbuf[0]=11;//不顯示
disbuf[1]=y3/10;
disbuf[2]=y3%10;
disbuf[3]=xiao*10*0.0625;}
void displaytemper()
//溫度顯示函數(shù)
{ unsigned int i;unsigned char e=0x01;//<<1;for(i=1;i<6;i++)
{ switch(i)
{
case 1:{SEGMENT=table[disbuf[1]];BIT_LED=e;break;}
case 2:{SEGMENT=table1[disbuf[2]];BIT_LED=e;break;}
case 3:{SEGMENT=table[disbuf[3]];BIT_LED=e;break;}
case 4:{SEGMENT=table[12];BIT_LED=e;break;}
case 5:{SEGMENT=table[13];BIT_LED=e;break;}
}
e=e<<1;
delay(80);
}
BIT_LED=0;
}
void delay(unsigned int i)
//delay函數(shù) {
while(i--);}
測(cè)試結(jié)果:
經(jīng)傳感器及數(shù)碼管延時(shí),溫度重新顯示
八、時(shí)鐘日歷測(cè)試
測(cè)試要求:本系統(tǒng)使用了時(shí)鐘日歷專用芯片,該芯片是以串行方式實(shí)現(xiàn)控制和數(shù)據(jù)傳輸?shù)摹?/p>
編寫如下程序進(jìn)行測(cè)試: #include
//段碼寄存器地址 #define BIT_LED XBYTE[0x0a000]
//位碼寄存器地址 #define fosc 11.0592
unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x40,0x00,0x63,0x39,};unsigned char table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};unsigned char table2[]={0x76,0x79,0x38,0x38,0x3f};sbit k1=P1^0;sbit k2=P1^1;sbit k3=P1^2;sbit k4=P1^3;//利用開關(guān)量實(shí)現(xiàn)切換
//頻率變量及子函數(shù)預(yù)定義 void displayfreq();void read_freq();unsigned char tcount=0,timecount=0;unsigned long freq=0.0;bit freqflag=0;unsigned char fr[6];unsigned int i=0,x=0;
//日期變量及子函數(shù)預(yù)定義 sbit SCL_ds1302=P2^0;sbit IO_ds1302=P2^1;sbit RST_ds1302=P2^2;
unsigned char data display_buffer[13];unsigned char bdata data_ds1302;
//傳輸符
unsigned char disbuf[]={0,0,0,0};void open_write_bit();void initial_ds1302();unsigned char read_ds1302(char command);void close_write_bit();void read_time();void set_time();void delay(unsigned int i);void delayms(unsigned int i);void displaytime();void displaydate();main(){ initial_ds1302();
//上電走時(shí)
read_time();
//讀取當(dāng)前時(shí)間,放到數(shù)組中
display_buffer[0]=0x01;
display_buffer[1]=0x05;
display_buffer[2]=0x01;display_buffer[3]=0x07;
display_buffer[4]=0x04;
display_buffer[5]=0x00;display_buffer[6]=0x01;
display_buffer[7]=0x06;
display_buffer[8]=0x00;display_buffer[9]=0x05;
display_buffer[10]=0x00;
display_buffer[11]=0x01;
display_buffer[12]=0x04;
set_time();
//設(shè)置時(shí)間
while(1){
if(k1==0)
{
while(1){
read_time();
displaytime();
if(k2==0)break;
}
}
read_time();
displaydate();} }
void close_write_bit()//close write { unsigned int i;
SCL_ds1302=0;
_nop_();
RST_ds1302=1;_nop_();_nop_();data_ds1302=0x8e;
for(i=1;i<=8;i++){
SCL_ds1302=0;
IO_ds1302=(data_ds1302&0x01);
_nop_();
SCL_ds1302=1;
data_ds1302=data_ds1302>>1;} data_ds1302=0x80;
IO_ds1302=0;for(i=1;i<=8;i++){
SCL_ds1302=0;
IO_ds1302=(data_ds1302&0x01);
_nop_();
SCL_ds1302=1;
data_ds1302=data_ds1302>>1;} }
void open_write_bit()//open write { unsigned int i;SCL_ds1302=0;_nop_();
//打開寫保護(hù)//關(guān)閉寫保護(hù)
RST_ds1302=1;_nop_();_nop_();data_ds1302=0x8e;for(i=1;i<=8;i++){
SCL_ds1302=0;
IO_ds1302=data_ds1302&0x01;
_nop_();SCL_ds1302=1;
data_ds1302=data_ds1302>>1;} data_ds1302=0x00;
//0x00,書上為0x80 IO_ds1302=0;for(i=1;i<=8;i++){
SCL_ds1302=0;
IO_ds1302=data_ds1302&0x01;
_nop_();SCL_ds1302=1;
data_ds1302=data_ds1302>>1;} }
void initial_ds1302()
//初始化函數(shù) { unsigned int i;SCL_ds1302=0;_nop_();RST_ds1302=1;_nop_();_nop_();data_ds1302=0x8e;
for(i=1;i<=8;i++){
SCL_ds1302=0;
IO_ds1302=data_ds1302&0x01;
_nop_();SCL_ds1302=1;
data_ds1302=data_ds1302>>1;} IO_ds1302=0;data_ds1302=0x00;
for(i=1;i<=8;i++){
SCL_ds1302=0;
IO_ds1302=data_ds1302&0x01;
_nop_();SCL_ds1302=1;
data_ds1302=data_ds1302>>1;} RST_ds1302=0;SCL_ds1302=0;_nop_();RST_ds1302=1;_nop_();_nop_();data_ds1302=0x90;
for(i=1;i<=8;i++){ SCL_ds1302=0;IO_ds1302=data_ds1302&0x01;_nop_();SCL_ds1302=1;data_ds1302=data_ds1302>>1;}
data_ds1302=0x0a4;
for(i=1;i<=8;i++){ SCL_ds1302=0;IO_ds1302=data_ds1302&0x01;_nop_();SCL_ds1302=1;data_ds1302=data_ds1302>>1;} RST_ds1302=0;_nop_();SCL_ds1302=0;_nop_();RST_ds1302=1;
data_ds1302=0x8e;
for(i=1;i<=8;i++){ SCL_ds1302=0;IO_ds1302=data_ds1302&0x01;_nop_();SCL_ds1302=1;data_ds1302=data_ds1302>>1;}
data_ds1302=0x80;
for(i=1;i<=8;i++){ SCL_ds1302=0;IO_ds1302=data_ds1302&0x01;_nop_();SCL_ds1302=1;data_ds1302=data_ds1302>>1;} RST_ds1302=0;_nop_();SCL_ds1302=0;}
unsigned char read_ds1302(char command)
//read函數(shù) { unsigned int i;data_ds1302=command;SCL_ds1302=0;_nop_();RST_ds1302=1;for(i=1;i<=8;i++){
SCL_ds1302=0;IO_ds1302=data_ds1302&0x01;_nop_();SCL_ds1302=1;data_ds1302=data_ds1302>>1;}
SCL_ds1302=1;for(i=1;i<=8;i++){
SCL_ds1302=0;
if(IO_ds1302)data_ds1302=(data_ds1302>>1)|0x80;
//送入到data_ds1302中,準(zhǔn)備送出
else data_ds1302>>=1;SCL_ds1302=1;} RST_ds1302=0;_nop_();SCL_ds1302=0;return(data_ds1302);}
void write_ds1302(unsigned char address,unsigned char numb){
unsigned int i;
SCL_ds1302=0;
RST_ds1302=0;
RST_ds1302=1;
data_ds1302=address;for(i=1;i<=8;i++){
SCL_ds1302=0;
IO_ds1302=data_ds1302&0x01;
//送入寫地址
_nop_();SCL_ds1302=1;
data_ds1302=data_ds1302>>1;} data_ds1302=numb;for(i=1;i<=8;i++){
SCL_ds1302=0;
IO_ds1302=data_ds1302&0x01;
_nop_();SCL_ds1302=1;
data_ds1302=data_ds1302>>1;} } void read_time(){ unsigned char second,minte,hour,d,date,month,year,zhou;second=0x81;
//讀秒
d=read_ds1302(second);display_buffer[5]=d&0x0f;display_buffer[4]=d>>4;minte=0x83;
//讀分
d=read_ds1302(minte);display_buffer[3]=d&0x0f;display_buffer[2]=d>>4;hour=0x85;
//讀時(shí)
d=read_ds1302(hour);display_buffer[1]=d&0x0f;display_buffer[0]=d>>4;year=0x8d;
//讀年
d=read_ds1302(year);display_buffer[7]=d&0x0f;display_buffer[6]=d>>4;month=0x89;
//讀月
d=read_ds1302(month);display_buffer[9]=d&0x0f;display_buffer[8]=d>>4;
//送入寫的內(nèi)容
zhou=0x8b;
//讀周d=read_ds1302(zhou);display_buffer[12]=d;date=0x87;
//讀日期
d=read_ds1302(date);display_buffer[11]=d&0x0f;display_buffer[10]=d>>4;}
void set_time(){ unsigned char data temp;unsigned char data hour_address=0x84,minte_address=0x82,second_address=0x80,date_address=0x86,month_address=0x88,zhou_address=0x8a,year_address=0x8c;//各個(gè)時(shí)間量的地址
open_write_bit();
temp=(display_buffer[0]<<4)|display_buffer[1];write_ds1302(hour_address,temp);
//寫小時(shí)
temp=(display_buffer[2]<<4)|display_buffer[3];write_ds1302(minte_address,temp);
//寫分鐘
temp=(display_buffer[4]<<4)|display_buffer[5];write_ds1302(second_address,temp);
//寫秒
temp=(display_buffer[6]<<4)|display_buffer[7];write_ds1302(year_address,temp);
//寫年
temp=(display_buffer[8]<<4)|display_buffer[9];write_ds1302(month_address,temp);
//寫月
temp=display_buffer[12];write_ds1302(zhou_address,temp);
//寫周temp=(display_buffer[10]<<4)|display_buffer[11];write_ds1302(date_address,temp);
//寫日期
close_write_bit();
}
void delay(unsigned int i)
//delay函數(shù) {
while(i--);}
void delayms(unsigned int i){ unsigned int n;while(i--){
for(n=0;n<125;n++);
} }
void displaytime(){ unsigned char e=0x01;unsigned int i;BIT_LED=0;
for(i=0;i<=5;i++){
if(i==5||i%2==0||i==11)
SEGMENT=table[display_buffer[i]];
else
SEGMENT=table1[display_buffer[i]];
BIT_LED=e;
e<<=1;
delayms(1);
}
}
void displaydate(){ unsigned char e=0x01;unsigned int i;BIT_LED=0;
for(i=6;i<=13;i++){
if(i==7||i==9)
SEGMENT=table1[display_buffer[i]];
else if(i==12)
SEGMENT=table[10];
else if(i==13)
SEGMENT=table[display_buffer[i-1]];
else
SEGMENT=table[display_buffer[i]];
BIT_LED=e;
e<<=1;delayms(1);
}
}
測(cè)試結(jié)果:
S1,S2實(shí)現(xiàn)年月日周與時(shí)分秒的切換
九、語音收錄播報(bào)測(cè)試:
測(cè)試要求:本系統(tǒng)中使用的是語音專用芯片IDS1760芯片,該芯片是以串行方式實(shí)現(xiàn)控制和數(shù)據(jù)傳輸?shù)摹?/p>
編寫如下程序進(jìn)行測(cè)試: #include
unsigned char bdata SR0_L;unsigned char bdata SR0_H;unsigned char bdata SR1;unsigned char APCL=0,APCH=0;unsigned char PlayAddL=0,PlayAddH=0;unsigned char RecAddL=0,RecAddH=0;
sbit CMD=SR0_L^0;sbit FULL=SR0_L^1;sbit PU=SR0_L^2;sbit EOM=SR0_L^3;sbit INTT=SR0_L^4;sbit RDY=SR1^0;sbit ERASE=SR1^1;sbit PLAY=SR1^2;sbit REC=SR1^3;
unsigned char ISD_SendData(unsigned char dat);void ISD_PU(void);void ISD_Rd_Status(void);void ISD_WR_APC2(unsigned char apcdatl,apcdath);void ISD_SET_PLAY(unsigned char Saddl,Saddh,Eaddl,Eaddh);void ISD_SET_Rec(unsigned char Saddl,Saddh,Eaddl,Eaddh);void ISD_SET_Erase(unsigned char Saddl,Saddh,Eaddl,Eaddh);
sbit SS=P1^4;sbit SCK=P1^7;sbit MOSI=P1^5;sbit MISO=P1^6;
void Cpu_Init(void);void ISD_Init(void);void delay(unsigned int t);
void main(){ Cpu_Init();ISD_Init();
while(1){ ISD_SET_Erase(0,0,9,0);ISD_SET_Rec(0,0,9,0);ISD_SET_PLAY(0,0,9,0);} }
void Cpu_init(void){ P0=P1=P2=P3=0xff;TMOD=0x01;EA=0;} void ISD_Init(void){ uchar i=2;SS=1;SCK=1;MOSI=0;do { ISD_PU();//上電 delay(50);ISD_Rd_Status();//讀取狀態(tài)
}while(CMD||(!PU));
//if(CMD_Err==1||(PU!+1))則再次發(fā)送上電指令 ISD_WR_APC2(0x40,0x04);//將0x0440寫入APC寄存器
do { ISD_Rd_Status();}while(RDY==0);do { delay(300);delay(300);i--;}while(i>0);}
//向cpu讀回或發(fā)送數(shù)據(jù)
unsigned char ISD_SendData(unsigned char dat){ unsigned char i,j,BUF_ISD=dat;SCK=1;SS=0;for(j=4;j>0;j--){;}
for(i=0;i<8;i++){ SCK=0;for(j=2;j>0;j--){;} if(BUF_ISD&0x01)
{MOSI=1;} else
{MOSI=0;} BUF_ISD>>=1;if(MISO)
{BUF_ISD|=0x80;} SCK=1;for(j=6;j>0;j--){;} } MOSI=0;return(BUF_ISD);} void ISD_PU(void){
ISD_SendData(0x01);
ISD_SendData(0x00);
SS=1;} void ISD_Rd_Status(void){ unsigned char i;ISD_SendData(0x05);ISD_SendData(0x00);ISD_SendData(0x00);SS=1;for(i=2;i>0;i--){;} SR0_L=ISD_SendData(0x05);SR0_H=ISD_SendData(0x00);SR1=ISD_SendData(0x00);SS=1;}
void ISD_WR_APC2(unsigned char apcdatl,apcdath){ ISD_SendData(0x65);ISD_SendData(apcdatl);ISD_SendData(apcdath);SS=1;}
void ISD_SET_PLAY(unsigned char Saddl,Saddh,Eaddl,Eaddh){ ISD_SendData(0x80);ISD_SendData(0x00);ISD_SendData(Saddl);ISD_SendData(Saddh);ISD_SendData(Eaddl);ISD_SendData(Eaddh);ISD_SendData(0x00);SS=1;}
void ISD_SET_Rec(unsigned char Saddl,Saddh,Eaddl,Eaddh){
ISD_SendData(0x81);ISD_SendData(0x00);ISD_SendData(Saddl);ISD_SendData(Saddh);ISD_SendData(Eaddl);ISD_SendData(Eaddh);ISD_SendData(0x00);SS=1;}
void ISD_SET_Erase(unsigned char Saddl,Saddh,Eaddl,Eaddh){ ISD_SendData(0x82);ISD_SendData(0x00);ISD_SendData(Saddl);ISD_SendData(Saddh);ISD_SendData(Eaddl);ISD_SendData(Eaddh);ISD_SendData(0x00);SS=1;} void delay(unsigned int t){ for(;t>0;t--){ TH0=0xfc;TL0=0x18;TR0=1;while(TF0!=1){;} TF0=0;TR0=0;} }
測(cè)試結(jié)果:需要在程序中設(shè)置斷點(diǎn),完成錄音,放音再錄音放音的循環(huán)操作。
測(cè)試功能正常。
十、單片機(jī)模塊調(diào)試
測(cè)試要求:該模塊的調(diào)試很復(fù)雜,牽扯面也很多。其實(shí)通過前面各個(gè)模塊的調(diào)試,已經(jīng)大部分得到了間接地驗(yàn)證。例如在“動(dòng)態(tài)數(shù)碼管測(cè)試”和“串行通訊測(cè)試”中就是用到了定時(shí)器。
如有必要可以再編寫一些測(cè)試程序。例如檢測(cè)單片機(jī)的某一口線的功能是否正常、測(cè)試某段程序運(yùn)行時(shí)間,等等。
測(cè)試結(jié)論:因單片機(jī)大部分功能在前調(diào)試方案中大部分已使用過,此處不再進(jìn)行其余調(diào)試。
第四篇:?jiǎn)纹瑱C(jī)出租車計(jì)價(jià)器源程序
出租車計(jì)價(jià)器設(shè)計(jì)與制作
設(shè)計(jì)并制作一臺(tái)出租車計(jì)價(jià)器。調(diào)試時(shí)采用10Hz方波信號(hào)模擬,每個(gè)方波代表10m?;疽螅?/p>
(1)不同情況具有不同的收費(fèi)標(biāo)準(zhǔn)
白天 1元/公里 晚上 2元/ 公里 途中等待(30s)1元/30s
(2)數(shù)據(jù)輸出(6位LED數(shù)碼管顯示)
單價(jià)輸出2位 路途輸出2位 總金額輸出2位
(3)按鍵(3個(gè))
啟動(dòng)計(jì)價(jià)開關(guān) 數(shù)據(jù)復(fù)位(清零)白天/晚上轉(zhuǎn)換
3.4.1模塊1:系統(tǒng)設(shè)計(jì)
(1)分析任務(wù)要求,寫出系統(tǒng)整體設(shè)計(jì)思路
通過分析,需要實(shí)現(xiàn)四個(gè)主要的功能模塊,分別為脈沖計(jì)數(shù)模塊、定時(shí)器計(jì)時(shí)模塊、按鍵的處理以及
數(shù)碼管動(dòng)態(tài)掃描等功能。
定時(shí)器計(jì)時(shí)模塊主要完成途中等待(即沒有脈沖來時(shí))30秒的計(jì)時(shí)。在啟動(dòng)鍵按下后,定時(shí)器就不停的計(jì)時(shí),只要有脈沖來就將計(jì)時(shí)的值清除為零。如果沒有脈沖來,當(dāng)計(jì)時(shí)超過30秒時(shí),相應(yīng)的總金額要
按照收費(fèi)標(biāo)準(zhǔn)計(jì)價(jià)。
中斷的管理:盡管中斷有嵌套以及優(yōu)先級(jí)的功能,但是由于定時(shí)器已經(jīng)使用一個(gè)了中斷資源,脈沖檢測(cè)不宜再采用中斷方式,而是采用查詢方式。由于需要不停的要清除30秒的計(jì)時(shí),因此,脈沖的計(jì)數(shù)不
采用定時(shí)器的計(jì)數(shù)方式。
啟動(dòng)鍵觸發(fā)定時(shí)器開始工作,而定時(shí)器的運(yùn)行可以作為脈沖計(jì)數(shù)的標(biāo)志,只要定時(shí)器計(jì)時(shí)在運(yùn)行,每來一個(gè)中斷都應(yīng)該計(jì)數(shù)。
主程序完成鍵盤的掃描和按鍵的處理,查詢脈沖產(chǎn)生的中斷,并完成脈沖的計(jì)數(shù)。每個(gè)脈沖代表10米,則當(dāng)計(jì)數(shù)到100時(shí)表示1千米的距離,相應(yīng)的總金額要按照收費(fèi)標(biāo)準(zhǔn)計(jì)價(jià)
(2)選擇單片機(jī)型號(hào)和所需外圍器件型號(hào),設(shè)計(jì)單片機(jī)硬件電路原理圖
采用MCS51系列單片機(jī)At89S51作為主控制器,外圍電路器件包括數(shù)碼管驅(qū)動(dòng)、獨(dú)立式鍵盤、復(fù)位電
路等。硬件電路原理圖如圖3-9所示。
圖3-11 出租車計(jì)價(jià)器的硬件電路原理圖
數(shù)碼管驅(qū)動(dòng)采用2個(gè)四聯(lián)共陰極數(shù)碼管顯示,由于單片機(jī)驅(qū)動(dòng)能力有限,采用74HC244作為數(shù)碼管的驅(qū)動(dòng)。在74HC244的7段碼輸出線上串聯(lián)100歐姆電阻起限流作用。
獨(dú)立式按鍵使用上提拉電路連接,在沒有鍵按下時(shí),輸出高電平。P0口用于輸出7段LED共陰極顯示代碼,P2口用于輸出低電平有效的位選碼。0~9的7段LED共陰極顯示代碼:3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH。
(3)分析軟件任務(wù)要求,寫出程序設(shè)計(jì)思路,分配單片機(jī)內(nèi)部資源,畫出程序流程圖
軟件的任務(wù)要求包括定時(shí)器的設(shè)置、按鍵的掃描、按鍵的功能處理、脈沖的計(jì)數(shù)、路途等待超30秒的計(jì)
時(shí)以及總金額的計(jì)算等。
程序設(shè)計(jì)的思路:使用中斷方式對(duì)定時(shí)器的溢出進(jìn)行計(jì)數(shù)實(shí)現(xiàn)30秒的計(jì)時(shí)。主程序采用查詢外部中斷標(biāo)志實(shí)現(xiàn)脈沖的計(jì)數(shù),由于每個(gè)脈沖代表10m,因此,當(dāng)脈沖計(jì)數(shù)超過100時(shí),計(jì)價(jià)器按照收費(fèi)標(biāo)準(zhǔn)計(jì)價(jià)。主程序在初始化變量和定時(shí)器參數(shù)設(shè)置之后,進(jìn)入一個(gè)循環(huán)結(jié)構(gòu),循環(huán)掃描鍵盤、查詢脈沖的中斷、數(shù)碼管的動(dòng)態(tài)掃描等功能,當(dāng)脈沖的中斷標(biāo)志被查詢到,若路途等待時(shí)間未超30秒時(shí),要及時(shí)將路途等待時(shí)間的值清除為零。主程序的流程圖如圖3-12所示。
圖3-12 出租車計(jì)價(jià)器的主程序流程圖
中斷服務(wù)程序主要實(shí)現(xiàn)計(jì)時(shí)功能,當(dāng)啟動(dòng)鍵按下之后,定時(shí)器開始工作,用一個(gè)變量對(duì)定時(shí)器溢出中斷的次數(shù)進(jìn)行計(jì)數(shù),達(dá)到計(jì)時(shí)功能,該變量在每次脈沖到來時(shí)被清零(在主程序中清零),當(dāng)脈沖長(zhǎng)時(shí)間沒有來,則當(dāng)該變量計(jì)數(shù)超過30秒時(shí),總金額按照途中等待計(jì)費(fèi)標(biāo)準(zhǔn)進(jìn)行計(jì)價(jià)。中斷程序的流程圖如圖
3-13所示。
圖3-13 出租車計(jì)價(jià)器的中斷服務(wù)程序流程圖
(4)設(shè)計(jì)系統(tǒng)軟件調(diào)試方案、硬件調(diào)試方案及軟硬件聯(lián)合調(diào)試方案
軟件調(diào)試方案:偉福軟件中,在“文件新建文件”中,新建C語言源程序文件,編寫相應(yīng)的程序。在“文件新建項(xiàng)目”的菜單中,新建項(xiàng)目并將C語言源程序文件包括在項(xiàng)目文件中。
在 “項(xiàng)目編譯”菜單中將C源文件編譯,檢查語法錯(cuò)誤及邏輯錯(cuò)誤。在編譯成功后,產(chǎn)生以 “*.hex”和“*.bin” 后綴的目標(biāo)文件。
硬件調(diào)試方案:在設(shè)計(jì)平臺(tái)中,將單片機(jī)的P1.0-P1.2分別與3個(gè)獨(dú)立式鍵盤通過插線連接起來,將P3.2與脈沖信號(hào)源連接起來。
在偉福中將程序文件編譯成目標(biāo)文件后,將下載線安裝在實(shí)驗(yàn)平臺(tái)上,運(yùn)行“MCU下載程序”,選擇相應(yīng)的flash 數(shù)據(jù)文件,點(diǎn)擊“編程”按鈕,將程序文件下載到單片機(jī)的Flash中。
然后,上電重新啟動(dòng)單片機(jī),檢查所編寫的程序是否達(dá)到題目的要求,是否全面完整地完成試題的內(nèi)容。3.4.2 程序設(shè)計(jì)
/*晶振:11.0592M T1-250微秒溢出中斷一次;P3.2(int0)-中斷100次,查詢IE0置位,P1^0為啟動(dòng)鍵;P1^1為清除鍵;P1^2為白天/晚上的切換鍵 變量的定義: key_val: 返回按鍵的值 255-無鍵
T1_cnt: 定時(shí)器溢出數(shù)計(jì)數(shù)
cnt_30: 30秒鐘的計(jì)時(shí)
cnt_distance: 計(jì)算路程
cnt_cost: 總金額
state_val: 狀態(tài):0-白天 1 夜晚
cost_val[3]: 收費(fèi)標(biāo)準(zhǔn):白天單價(jià)cost_val[0]=1元/公里;晚上單價(jià)cost_val[1]=2元/公里; 等待單價(jià)cost_val[2]=1元/30s
led_seg_code:數(shù)碼管7段碼 */ //-------------------#include “reg51.h” unsigned char data cnt_30,cnt_distance,cnt_cost;unsigned int data T1_cnt,D_cnt;unsigned char data key_val,key_val_old;unsigned char data state_val;char code cost_val[3]={1,2,1};char code led_seg_code[10]={0x3f,0x06,0x05b,0x04f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//led_seg_code[0-9]代表0-9 //-------延時(shí)-----------------void delay(unsigned int i)//延時(shí) { while(--i);} //-------初始化變量------------------void init_variant()//初始化一些變量的內(nèi)容 {unsigned char i;cnt_30=0;//30秒的計(jì)時(shí) D_cnt=0;//脈沖的個(gè)數(shù) cnt_distance=0;//距離的計(jì)數(shù)
cnt_cost=0;//保存總價(jià)格 } //-------掃描鍵盤-----------------unsigned char scan_key(){ unsigned char i,k;i=P1;if(i==0xff){ k=255;} //無鍵按下
else //有鍵按下
{ delay(10);//延時(shí)去抖動(dòng)
if(i!=P1){k=255;} else { switch(i){ case 0xfe: k=0;break;//P1.0按下,啟動(dòng)鍵
case 0xfd: k=1;break;//P1.1按下,清除鍵
case 0xfb: k=2;break;//P1.2按下,切換鍵
} } } return k;} //-------數(shù)碼管動(dòng)態(tài)掃描-------------void led_show(){unsigned char i,k;
//-----顯示單價(jià)----k=cost_val[state_val];i=k%10;//暫存?zhèn)€位 P0=led_seg_code[i];P2=0xbf;delay(10);i=k%100/10;P0=led_seg_code[i];P2=0x7f;delay(10);//-----顯示距離------k=cnt_distance;i=k%10;//暫存?zhèn)€位 P0=led_seg_code[i];P2=0xf7;delay(10);i=k%100/10;P0=led_seg_code[i];P2=0xef;delay(10);//-----顯示總價(jià)格-----------k=cnt_cost;i=k%10;//暫存?zhèn)€位 P0=led_seg_code[i];P2=0xfe;delay(10);i=k%100/10;P0=led_seg_code[i];P2=0xfd;delay(10);} //-------計(jì)時(shí)----------------void timer1()interrupt 3 //T1中斷 { T1_cnt++;if(T1_cnt>3999)//如果計(jì)數(shù)>3999, 計(jì)時(shí)1s { T1_cnt=0;if(cnt_30<30)//沒有超過30秒,繼續(xù)計(jì)時(shí)
{cnt_30++;} else //超過30秒,途中等待計(jì)價(jià)
{cnt_30=0;cnt_cost=cnt_cost+cost_val[2];} } } //---------主程序----------------
main(){//初始化各變量 T1_cnt=0;state_val=0;key_val_old=255;init_variant();//初始化51的寄存器
TMOD=0x20;//用T1計(jì)時(shí) 8位自動(dòng)裝載定時(shí)模式,不用T0 TH1=0x19;//250微秒溢出一次;250=(256-x)*12/11.0592-> x= 230.4 TL1=0x19;EA=1;//開中斷 ET1=1;
TR1=0;//定時(shí)器T0 TCON=0x01;//Int0中斷取邊沿觸發(fā)模式 while(1){ key_val=scan_key();// 255;// if(key_val!=key_val_old){ key_val_old=key_val;if(key_val!=255){ switch(key_val){ case 0: //啟動(dòng)鍵
TR1=1;//啟動(dòng)計(jì)時(shí),TR1=1為啟動(dòng)了的標(biāo)志
break;case 1: //清除鍵
init_variant();//清除變量
TR1=0;//關(guān)閉定時(shí)器
break;case 2: //白天/黑夜的切換
if(state_val==0){state_val=1;} else {state_val=0;} break;} } } if(IE0==1&& TR1==1)//每來1個(gè)脈沖,中斷一次
{ IE0=0;cnt_30=0;//30秒的計(jì)時(shí)清零
if(D_cnt<100)
{D_cnt++;} else //計(jì)數(shù)100次,每次10米,表示一公里
{D_cnt=0;cnt_distance=cnt_distance+1;
cnt_cost=cnt_cost+cost_val[state_val];} } led_show();} } //-----出租車計(jì)價(jià)器程序結(jié)束------------
第五篇:出租車計(jì)價(jià)器 硬件課程設(shè)計(jì)
硬件課程設(shè)計(jì)報(bào)告
題目:出租車計(jì)價(jià)器
目錄
1. 引言....................................................................................................................................錯(cuò)誤!未定義書簽。
1.1設(shè)計(jì)目的................................................................................................................錯(cuò)誤!未定義書簽。1.2設(shè)計(jì)任務(wù)................................................................................................................錯(cuò)誤!未定義書簽。1.3設(shè)計(jì)思路................................................................................................................錯(cuò)誤!未定義書簽。
2.需求分析.............................................................................................................................錯(cuò)誤!未定義書簽。
2.1芯片原理................................................................................................................錯(cuò)誤!未定義書簽。2.1.1可編程計(jì)數(shù)器/定時(shí)器8253/8254原理.............................................................錯(cuò)誤!未定義書簽。2.1.2可編程外圍接口芯片8255原理.......................................................................錯(cuò)誤!未定義書簽。2.1.3 12864液晶顯示器ST7920原理........................................................................錯(cuò)誤!未定義書簽。2.2硬件設(shè)計(jì)................................................................................................................錯(cuò)誤!未定義書簽。2.3軟件設(shè)計(jì)................................................................................................................錯(cuò)誤!未定義書簽。2.3.1功能模塊圖.........................................................................................................錯(cuò)誤!未定義書簽。2.3.2程序流程圖.........................................................................................................錯(cuò)誤!未定義書簽。2.3.3模塊流程圖.........................................................................................................錯(cuò)誤!未定義書簽。
3.詳細(xì)設(shè)計(jì).............................................................................................................................錯(cuò)誤!未定義書簽。
3.1程序模塊分析........................................................................................................錯(cuò)誤!未定義書簽。3.1.1初始化模塊程序分析.........................................................................................錯(cuò)誤!未定義書簽。3.1.2判斷開關(guān)程序模塊分析.....................................................................................錯(cuò)誤!未定義書簽。3.1.3圈數(shù)統(tǒng)計(jì)模塊程序分析.....................................................................................錯(cuò)誤!未定義書簽。3.1.4計(jì)算里程模塊程序分析.....................................................................................錯(cuò)誤!未定義書簽。3.1.5顯示模塊程序分析.............................................................................................錯(cuò)誤!未定義書簽。3.1.6結(jié)束模塊程序分析.............................................................................................錯(cuò)誤!未定義書簽。3.2程序代碼................................................................................................................錯(cuò)誤!未定義書簽。
4.5.6.程序結(jié)果.............................................................................................................................錯(cuò)誤!未定義書簽。分析與測(cè)試.........................................................................................................................錯(cuò)誤!未定義書簽。體會(huì).....................................................................................................................................錯(cuò)誤!未定義書簽。
附錄A:參考文獻(xiàn).....................................................................................................................錯(cuò)誤!未定義書簽。
一、引言
1.1設(shè)計(jì)目的
現(xiàn)在各大城市出租車已經(jīng)成為了一種重要的交通工具,當(dāng)然出租車的收費(fèi)問題也成了人們關(guān)注的焦點(diǎn),那么怎么樣才能實(shí)現(xiàn)一種合理的收費(fèi)方式讓大家都認(rèn)可呢?在這種要求下,出租車自動(dòng)計(jì)價(jià)器就走進(jìn)了人們的生活,當(dāng)然這就要求有一種合理公正的計(jì)價(jià)器收費(fèi)方式。這不僅關(guān)系到出租車計(jì)價(jià)器的市場(chǎng),也影響這出租車的市場(chǎng),這就要求我們?cè)O(shè)計(jì)出更好的計(jì)價(jià)器來滿足人們的需求。
本設(shè)計(jì)是關(guān)于出租車計(jì)價(jià)器的設(shè)計(jì)。在本次設(shè)計(jì)中,我以計(jì)價(jià)器的基本功能作為設(shè)計(jì)的重點(diǎn)。為了完成上述設(shè)計(jì),我們采用了8254、8255等芯片,用計(jì)算機(jī)匯編語言進(jìn)行軟件功能的實(shí)現(xiàn)。
1.2設(shè)計(jì)任務(wù)
1.實(shí)現(xiàn)一個(gè)出租車計(jì)價(jià)器,可以顯示起步價(jià)。2.一個(gè)鍵來控制是否到達(dá)終點(diǎn),是否計(jì)價(jià)要清零。3.基于路程的出租車計(jì)價(jià)方式。
1.3設(shè)計(jì)思路
利用直流電機(jī)來模仿出租車輪子的轉(zhuǎn)動(dòng)來計(jì)算出租車行進(jìn)的路程。將直流電機(jī)的直流端與滑動(dòng)變阻器相連,通過人工控制滑動(dòng)變阻器來模擬出租車的行進(jìn);并將計(jì)數(shù)端與8253CLK0端相連,GATE0接高電平,工作方式為方式二。直流電機(jī)每轉(zhuǎn)1000圈,8253輸出一個(gè)高電平,假設(shè)出租車已經(jīng)走了1公里。同時(shí)將8253OUT0接入8255方便CPU讀取。再將8255與ST7920顯示器相連,CPU通過控制8255來控制顯示,一旦8255從8253讀入一個(gè)高電平,則公里數(shù)加一,同時(shí)價(jià)格相應(yīng)增加。另有一個(gè)開關(guān)連入8255,用以判斷出租車計(jì)價(jià)器是否啟動(dòng)。
二、需求分析
2.1芯片原理
本節(jié)主要在介紹本次設(shè)計(jì)所用到的芯片的原理,共有可編程計(jì)數(shù)器/定時(shí)器8253/8254、可編程外圍接口芯片8255和12864液晶顯示器ST7920原理三種芯片。
2.1.1可編程計(jì)數(shù)器/定時(shí)器8253/8254原理
圖2-1 8254內(nèi)部結(jié)構(gòu)圖
從圖2-1可見,8254內(nèi)部包含數(shù)據(jù)總線緩沖器、讀/寫控制邏輯、控制字寄存器和3個(gè)結(jié)構(gòu)完全相同的計(jì)數(shù)器,這3個(gè)計(jì)數(shù)器分別稱為計(jì)數(shù)器0、計(jì)數(shù)器1和計(jì)數(shù)器2。
圖2-2 8254管腳圖
A1、A0:地址輸入線,用來控制8253內(nèi)部的4個(gè)端口,即3個(gè)計(jì)數(shù)器和1個(gè)控制字寄存器與CPU系統(tǒng)地址線相連。
CLK0-2:時(shí)鐘脈沖輸入端,用于輸入定時(shí)脈沖或計(jì)數(shù)脈沖信號(hào)。CLK可以是系統(tǒng)的時(shí)鐘脈沖,也可以由系統(tǒng)時(shí)鐘分頻或者其他脈沖源提供。當(dāng)用于定時(shí)時(shí),這個(gè)脈沖必須是均勻的、連續(xù)的、周期精確的,而用于計(jì)數(shù)時(shí),這個(gè)脈沖可以是不均勻的、斷續(xù)的、周期不定的。
GATE0-2:門控輸入端,用于外部控制計(jì)數(shù)器的啟動(dòng)計(jì)數(shù)和停止計(jì)數(shù)的操
作。兩個(gè)或兩個(gè)以上計(jì)數(shù)器連用時(shí),可用此信號(hào)同步,也可用于與外部某信號(hào)的同步。
OUT0-2:計(jì)數(shù)輸出,當(dāng)計(jì)數(shù)器從初值開始完成計(jì)數(shù)操作進(jìn),OUT引腳輸出相應(yīng)的信號(hào)。
8253的方式控制字
圖2-3 8254控制字圖
本設(shè)計(jì)中8254的功能
只是用通道1,采用方式三。采用二進(jìn)制計(jì)數(shù),輸入0FFFH。先輸入低字節(jié),再輸入高字節(jié)。當(dāng)8254從0FFFFH遞減到159FH時(shí)(即轉(zhuǎn)了60000圈時(shí)),8254向總線發(fā)信號(hào)使程序向下進(jìn)行。
2.1.2可編程外圍接口芯片8255原理
內(nèi)部結(jié)構(gòu)如圖所示,由以下4個(gè)部分組成:
圖2-4 8255內(nèi)部結(jié)構(gòu)圖
(1)輸入/輸出端口A、B、C。這三個(gè)端口均可看作是I/O端口,但它們的結(jié)構(gòu)和功能也稍有不同。A口和B口是一個(gè)獨(dú)立的8位I/O口。C口:可以看作是一個(gè)獨(dú)立的8位I/O口;也可以看作是兩個(gè)獨(dú)立的4位I/O口。
(2)A組和B組控制電路。這是兩組根據(jù)CPU命令控制8255A工作方式的電路,這些控制電路內(nèi)部設(shè)有控制寄存器,可以根據(jù)CPU送來的編程命令來控制8255A的工作方式,也可以根據(jù)編程命令來對(duì)C口的指定位進(jìn)行置/復(fù)位的操作。A組控制電路用來控制A口及C口的高4位;B組控制電路用來控制B口及C口的低4位
(3)讀/寫控制邏輯。(同上:它負(fù)責(zé)管理8255A的數(shù)據(jù)傳輸過程。它接收CS*及RD*、WR*、RESET,還有來自系統(tǒng)地址總線的口地址選擇信號(hào)A0和A1。將這些信號(hào)組合后,得到對(duì)A組控制部件和B組控制部件的控制命令,并將命令發(fā)給這兩個(gè)部件,以完成對(duì)數(shù)據(jù)、狀態(tài)信息和控制信息的傳輸。)
(4)數(shù)據(jù)總緩沖器。(同上:它是8位的雙向的三態(tài)緩沖器。作為8255A與系統(tǒng)總線連接的界面,輸入/輸出的數(shù)據(jù),CPU的編程命令以及外設(shè)通過8255A傳送的工作狀態(tài)等信息,都是通過它來傳輸?shù)摹#?/p>
如圖所示8255A的芯片引腳信號(hào)。除了電源和地以外,其他信號(hào)可以分為兩組:
圖2-5 8255管腳圖
1.和外設(shè)一邊相連的: PA7-PA0:A組數(shù)據(jù)信號(hào)
PB7-PB0:B組數(shù)據(jù)信號(hào) PC7-PC0:C組數(shù)據(jù)信號(hào) 2.和CPU一邊相連的:
RESET:復(fù)位信號(hào),低電平有效。當(dāng)RESET信號(hào)來到時(shí),所有內(nèi)部寄存器就被清除,同時(shí),3個(gè)數(shù)據(jù)端口被自動(dòng)設(shè)為輸入端口。
D7-D0:它們是8255A的數(shù)據(jù)線,和系統(tǒng)數(shù)據(jù)總線相連。
CS*:芯片選擇信號(hào),低電平有效。在一個(gè)系統(tǒng)中,一般根據(jù)全部接口芯片來分配若干較低位地址(比如A5、A4、A3)來組成各種芯片選擇碼,當(dāng)這幾位地址組成某一個(gè)代碼時(shí),譯碼器便往8255A的CS*端輸出一個(gè)低電平,于是8255A被選中。只有當(dāng) CS*有效時(shí),讀信號(hào)RD*和寫信號(hào)WR*才對(duì)8255A有效。
RD*:芯片讀出信號(hào)低電平有效。WR*:芯片寫入信號(hào)低電平有效。8255的方式控制字格式
圖2-6 8255控制字圖
本設(shè)計(jì)中8255的功能
8255PA0-PA7和PC0-PC2與ST7920相連,控制輸出。PB0與8253的OUT1相連,讀入8253OUT1 的數(shù)據(jù)。PB1與開關(guān)K0相連,讀入K0的數(shù)值用于確定是否開啟計(jì)價(jià)器。
2.1.3可編程外圍接口芯片8255原理
ST7920控制器系列中文圖形液晶模塊的軟件特性主要由ST7920控制驅(qū)動(dòng)器決定。ST7920同時(shí)作為控制器和驅(qū)動(dòng)器,它可提供33路com輸出和64路seg輸出。在驅(qū)動(dòng)器ST7921的配合下,最多可以驅(qū)動(dòng)256×32點(diǎn)陣液晶。
ST7920是臺(tái)灣矽創(chuàng)電子公司生產(chǎn)的中文圖形控制芯片,它是一種內(nèi)置12864漢字圖形點(diǎn)陣的液晶顯示控制模塊,用于顯示漢字及圖形。該芯片共內(nèi)置8192
個(gè)中文漢字(16×16點(diǎn)陣)、128個(gè)字符的ASCII字符庫(kù)(8×16點(diǎn)陣)及64×2256點(diǎn)陣顯示RAM(GDRAM)。
為了能夠簡(jiǎn)單、有效地顯示漢字和圖形,該模塊內(nèi)部設(shè)計(jì)有2MB的中文字型CGROM和64×256點(diǎn)陣的GDRAM繪圖區(qū)域;同時(shí),該模塊還提供有4組可編程控制的16×16點(diǎn)陣造字空間;除此之外,為了適應(yīng)多種微處理器和單片機(jī)接口的需要,該模塊還提供了4位并行、8位并行、2線串行以及3線串行等多種接口方式。利用上述功能可方便地實(shí)現(xiàn)漢字、ASCII碼、點(diǎn)陣圖形、自造字體的同屏顯示,所有這些功能(包括顯示RAM、字符產(chǎn)生器以及液晶驅(qū)動(dòng)電路和控制器)都包含在集成電路芯片里,因此,只要一個(gè)最基本的微處理系統(tǒng)就可以通過ST7920芯片來控制其它的芯片
圖2-7 ST7920外觀尺寸圖
本設(shè)計(jì)中ST7920的功能
用于顯示出租車行駛路程與應(yīng)收費(fèi)用。
2.2硬件設(shè)計(jì)
其中,8253GATE1連+5V高電平,直流電機(jī)連0~+5V,8253連280h~287h,8255連288h~28fh。8255PA0-PA7連ST7920顯示器D0-D7,PC0連DI,PC1連RW,PC2連E。開關(guān)K0連8255PB0。8253CLK1連直流電機(jī)計(jì)數(shù)端。
0~+5V直流電機(jī)D0-D7計(jì)數(shù)ST7920顯示屏DIRWE+5VGATE1CLK1PA0-PA7+5VPC0PC1PC2開關(guān)K0PB0+5V8253CS8255CS280H-288H289H-28FH總線圖2-8硬件連接圖
實(shí)際連接圖如下圖所示
圖2-9硬件實(shí)際連接圖
2.3軟件設(shè)計(jì) 2.3.1功能模塊圖
本節(jié)先給出一個(gè)程序的功能模塊圖。
出租車計(jì)價(jià)器系統(tǒng)計(jì)價(jià)器開關(guān)功能模塊讀入直流電機(jī)轉(zhuǎn)圈數(shù)模塊ST7920顯示功能模塊根據(jù)里程計(jì)算價(jià)格模塊
圖2-10軟件功能模塊圖
2.3.2程序流程圖
本節(jié)先給出一個(gè)程序的整體流程圖。
開始結(jié)束8253初始化液晶顯示屏初始化8255初始化是計(jì)價(jià)器是否開始工作通過8255讀入b0否是否有鍵盤輸入否液晶顯示屏初始化是液晶顯示屏調(diào)用顯示價(jià)格功能從直流電機(jī)讀入輸入圈數(shù)將更改過的路程在顯示器中顯示出來讀到一定圈數(shù)走的路程加一比較路程是否大于3公里是價(jià)格為(路程-3)*2+7 元將儲(chǔ)存的顯示字符串內(nèi)路程價(jià)格改為目前路程價(jià)格否價(jià)格為7元
圖2-11軟件程序流程圖
2.3.3模塊流程圖
如果對(duì)整個(gè)程序進(jìn)行細(xì)分則可以分為初始化模塊,判斷開關(guān)模塊,圈數(shù)統(tǒng)計(jì)模塊,計(jì)算里程模塊、結(jié)束模塊和顯示模塊。其中初始化模塊是8253芯片、8255芯片和顯示屏的初始化。判斷開關(guān)模塊是對(duì)8255的b0端是否有高電平進(jìn)行判斷。
圈數(shù)統(tǒng)計(jì)模塊是對(duì)直流電機(jī)傳入8253中高電平的數(shù)量進(jìn)行圈數(shù)統(tǒng)計(jì)。計(jì)算里程模塊是對(duì)里程及價(jià)格進(jìn)行計(jì)算的模塊。結(jié)束模塊是程序結(jié)束的操作與方法。顯示模塊是控制顯示屏顯示計(jì)算模塊的結(jié)果。
初始化模塊顯示模塊調(diào)用關(guān)判斷開關(guān)模塊開結(jié)束模塊圈數(shù)統(tǒng)計(jì)模塊計(jì)算里程模塊調(diào)用顯示模塊圖2-12軟件模塊流程圖
三、詳細(xì)設(shè)計(jì)
3.1程序模塊分析
我們將按模塊分析程序的功能并給出模塊內(nèi)的功能流程圖。
3.1.1初始化模塊分析
在初始化模塊中,我們定義了需要使用的8255和8254的接口,需要使用的變量如JSS,要輸出的字符串等,初始化了DS,完成了8255的初始化以及顯示屏的初始化。其流程圖為
開始圖3-1初始化模塊流程圖
3.1.2判斷開關(guān)模塊分析
以上為判斷開關(guān)模塊,在判斷開關(guān)模塊中,系統(tǒng)讀入8255PB0的電平,如果是高電平則程序繼續(xù)進(jìn)行,如果是低電平則程序調(diào)用chushi函數(shù),用屏幕顯示“空車歡迎乘坐”,并繼續(xù)度8255PB0直到有高電平為止。其流程圖如下所示:
8255PB0是否為高電平是圈數(shù)統(tǒng)計(jì)模塊否Chushi函數(shù)計(jì)數(shù)變量和對(duì)應(yīng)的字符串置零顯示 空車 歡迎乘坐 調(diào)用顯示模塊
圖3-2判斷開關(guān)模塊流程圖
3.1.3圈數(shù)統(tǒng)計(jì)模塊分析
在圈數(shù)統(tǒng)計(jì)模塊中,我們將直流電機(jī)計(jì)數(shù)端連入8254CLK1中(8253采用方式三),在CLK1中讀所記的數(shù),從0FFFFH向下計(jì),一直計(jì)到159FH,即轉(zhuǎn)了6000圈后,進(jìn)入程序的下一段。其流程圖如下所示:
讀8254計(jì)數(shù)值否是否到159FH以下是重新將8254計(jì)數(shù)初值設(shè)為0FFFFH計(jì)算里程模塊
圖3-3圈數(shù)統(tǒng)計(jì)模塊流程圖
3.1.4計(jì)算里程模塊分析
我們用地址JSS里表示已經(jīng)走過的公里,即8254傳過來的高電平,同時(shí)我們采用價(jià)格公式來計(jì)算價(jià)格,將其里程和價(jià)格對(duì)應(yīng)的中文字碼表存入要顯示的字符串中。我們用地址JSS里表示已經(jīng)走過的公里,即8254傳過來的高電平,同時(shí)我們采用價(jià)格公式來計(jì)算價(jià)格,將其里程和價(jià)格對(duì)應(yīng)的中文字碼表存入要顯示的字符串中。
計(jì)算公式為: 價(jià)格=(里程-3)* 2……(里程>3)
價(jià)格= 7…………………..(里程<=3)并調(diào)用顯示模塊來顯示這些字碼其流程圖如下所示:
圈數(shù)統(tǒng)計(jì)模塊計(jì)數(shù)值JSS加一并十進(jìn)制化里程數(shù)加一里程數(shù)是否是大于3是價(jià)格為(里程-3)*2調(diào)用顯示模塊否價(jià)格為7
圖3-4計(jì)算里程模塊流程圖
3.1.5顯示模塊分析
在顯示模塊中,我們使用ST7920顯示我們要顯示的兩行字符串。我們采取先顯示第一行,再顯示第二行的方法,只是用ST7920的中間兩行。
調(diào)整顯示屏指針指向第二行調(diào)整顯示屏指針指向第三行調(diào)整字符串指針指向第一個(gè)字調(diào)整字符串指針指向第九個(gè)字輸出輸出延時(shí)延時(shí)
圖3-5顯示模塊流程圖
3.1.6結(jié)束模塊分析
結(jié)束模塊在程序的尾部在結(jié)束模塊中,我們規(guī)定只要在鍵盤上按任意一個(gè)鍵就會(huì)結(jié)束整個(gè)程序。如果無鍵按下,則程序自動(dòng)跳轉(zhuǎn)到程序頭部。其程序流程圖如下圖所示:
調(diào)用DOS中斷是否有鍵按下是結(jié)束否判斷開關(guān)模塊
圖3-6結(jié)束模塊流程圖
3.2程序代碼
IO8253A
EQU 280H IO8253B
EQU 281H IO8253C
EQU 283H
DATA
SEGMENT HZ DW 0C2B7H,0B3CCH,0A3B0H,0A3B0H,0A3AEH,0A3B0H,0B9ABH,0C0EFH
DW BCDBH,0B8F1H,0A3B0H,0A3B0H,0A3B0H,0A3AEH,0A3B0H,0D4AAH;存放原始輸出 HZ_TAB DW 0C2B7H,0B3CCH,0A3B0H,0A3B0H,0A3AEH,0A3B0H,0B9ABH,0C0EFH
DW 0BCDBH,0B8F1H,0A3B0H,0A3B0H,0A3B0H,0A3AEH,0A3B0H,0D4AAH;存放要輸出的值 HZ_BG DW 0BFD5H,0B3B5H,0A2A0H,0A2A0H,0BBB6H,0D3ADH,0B3CBH,0D7F8H
DW 0A2A0H,0A2A0H,0A2A0H,0A2A0H,0A2A0H,0A2A0H,0A2A0H,0A2A0H;存放“空車歡迎乘坐”
HZ_ADR DB ?
;存放顯示行起始端口地址 JSS
DW 0000H DII
DW 0000H GAO
DW 0000H ZHE
DW 0000H NUMBER
DW 0A3B0H,0A3B1H,0A3B2H,0A3B3H,0A3B4H,0A3B5H,0A3B6H,0A3B7H,0A3B8H,0A3B9H DATA
ENDS IO_ADDRESS
EQU 288H
CODE SEGMENT ASSUME CS:CODE,DS:DATA START:
MOV AX,DATA MOV DS,AX
MOV DX,IO_ADDRESS ADD DX,3 MOV AL,82H OUT DX,AL
;8255初始化 MOV AL,0FFH MOV DX,300H OUT DX, AL CALL CLEAR
;LCD 清除
LLL:
MOV DX,IO_ADDRESS ADD DX,1 IN AL,DX
;判斷開關(guān)是否打開 AND AL,01H CMP AL,01H JZ F0 CALL CHUSHI JMP LLL F0: MOV AL,01110110B MOV DX,IO8253C OUT DX,AL
;8254初始化 MOV AL,0FFH MOV DX,IO8253B OUT DX,AL MOV AL,0FFH
;設(shè)置計(jì)數(shù)初值0FFFFH OUT DX,AL F1: MOV AL,01000000B
MOV DX,IO8253C OUT DX,AL MOV DX,IO8253B
IN AL,DX MOV AH,AL IN AL,DX XCHG AH,AL CMP AX,159FH
;查看是否下降到159FH JA F1
;不滿足條件繼續(xù)讀值
MOV AL,01110110B
;重置8253 MOV DX,IO8253C OUT DX,AL MOV AL,0FFH MOV DX,IO8253B OUT DX,AL MOV AL,0FFH OUT DX,AL
CALL DISP
;調(diào)顯示子程序
CALL DDSP
CALL DELAY PUSH DX
MOV AH,06H MOV DL,0FFH INT 21H POP DX
JZ LLL
MOV AH,4CH
;退出
INT 21H L1:
JMP
START;L1
CHUSHI PROC NEAR
LEA SI, HZ_TAB LEA DI,HZ MOV CX,0FH F3: ADD SI,2 ADD DI,2 MOV AX,[DI] MOV [SI],AX LOOP F3
;重置HZ_TAB
MOV AX,0000H LEA BX,JSS MOV [BX],AX LEA BX, HZ_BG MOV CH,2
CALL LCD_DISP LEA BX, HZ_BG MOV CH,3
;顯示“空車歡迎乘坐” CALL LCD_DISP RET CHUSHI ENDP
DDSP
PROC NEAR
LEA DI,HZ_TAB LEA BX,JSS LEA SI,NUMBER MOV AX,WORD PTR[BX]
MOV BP,AX AND BP,00FFH ADD BP,BP
MOV DX,WORD PTR[BP+SI] MOV WORD PTR[DI+6],DX
;將JSS中低八位傳入HZ_TAB MOV BP,AX AND BP,0FF00H ROR BP,8 ADD BP,BP MOV DX,WORD PTR[BP+SI] MOV WORD PTR[DI+4],DX
LEA BX, HZ_TAB
MOV CH,2
息
CALL LCD_DISP LEA DI,HZ_TAB LEA BX,JSS LEA SI,NUMBER MOV AX,WORD PTR[BX] CMP AX,0003H
JBE L3 CALL BJ LEA BX,JSS JMP L4
L3:MOV BP,0007H
ADD BP,BP MOV DX,WORD PTR[BP+SI ] MOV WORD PTR[DI+24],DX JMP L4 L4:
LEA BX, HZ_TAB
MOV CH,3
CALL LCD_DISP RET DDSP
ENDP
BJ
PROC NEAR
LEA DI,HZ_TAB LEA BX,JSS LEA SI,NUMBER MOV AX,WORD PTR[BX] CMP AL,03H
;將JSS中高八位傳入HZ_TAB
;顯示第2行信;比較路程與3的大小;路程比3小的情況
;顯示第3行信息
JAE BJ1 SUB AH,01H ADD AL,0AH SUB AL,03H AAS
;路程減三并十進(jìn)制化 JMP BJ2 BJ1:
SUB AX,0003H BJ2: MOV CX,AX AND AX,00FFH ADD AL,AL AAA ADD AX,07H AAA
LEA BX,DII MOV [BX],AX;DII MOV BP,AX AND BP,00FFH ADD BP,BP MOV DX,WORD PTR[BP+SI] MOV WORD PTR[DI+24],DX
MOV AX,CX SHR AX,8 AND AX,00FFH ADD AL,AL
AAA LEA BX,GAO MOV [BX],AX;GAO LEA BX,DII MOV DX,[BX];DII AND AX,00FFH AND DX,0FF00H SHR DX,8 AND DX,00FFH ADD AL,DL
AAA LEA BX,ZHE MOV [BX],AX;ZHE MOV BP,AX AND BP,00FFH ADD BP,BP MOV DX,WORD PTR[BP+SI]
;路程加七并十進(jìn)制化;先計(jì)算個(gè)位
;十位相加
;再加進(jìn)位
MOV WORD PTR[DI+22],DX
;再計(jì)算十位 LEA BX,ZHE MOV DX,[BX] LEA BX,GAO MOV AX,[BX] AND DX,0FF00H AND AX,0FF00H SHR AX,8 SHR DX,8 ADD DL,AL
;百位加進(jìn)位 AAA MOV BP,DX AND BP,00FFH ADD BP,BP MOV DX,WORD PTR[BP+SI] MOV WORD PTR[DI+20],DX
;最后計(jì)算百位 RET BJ ENDP
DISP
PROC NEAR
;顯示子程序
PUSH DX
LEA BX, JSS
MOV AX,WORD PTR[BX]
ADD AL,01H
CMP AL,09H
;判斷是否<=9
JLE NUM
;若是則為'0'-'9',ASCII碼加30H
MOV AL,00H
ADD AH,01H
CMP AH,0AH
JZ L2 NUM:
MOV WORD PTR[BX],AX
ADD AL,30H
ADD AH,30H
MOV DL,AH
MOV DH,AL
MOV AH,02H
;屏幕顯示
INT 21H
MOV DL,DH
MOV AH,02H
;屏幕顯示
INT 21H
MOV DL,0DH
;加回車符
INT 21H
MOV DL,0AH
;加換行符
INT 21H
POP DX
RET
;子程序返回 DISP ENDP L2: MOV AH,4CH
;退出
INT 21H
CLEAR
PROC
MOV AL,0CH
CLEAR
FUNCUP
;
;
;
FUNCUP
LCD_DISP
;
址
DISP_SEC:
NEXT:
CONTINUE:
MOV DX, IO_ADDRESS OUT DX,AL
;設(shè)置CLEAR命令 CALL CMD_SETUP
;啟動(dòng)LCD執(zhí)行命令 RET
ENDP
PROC MOV AL, 0FH
;LCD功能設(shè)置命令 OUT DX, AL CALL CMD_SETUP MOV AL, 34H
;LCD顯示狀態(tài)命令 OUT DX, AL CALL CMD_SETUP RET
ENDP PROC LEA BX, HZ_TAB CMP CH, 2 JZ DISP_SEC MOV BYTE PTR HZ_ADR, 88H
;第三行起始端口地ADD BX,16
;指向第二行信息 JMP NEXT MOV BYTE PTR HZ_ADR,90H MOV CL,8
PUSH CX MOV AL,HZ_ADR MOV DX, IO_ADDRESS OUT DX, AL CALL CMD_SETUP
;設(shè)定DDRAM地址命令 MOV AX,[BX] PUSH AX MOV AL,AH
;先送漢字編碼高位 MOV DX,IO_ADDRESS OUT DX,AL CALL DATA_SETUP
;輸出漢字編碼高字節(jié)
CALL DELAY
;延遲
POP AX
MOV DX,IO_ADDRESS
OUT DX, AL
CALL DATA_SETUP
;輸出漢字編碼低字節(jié)
CALL DELAY
INC BX
INC BX
;修改顯示內(nèi)碼緩沖區(qū)指針
INC BYTE PTR HZ_ADR
;修改LCD顯示端口地址
POP CX
DEC CL
JNZ CONTINUE
RET LCD_DISP
ENDP CMD_SETUP
PROC
MOV DX,IO_ADDRESS
制端口
ADD DX,2
NOP
MOV AL,00000000B
(LCD I端=0,W端=0)
OUT DX, AL
CALL DELAY
NOP
MOV AL,00000100B
=1)
OUT DX, AL
NOP
CALL DELAY
MOV AL, 00000000B
0)
OUT DX, AL
CALL DELAY
RET CMD_SETUP
ENDP DATA_SETUP
PROC
MOV DX,IO_ADDRESS
口
ADD DX,2
MOV AL,00000001B
(LCD I端=1)
OUT DX, AL
NOP
CALL DELAY
;指向8255端口控
;PC1置0,PC0置0
;PC2置1(LCD E端
;PC2置0,(LCD E端置
;指向8255控制端
;PC1置0,PC0=1
MOV AL,00000101B
;PC2置1(LCD E端=1)
OUT DX, AL
NOP
CALL DELAY
MOV AL, 00000001B
;PC2置0,(LCD E端=0)
OUT DX, AL
NOP
CALL DELAY
RET DATA_SETUP
ENDP DELAY
PROC
PUSH CX
PUSH DX
MOV CX, 0FFFH X1:
LOOP
X1
POP DX
POP CX
RET DELAY
ENDP
CODE ENDS
END START
四、程序結(jié)果
我們利用8254、8255、ST7920顯示屏、直流電機(jī)等制作出了一個(gè)出租車計(jì)價(jià)器有專用鍵可以表示是否空車,同時(shí)利用直流電機(jī)模擬車輪運(yùn)動(dòng),通過路程計(jì)算價(jià)格,成果如下圖所示:
圖4-1程序結(jié)果圖
五、分析與測(cè)試
程序中,我遇到的最大的難題就是如何完成正確的十進(jìn)制計(jì)算,因?yàn)樗械挠?jì)算指令都是十六進(jìn)制的,雖然有的計(jì)算里有類似AAA這樣的調(diào)整指令,但是很多時(shí)候就不一定記得起來加上。同時(shí)由于需要根據(jù)數(shù)字來查表對(duì)應(yīng)相應(yīng)的字符碼,而且我是建立一個(gè)從零到九的數(shù)組,而由于計(jì)算錯(cuò)誤導(dǎo)致經(jīng)常出現(xiàn)亂碼,而且比較難找到相應(yīng)的錯(cuò)誤。而且有些計(jì)算沒有十進(jìn)制轉(zhuǎn)換指令,需要自己編寫。
同時(shí)我認(rèn)為我利用提前存儲(chǔ)變量來表示走過的路程比利用堆棧要好,因?yàn)槎褩H菀子浕?,而變量有?dú)特的名字,利于記憶與調(diào)用。而且易于清零、增減。
六、心得體會(huì)
這次課程設(shè)計(jì)中,令我印象最為深刻的就是我們應(yīng)該有一種堅(jiān)持的精神,有時(shí)候幾個(gè)小時(shí)都沒有成果,找不到BUG。顯示的就是有問題,這時(shí)候我們應(yīng)該有一種堅(jiān)持下去的毅力,積極詢問老師同學(xué),問題的解決就很快了。
同時(shí)我發(fā)現(xiàn)編程習(xí)慣非常重要,應(yīng)該有一個(gè)提前的規(guī)劃,不能想到哪寫到哪,這樣的話,后期的DEBUG會(huì)非常麻煩,因?yàn)樽约阂部床欢约旱拇a,我們都應(yīng)該有規(guī)范化的代碼意識(shí),這樣的編程能力才能上升。
參考文獻(xiàn)
[1]周荷琴,吳秀清,《微型計(jì)算機(jī)原理與接口技術(shù)》,合肥:中國(guó)科學(xué)技術(shù)大學(xué)出版社 2008。[2] 曹國(guó)清,《數(shù)字電路與邏輯設(shè)計(jì)》,徐州:中國(guó)礦業(yè)大學(xué)出版社 2003。[3] 8255芯片原理:http://baike.baidu.com/link?url=KHojvZzBGmo26_6iYGTdrdqH6PxQbM1Hnnc8hWQNPIp60L7TWG5LZu_ppSkXo5maU5M4APs4qCGSudiqZ0bdl_ [4]ST7920芯片原理:http://wenku.baidu.com/view/0dafd9232f60ddccda38a0fa.html訪問時(shí)間2013/10/15 [5]ST7920中文字碼表:http://wenku.baidu.com/view/d4abe628647d27284b735127.html訪問時(shí)間:2013/10/15