超聲波避障小車的設計與制作
摘 要
智能小車是一種能夠通過編程手段完成特定任務的小型化機器人,它具有制作成本低廉,電路結構簡單,程序調試方便等優點。由于具有很強的趣味性,智能小車深受廣大機器人愛好者以及高校學生的喜愛。
本論文介紹的是具有自動避障功能的智能小車的設計與制作(以下簡稱智能小車),論文對智能小車的方案選擇,設計思路,以及軟硬件的功能和工作原理進行了詳細的分析和論述。經實踐驗收測試,該智能小車的電路結構簡單,調試方便,系統反映快速、靈活,設計方案正確、可行,各項指標穩定、可靠。
目 錄
摘 要 I
Abstract II
目 錄 III
第一章 緒論 1
1.1項目研究背景及意義: 1
1.2項目主要研究內容: 1
1.3設計思路: 1
1.4應用場合和功能: 2
第二章 總體方案 3
2.1總體方案概述: 3
2.2 總體電路原理圖: 3
第三章 各模塊功能介紹 4
3.1障礙物測距系統: 4
3.2顯示模塊: 5
3.3驅動模塊: 10
3.4電源模塊: 12
第四章 軟件設計 13
4.1 程序設計流程圖 13
4.2 關鍵程序設計: 14
第五章 系統調試 17
5.1 調試的思路: 17
5.2 各模塊的調試: 17
5.3 調試心得: 19
第六章 結論與展望 20
6.1 結論: 20
6.2 展望: 20
致 謝 21
參考資料 22
附錄 23
1.元器件清單: 23
2.樣機實物照片: 24
3.電路原理圖: 25
相關程序 26
第一章 緒論
1.1項目研究背景及意義:
智能作為現代社會的新產物,是以后的發展方向,他可以按照預先設定的 模式在一個特定的環境里自動的運作,無需人為管理,便可以完成預期所要達 到的或是更高的目標。本設計主要體現多功能小車的智能模式,設計中的理論 方案、分析方法及特色與創新點等可以為自動運輸機器人、采礦勘探機器人、 家用自動清潔機器人等自動半自動機器人的設計與普及有一定的參考意義。同 時小車可以作為玩具的發展對象,為中國玩具市場技術含量的缺乏進行一定的 彌補,實現經濟收益,形成商業價值。 超聲波作為智能車避障的一種重要手段,以其避障實現方便,計算簡單, 易于做到實時控制,測量精度也能達到實用的要求,在未來汽車智能化進程中 必將得到廣泛應用。我國作為一個世界大國,在高科技領域也必須占據一席之 地,未來汽車的智能化是汽車產業發展必然的,在這種情況下研究超聲波在智 能車避障上的應用具有深遠意義,這將對我國未來智能汽車的研究在世界高科 技領域占據領先地位具有重要作用。 本智能小車系統最誘人的前景就是可用于未來的智能汽車上了,當駕駛員 因疏忽或打瞌睡時這樣的智能汽車的設計就能體現出它的作用。如果汽車偏離 車道或距障礙物小于安全距離時,汽車就會發出警報,提醒駕駛員注意,如果 駕駛員沒有及時作出反應,汽車就會自動減速或停靠于路邊。 這樣的小車還可以用于月球探測等的無人探月車,幫助我們傳達月球上更 多的信息,讓我們更加的了解月球,為將來登月做好充分準備。 這樣的小車在科學考察探測車上也有廣闊的應用前景,在科學考察中,有 很多危險且人們無法涉足的地方,這時,智能科學考察車就能夠派上用場,在 它上面裝上攝像機,代替人們進行許多無法進行的工作。
1.2項目主要研究內容:
本設計題目為智能避障小車設計,主要研究小車的避障功能,小車遇到障礙物時,當距離障礙物大于40cm,PWM信號自增,驅動電機加速,小車加速前進,當小于30cm時,PWM信號自減,驅動電機減速,小車減速前進,并且小車采取相應的避障措施。這里探測裝置必不可少,因為超聲波在距離檢測方面的較準確定位。所以采用超聲波傳感器作為探測裝置,由于超聲波遇到障礙物時發生像光一樣的反射和散射,在經過多次發射之后再回到超聲波檢測端口會產生較嚴重的路程差,從而影響對距離的檢測進而影響對障礙物的較準確定位。通過軟件內部校準優化消除外部物理條件造成的誤差從而達到對障礙物的較準確定位。
1.3設計思路:
直流電機PWM控制系統的主要功能包括:實現對直流電機的加速、減速,并且可以調整電機的轉速,能夠很方便的實現電機的智能控制。主體電路:即直流電機 PWM 控制模塊。這部分電路主要由 AT89S52 單片機 的 I/O 端口、定時計數器、外部中斷擴展等控制直流電機的加速、減速以及轉彎,并且可以調整電機的轉速,能夠很方便的實現電機的智能控制。 其間是通過 AT89S52 單片機產生脈寬可調的脈沖信號并輸入到 L298 驅動芯片來 控制直流電機工作的。該直流電機 PWM 控制系統由以下電路模塊組成:設計控制部分: 主要由 AT89S52 單片機的外部中斷擴展電路組成。直流電機PWM控制實現部分主要由電機和 L298 直流電機驅動模塊組成。設計顯示部分:LCD 數碼顯示部分,實現對超聲波測的距離的實時顯示。
1.4應用場合和功能:
應用場合:智能小車是一種能夠通過編程手段完成特定任務的小型化機器人,它具有制作成本低廉,電路結構簡單,程序調試方便等優點。由于具有很強的趣味性,智能小車深受廣大機器人愛好者以及高校學生的喜愛。同時在玩具的應用上深受小朋友的青睞。
功能:本小車使用AT89S52單片機作為主控芯片,它通過超聲波測距來獲取小車距離障礙物的距離,并且用LED顯示出來,當小車與障礙物的距離大于40cm時,小車會沿直線前進,當小車與障礙物的距離小于30cm時,小車轉彎以避開障礙物,并且此時蜂鳴器報警。在避開障礙物后,小車會沿直線前進。
第二章 總體方案
2.1總體方案概述:
本小車使用AT89S52單片機作為主控芯片,它通過超聲波測距來獲取小車距離障礙物的距離,并且用LCD顯示出來,當小車與障礙物的距離大于40cm時,小車會沿直線前進,當小車與障礙物的距離小于30cm時,小車轉彎以避開障礙物,并且此時蜂鳴器報警。在避開障礙物后,小車會沿直線前進。簡要框圖如圖2-1。
圖 2.1:簡要框圖
2.2 總體電路原理圖:
第三章 各模塊功能介紹
3.1障礙物測距系統:
方案一:超聲波視覺
優點:價格合理,夜間不受影響。易于多目標測量和分類,分辨率好。缺點:測量范圍小,對天氣變化敏感。不能直接測量距離,算法復雜,處理速度慢。
方案二:激光雷達MMW雷達
優點:夜間不受影響,不受燈光、天氣影響。缺點:對水、灰塵、燈光敏感、價格貴。
探測障礙的最簡單的方法是使用超聲波傳感器,它是利用向目標發射超聲波脈沖,計算其往返時間來判定距離的。算法簡單,價格合理。所以我們選擇超聲波傳感器。
超聲波測距原理:
首先利用單片機輸出一個40kHz的觸發信號,把觸發信號通過TRIG管腳輸入到超聲波測距模塊,再由超聲波測距模塊的發射器向某一方向發射超聲波,在發射時刻的同時單片機通過軟件開始計時,超聲波在空氣中傳播,途中碰到障礙物返回,超聲波測距模塊的接收器收到反射波后通過產生一個回應信號并通過ECHO腳反饋給單片機,此時單片機就立即停止計時。時序圖如圖1所示。由于超聲波在空氣中的傳播速度為340m/s,根據計時器記錄的時間t,就可以計算出發射點距障礙物的距離,即:S=VT/2,通過單片機來算出距離。
圖3.1:超聲波測距原理
3.2顯示模塊:
方案一:用LCD顯示。
優點:輻射小、顯示內容多 、低耗能、散熱小、顯示的畫面穩定不閃爍。缺點:不適合做圖,圖像還原不好、有可視范圍限制 。
方案二:用LED顯示。
優點:亮度高、成本低,缺點:不能顯示漢字,顯示內容較少。
對于本課題的要求,我們選擇LCD實現功能,顯示內容多,低功耗,顯示畫面穩定不閃爍,硬件電路設計簡單。
字符型液晶顯示模塊是一種專門用于顯示字母、數字、符號等點陣式LCD,目前常用16*1,16*2,20*2和40*2行等的模塊。下面以長沙太陽人電子有限公司的1602字符型液晶顯示器為例,介紹其用法。一般1602字符型液晶顯示器實物如圖:
圖 3.2.1:1602字符型液晶顯示器
3.2.1 1602LCD主要技術參數:
顯示容量:16×2個字符
芯片工作電壓:4.5—5.5V
工作電流:2.0mA(5.0V)
模塊最佳工作電壓:5.0V
字符尺寸:2.95×4.35(W×H)mm
3.2.2 引腳功能說明:
1602LCD采用標準的14腳(無背光)或16腳(帶背光)接口,各引腳接口說明如表3-2-1所示:
編號 符號 引腳說明 編號 符號 引腳說明
1 VSS 電源地 9 D2 數據
2 VDD 電源正極 10 D3 數據
3 VL 液晶顯示偏壓 11 D4 數據
4 RS 數據/命令選擇 12 D5 數據
5 R/W 讀/寫選擇 13 D6 數據
6 E 使能信號 14 D7 數據
7 D0 數據 15 BLA 背光源正極
8 D1 數據 16 BLK 背光源負極
表3-2-1:引腳接口說明表
第1腳:VSS為地電源。
第2腳:VDD接5V正電源。
第3腳:VL為液晶顯示器對比度調整端,接正電源時對比度最弱,接地時對比度最高,對比度過高時會產生“鬼影”,使用時可以通過一個10K的電位器調整對比度。
第4腳:RS為寄存器選擇,高電平時選擇數據寄存器、低電平時選擇指令寄存器。
第5腳:R/W為讀寫信號線,高電平時進行讀操作,低電平時進行寫操作。當RS和R/W共同為低電平時可以寫入指令或者顯示地址,當RS為低電平R/W為高電平時可以讀忙信號,當RS為高電平R/W為低電平時可以寫入數據。
第6腳:E端為使能端,當E端由高電平跳變成低電平時,液晶模塊執行命令。
第7~14腳:D0~D7為8位雙向數據線。
第15腳:背光源正極。
第16腳:背光源負極。
3.2.3 1602LCD的指令說明及時序:
1602液晶模塊內部的控制器共有11條控制指令,如表3-2-2所示:
序號 指令 RS R/W D7 D6 D5 D4 D3 D2 D1 D0
1 清顯示 0 0 0 0 0 0 0 0 0 1
2 光標返回 0 0 0 0 0 0 0 0 1 *
3 置輸入模式 0 0 0 0 0 0 0 1 I/D S
4 顯示開/關控制 0 0 0 0 0 0 1 D C B
5 光標或字符移位 0 0 0 0 0 1 S/C R/L * *
6 置功能 0 0 0 0 1 DL N F * *
7 置字符發生存貯器地址 0 0 0 1 字符發生存貯器地址
8 置數據存貯器地址 0 0 1 顯示數據存貯器地址
9 讀忙標志或地址 0 1 BF 計數器地址
10 寫數到CGRAM或DDRAM) 1 0 要寫的數據內容
11 從CGRAM或DDRAM讀數 1 1 讀出的數據內容
表3-2-2:控制命令表
1602液晶模塊的讀寫操作、屏幕和光標的操作都是通過指令編程來實現的。(說明:1為高電平、0為低電平)
指令1:清顯示,指令碼01H,光標復位到地址00H位置。
指令2:光標復位,光標返回到地址00H。
指令3:光標和顯示模式設置 I/D:光標移動方向,高電平右移,低電平左移 S:屏幕上所有文字是否左移或者右移。高電平表示有效,低電平則無效。
指令4:顯示開關控制。 D:控制整體顯示的開與關,高電平表示開顯示,低電平表示關顯示 C:控制光標的開與關,高電平表示有光標,低電平表示無光標 B:控制光標是否閃爍,高電平閃爍,低電平不閃爍。
指令5:光標或顯示移位 S/C:高電平時移動顯示的文字,低電平時移動光標。
指令6:功能設置命令 DL:高電平時為4位總線,低電平時為8位總線 N:低電平時為單行顯示,高電平時雙行顯示 F: 低電平時顯示5x7的點陣字符,高電平時顯示5x10的點陣字符。
指令7:字符發生器RAM地址設置。
指令8:DDRAM地址設置。
指令9:讀忙信號和光標地址 BF:為忙標志位,高電平表示忙,此時模塊不能接收命令或者數據,如果為低電平表示不忙。
指令10:寫數據。
指令11:讀數據。
與HD44780相兼容的芯片時序表如下:
讀狀態 輸入 RS=L,R/W=H,E=H 輸出 D0—D7=狀態字
寫指令 輸入 RS=L,R/W=L,D0—D7=指令碼,E=高脈沖 輸出 無
讀數據 輸入 RS=H,R/W=H,E=H 輸出 D0—D7=數據
寫數據 輸入 RS=H,R/W=L,D0—D7=數據,E=高脈沖 輸出 無
表3-2-3:基本操作時序表
讀寫操作時序如圖3.2.2和3.2.3所示:
圖 3.2.2 :讀操作時序
圖 3.2.3 :寫操作時序
3.3驅動模塊:
方案一:采用ULN2003驅動,它是由7組達林頓晶體管陣列和相應的電阻網絡以及鉗位二極管網絡構成,具有同時驅動7組負載的能力,一般用于高速大功率驅動電路。所以我們不采用這個方案。
方案二:采用由雙極性管組成的H橋電路(L298N)。用單片機控制晶體管使之工作在占空比可調的開關狀態,精確調整電機轉速。這種電路由于工作在管子的飽和截止模式下,則效率非常高;H橋電路保證了可以簡單地實現轉速和方向的控制,電子開關的速度很快,穩定性也很高。而且它有更強的驅動能力。L298N有過電流保護功能,當出現電機卡死時,可以保護電路和電機等。
L298N有過電流保護功能,當出現電機卡死時,可以保護電路和電機
等。所以我們選擇L298N。
下圖為L298內部圖:
圖3.3:L298內部原理圖
L298各引腳功能,如下表。
引腳 功能
1、15 SEN1、SEN2 分別為兩個H橋的電流反饋腳,不用時可以接地
2、3 1Y1、1Y2 輸出端,與對應輸入端(IN1、IN2)同邏輯
4 VS 驅動電壓,最小值需比輸入的低電平電壓高2.5V
5、7 IN1、IN2 輸入端,TTL電平兼容
6、11 EN1、EN2 使能端,低電平禁止輸出
8 GND 地
9 VSS 邏輯電源,4.5~7V
10、12 IN3、IN4 輸入端,TTL電平兼容
13、14 2Y1、2Y2 輸出端,與對應輸入端(IN3、IN4)同邏輯
表3-3-1 封裝引腳及功能
驅動電機的運行,I/O端口狀態與電機制動對照表,如下。
IN1 IN2 IN3 IN4 EN1 EN2 轉速
1 0 1 0 1 1 正轉
0 1 0 1 1 1 反轉
1 1 1 1 1 1 停止
0 0 0 0 1 1 停止
X X X X 0 0 停止
表3-3-2 I/O端口狀態與電機制動對照表
3.4電源模塊:
我們選擇采用5v的獨立的穩壓電源。
優點:穩定可靠,且有各種成熟電路可供選用;
缺點:各模塊都采用獨立電源,會使系統復雜,且可能影響電路電平。
綜合電源模塊的缺優點,和電路的實際需求,我們采用了兩塊獨立穩壓電源,一塊給小車的電機驅動供電,一塊給小車的芯片供電,這樣彌補了單個獨立電源供電出現電力不足的情況。
第四章 軟件設計
4.1 程序設計流程圖
本設計系統軟件采用模塊化結構,由主程序﹑定時子程序、電機驅動子程序﹑中斷子程序、顯示子程序﹑算法子程序構成。主程序流程圖如圖4.1所示。
圖 4.1:主程序流程圖
4.2 關鍵程序設計:
1. PWM產生程序設計:
void Timer2(void) interrupt 5
{
TF2=0;
RCAP2H=0x0fe;
RCAP2L=0x33;
++click;
if (click>=100) click=0;
if (click<=ZK1)
PWM1=1;
else
PWM1=0;
if (click<=ZK2)
PWM2=1;
else
PWM2=0;
}
2.超聲波的發射與接受程序設計:
void zd3() interrupt 3
{
TH1=0x0f8;
TL1=0x30;
timer++;
if(timer>=200)
{
timer=0;
TX=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
}
3.1602的初始化程序的設計:
void ini_lcd1602()
{
write_lcd1602(0x38,0);
delay(1);
write_lcd1602(0x0c,0);
delay(1);
write_lcd1602(0x06,0);
delay(1);
write_lcd1602(0x01,0);
delay(1);
}
4.1602的寫程序的設計:
void write_lcd1602(uchar cmd,uchar i)
{
lcd_mang();
rs=i;
rw=0;
e=0;
_nop_();
_nop_();
e=1;
_nop_();
_nop_();
P0=cmd;
_nop_();
_nop_();
_nop_();
_nop_();
e=0;
}
5.1602的判忙程序的設計:
void lcd_mang()
{
rs=0;
rw=1;
e=1;
_nop_();
_nop_();
_nop_();
_nop_();
while(P0&0x80);
e=0;
}
第五章 系統調試
5.1 調試的思路:
本設計的智能避障小車,一共分為四大模塊。分別是:L298驅動模塊,超聲波測距模塊,LCD顯示模塊以及蜂鳴器報警模塊。調試的時候我們可以把四大模塊分別調試,最后再把所有模塊組合起來再進行最后的整機調試這樣一個調試的思路。
5.2 各模塊的調試:
5.2.1 LCD的調試:首先根據電路圖將顯示模塊焊好,再用萬用表檢查電路是否出現短路。一切都正常的情況下,將LCD測試程序燒到芯片中,觀察LCD的顯示是否正確,如圖5.2.1。一開始可能什么都不顯示,這個時候我們只需調整LCD 3腳的變阻器阻值即可。
圖 5.2.1:LCD測試圖
5.2.2 超聲波的調試:
超聲波模塊一共有四個腳,一個是VCC,一個是GND,還有兩個分別是超聲波的發射和接收引腳。連接電路時候只需引出四根插線,分別連接到89S52的對應引腳,燒制好測試程序,測試結果圖如5.2.2。本設計四根插線分別連接到VCC,GND,還有發射和接收引腳分別為:P3.0和P3.2口。
圖 5.2.2:超聲波測試圖
5.2.3 蜂鳴器報警調試:
蜂鳴器的連接很簡單,只需用一個PNP管來做驅動,當低電平到來時蜂鳴器發出聲音,當高電平到來時沒有聲音。本設計中,蜂鳴器連接到P3.4口,如圖5.2.3所示。
圖5.2.3:蜂鳴器報警電路
5.3 調試心得:
通過系統的調試,我們可以學到更多的知識,我們也可以發現仿真和實物調試不同的地方。程序設計的結果可能往往和實物調試出的結果不一樣,這就需要我們去思考,去斟酌,去改進,以達到預期效果。通過程序和硬件的調試,我們可以更深刻的理解各功能模塊之間的聯系,也可以明白各調試的步驟。
在調試的過程中,我也遇到許多問題,例如:我在宿舍調試好小車之后,帶到班級時候在插上電源試圖讓小車跑起來時候,發現超聲波模塊失去了作用,LCD不再顯示數據了,后來我用電腦USB口供電發現也不可以,檢查了許久才發現是超聲波模塊上的電源線和地線的兩根插線出現了斷路,換線之后LCD正常顯示數值,小車正常行駛。整個調試過程需要硬件和軟件結合起來調試,要仔細檢查電路,認真思考程序。
硬件部分調試的步驟:
1) 檢查原理圖連接是否正確
2) 用萬用表檢查是否有虛焊,引腳短路現象
3) 檢查原理圖與電路板上引腳是否一致
4) 各模塊逐個調試,看看各模塊是否能用
5) 整合在一起調試,用電腦USB口供電
6) 在5的基礎上用電池供電
第六章 結論與展望
6.1 結論:
歷時三個月的設計過程中,我首先邊查資料,邊在實驗室焊接小車的線路板。在焊接過程中,我感覺到即使是一個簡單的電路,要想很輕松的焊好,也不是很容易的事情。有時是“虛焊”的原因,有時可能是阻值選錯。在焊接顯示電路時,我就錯將680歐的電阻焊成了6.8千歐。這使我深深感受到理論與實際間的差距。在調試過程中,發現插上編程器后不能燒制程序,通過檢查電路發現,AT89S52芯片的使能端沒有接VCC。改好之后重新燒制,發現還是不可以,通過再次檢查,發現是共陰管的驅動芯片74LS245的引腳出現焊接錯誤。通過這些調試,提高了我檢查電路的能力,以及鞏固了電路圖的知識。通過這樣的設計,提高了我的動手能力。每天在實驗室除了焊接線路板,還可以上機編程,使我軟件調試知識也提高了。本設計采用的是89S52單片機,這主要是因為該單片機的穩定性比較好。還可以采用其它系列的單片機。比如采用陵陽單片機,就可以簡化編程,但其穩定性不是很好。
6.2 展望:
1、在本課題的基礎上,我們可以在小車的底座下面裝一個吸塵裝置,這樣就可以在小車行駛的過程中吸除一些預先放好的小紙屑。
2、設計出兩輛小車,一輛小車放在另一輛的前面。當前面一輛小車起動時候,后面一輛小車也起動,前面一輛小車轉彎的時候后面一輛也跟著轉彎,前面一輛小車停止時,后面一輛也跟著停止。
致 謝
歷時三個月的畢業設計已經告一段落。經過自己不斷的搜索努力以及白老師的耐心指導和熱情幫助,本設計已經基本完成。在這段時間里,白老師嚴謹的治學態度和熱忱的工作作風令我十分欽佩,他的指導使我受益非淺。
通過這次畢業設計,使我深刻地認識到學好專業知識的重要性,也理解了理論聯系實際的含義,并且檢驗了大學四年的學習成果。雖然在這次設計中對于知識的運用和銜接還不夠熟練。但是我將在以后的工作和學習中繼續努力、不斷完善。這三個月的設計是對過去所學知識的系統提高和擴充的過程,為今后的發展打下了良好的基礎。
由于自身水平有限,設計中一定存在很多不足之處,敬請各位老師批評指正。
參考資料
1 趙負圖,傳感器集成電路手冊.第一版,化學工業出版社,2004,590~591
2李華,MCS-51系列單片機實用接口技術,第三版,北京:1997年
3張紅潤,實用自動控制,成都:科技大學出版社。1990年1月
4康華光,電子技術基礎,北京:高等教育出版社,1983年10月
5潘新民,微型計算機控制技術,北京:人民郵電技術出版社,1988年3月
6趙依軍,單片機微型接口技術。北京:人民郵電技術出版社,1989年3月
7李廣弟,單片機基礎,北京:北京航空航天大學出版社,2001
8胡漢才,單片機原理及其接口技術,北京:清華大學出版社,1996
9王毅,單片機器件應用手冊,北京:人民郵電出版社,1995
附錄
1.元器件清單:
序號 元件名稱 數量 參數
1 AT89S52單片機 1 ——
2 超聲波模塊 1 ——
3 L298n 1
4 智能避障小車底盤 1
5 蜂鳴器 1
6 LCD液晶屏 1
2.樣機實物照片:
3.電路原理圖:
相關程序
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
unsigned char i;
sbit rs=P2^6; //定義引腳
sbit rw=P2^5;
sbit e=P2^7;
sbit TX=P3^0; //觸發信號引腳
sbit FM=P3^4;
sbit PWM1=P3^6; //pwm信號輸出
sbit PWM2=P3^7;
static char click=0;
unsigned char ZK1,ZK2;
unsigned int time=0;
unsigned int timer=0;
unsigned long S;
bit flag =0;
unsigned char code ASCII[19] = {'0','1','2','3','4','5','6','7','8','9','.','-','M','J','U',' ','L','I',':'};
static unsigned char DisNum = 0; //顯示用指針
unsigned long S=0;
unsigned char disbuff[11] ={ 0};
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/100;
disbuff[0]=13;
disbuff[1]=14;
disbuff[2]=15;
disbuff[3]=16;
disbuff[4]=17;
disbuff[5]=18;
disbuff[6]=S%1000/100;
disbuff[7]=10;
disbuff[8]=S%1000%100/10;
disbuff[9]=S%1000%10 %10;
disbuff[10]=12;
}
void delay_1(void) //誤差 0us
{
unsigned char a,b;
for(b=215;b>0;b--)
for(a=45;a>0;a--);
}
void delay(uchar a)
{
uchar i;
while(a--)
{
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
//判忙
void lcd_mang()
{
rs=0;
rw=1;
e=1;
_nop_();
_nop_();
_nop_();
_nop_();
while(P0&0x80);
e=0;
}
//1602的寫
void write_lcd1602(uchar cmd,uchar i) //當i為0的時候為向1602寫指令為1寫數據
{
lcd_mang();
rs=i;
rw=0;
e=0;
_nop_();
_nop_();
e=1;
_nop_();
_nop_();
P0=cmd;
_nop_();
_nop_();
_nop_();
_nop_();
e=0;
}
//1602的初始化
void ini_lcd1602()
{
write_lcd1602(0x38,0);
delay(1);
write_lcd1602(0x0c,0);
delay(1);
write_lcd1602(0x06,0);
delay(1);
write_lcd1602(0x01,0);
delay(1);
}
void Timer2Interrupt()
{
RCAP2H=0x0fe;
RCAP2L=0x33;
ET2=1; // 允許T2定時器中斷
EA=1; // 打開總中斷
TR2=1; // 啟動T2定時器
}
void zd0() interrupt 1
{
flag=1;
}
void zd3() interrupt 3 //T1中斷用來掃描數碼管和計800MS啟動模塊
{
TH1=0x0f8;
TL1=0x30;
timer++;
if(timer>=200)
{
timer=0;
TX=1; //800MS 啟動一次模塊
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
}
void Timer2(void) interrupt 5
{
TF2=0; // T2定時器發生溢出中斷時,需要用戶自己清除溢出標記
RCAP2H=0x0fe;
RCAP2L=0x33; /*恢復定時器初始值*/
++click;
if (click>=100) click=0;
if (click<=ZK1)
PWM1=1;
else
PWM1=0;
if (click<=ZK2)
PWM2=1;
else
PWM2=0;
}
//主函數
void main()
{
TMOD=0x19; //設T0為方式1,GATE=1;
TH0=0;
TL0=0;
TH1=0x0f8; //2MS定時
TL1=0x30;
ET0=1; //允許T0中斷
ET1=1; //允許T1中斷
TR1=1; //開啟定時器
Timer2Interrupt();
EA=1; //開啟總中斷
ZK1=20;
ZK2=20;
ini_lcd1602();
while(1)
{
while(INT0==0); //當RX為零時等待
TR0=1;
while(INT0==1); //當RX為1計數并等待
TR0=0; //關閉計數
Conut(); //計算
if (S>40) //控制加速
{
FM=1;
P1=0xaf;
ZK1=ZK1-5;
ZK2=ZK2-5;
}
else
if(S<30) //控制轉向
{
FM=0;
ZK1=ZK1+5;
ZK2=ZK2+5;
P1=0X8F;
delay_1();
}
if (ZK1>99) ZK1=1;
if (ZK1<1) ZK1=10;
if (ZK2>99) ZK2=1;
if (ZK2<1) ZK2=10;
write_lcd1602(0x80,0);
for(i=0;i<=10;i++)
write_lcd1602(ASCII[disbuff[i]],1);
}
}
|