基于STM32的無線遙控小車的設(shè)計(jì)與實(shí)現(xiàn)_第1頁
基于STM32的無線遙控小車的設(shè)計(jì)與實(shí)現(xiàn)_第2頁
基于STM32的無線遙控小車的設(shè)計(jì)與實(shí)現(xiàn)_第3頁
基于STM32的無線遙控小車的設(shè)計(jì)與實(shí)現(xiàn)_第4頁
基于STM32的無線遙控小車的設(shè)計(jì)與實(shí)現(xiàn)_第5頁
已閱讀5頁,還剩48頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

引言在這高速發(fā)展的21世紀(jì),路上隨處可見造型漂亮玩法新穎的玩具小車和飛機(jī),自動(dòng)公交車、無人出租車也是科學(xué)家們研究的熱門。我對(duì)這一嵌入式、也是自動(dòng)化技術(shù)十分的感興趣。首先它非常有趣,可以成為孩子和家人的娛樂活動(dòng),其次它的技術(shù)性也很高,和我的專業(yè)還算對(duì)口,最重要的一點(diǎn)就是,它的科技時(shí)尚性非常強(qiáng),是走在科技前沿的研究項(xiàng)目?;仡欀悄苘囕v研究的歷史:在上世紀(jì)50年代初,國外就有關(guān)于智能車輛的研究了。從90年代開始,智能車輛研究就進(jìn)入了系統(tǒng)化大規(guī)模的研究階段。尤其突出的成果是美國卡內(nèi)基梅隴大學(xué)機(jī)器人研究所完成的Navlab系列自主車輛的研究,這一研究成果成為國外智能車輛的主要里程碑。而國內(nèi)對(duì)于智能車輛的研究較晚,研究始于上世紀(jì)80年代,現(xiàn)在大部分還是使用入門級(jí)別的51單片機(jī)進(jìn)行設(shè)計(jì)與研究。為了彌補(bǔ)與國外研究的差距,教育部和工業(yè)和信息化部共同發(fā)起了全國大學(xué)生電子設(shè)計(jì)競(jìng)賽。本課題智能小車,通過各種藍(lán)牙模塊獲得外部的指令和內(nèi)部的中斷,實(shí)現(xiàn)簡(jiǎn)單的前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)、停止的簡(jiǎn)單遙控運(yùn)動(dòng)功能。通過研究完成簡(jiǎn)易智能小車的設(shè)計(jì),增進(jìn)了畢業(yè)生理論與實(shí)踐相結(jié)合的基礎(chǔ)知識(shí),也鍛煉了基本的動(dòng)手能力??梢允箤W(xué)生在了解智能化電器工作原理的基礎(chǔ)上,再獲得完成整體項(xiàng)目的能力,還能夠掌握stm32開發(fā)板的編程原理,為學(xué)生走上工程應(yīng)用,成為優(yōu)秀沉穩(wěn)的工程師打下了無比堅(jiān)固的基礎(chǔ)。2開發(fā)環(huán)境及軟件的介紹2.1開發(fā)環(huán)境系統(tǒng)環(huán)境:Windows72.2軟件介紹①Eclipse(藍(lán)牙遙控app)Eclipse是從事java開發(fā)的軟件工作人員的不二選擇,原因有n,一是因?yàn)樗_放源代碼,而且可擴(kuò)展,可塑性很強(qiáng)。就其本身而言,它只是一個(gè)框架和一組服務(wù),用于通過插件組件構(gòu)建開發(fā)環(huán)境;二是因?yàn)樗綆Я艘粋€(gè)標(biāo)準(zhǔn)的插件集,比如JDK,方便快捷,不用再次單獨(dú)安裝,省了麻煩;三是它界面友好,操作性強(qiáng),很容易使用。我使用的是EclipseIDEforJavaEEDevelopers(MARS),是一個(gè)2015年發(fā)布的最新版本。eclipse有java和javaee兩種產(chǎn)品,java的功能要少一點(diǎn),而javaee可以用于安卓開發(fā)和web開發(fā)。工具都已經(jīng)安裝在內(nèi),是全面理想的Java開發(fā)工具,java語言開發(fā)手機(jī)app的理想平臺(tái)。②Keil5(控制系統(tǒng))KeilC51是美國KeilSoftwar公司出品的51系列C語言軟件開發(fā)系統(tǒng),易學(xué)易用,包括C編譯器、宏匯編、鏈接器、庫管理和一個(gè)功能強(qiáng)大的仿真調(diào)試器等在內(nèi)的完整開發(fā)方案,通過一個(gè)集成開發(fā)環(huán)境(μVision)將這些部分組合在一起。我用的并不是keil的c51版本,而是MDK版本,c51版本不能開發(fā)stm32芯片,二MDK版本是一個(gè)stm32開發(fā)的利器。Keil公司是一家微控制器(MCU)軟件開發(fā)工具的獨(dú)立供應(yīng)商,于2005年由ARM公司收購。2011年3月ARM公司發(fā)布最新集成開發(fā)環(huán)境RealViewMDK開發(fā)工具中,集成了最新版本的KeilμVision4,其編譯器、調(diào)試工具與ARM器件完美匹配。2013年10月,Keil正式發(fā)布了KeilμVision5IDE,本次設(shè)計(jì)用的就是這一版本的軟件。它的界面強(qiáng)大而友好,功能欄漂亮又清晰,字號(hào)較大,顏色是綠色,起觀看感受良好的護(hù)眼作用。③STM32STlinkUtility(燒寫)STM32ST-LINKUtility軟件主要的功能就是量產(chǎn)(批量下載代碼的工具),它是一個(gè)功能多而全的實(shí)用工具,它的界面簡(jiǎn)潔專業(yè),用色舒適,可以新建和編輯文件、對(duì)flash數(shù)據(jù)快速讀取、對(duì)芯片進(jìn)行基本信息例如型號(hào)、ID、版本等的檢索、強(qiáng)大的IAR在線調(diào)試仿真功能、燒寫功能、幫助功能,非常方便。此外,雖然我是單獨(dú)安裝驅(qū)動(dòng)的,但它已經(jīng)包含了ST-Link驅(qū)動(dòng),無需再次下載,可以直接使用stlink有關(guān)仿真燒寫功能,是一款很好的下載(燒寫)仿真軟件。3總體設(shè)計(jì)3.1總體需求我認(rèn)為主要的功能需求有兩個(gè):遙控、電機(jī)驅(qū)動(dòng)。1.遙控通訊可選用的方式:①紅外線②無線電波③藍(lán)牙④總線總線因?yàn)椴环项}意,所以不考慮。不管是藍(lán)牙還是紅外線都需要使用模塊或者一個(gè)紅外/藍(lán)牙發(fā)送設(shè)備。我不太清楚無線電波是使用什么發(fā)送的,不過應(yīng)該也是根據(jù)對(duì)頻來發(fā)送數(shù)據(jù)。遙控器可以是實(shí)物,由電路或者模塊控制,也可以是遙控軟件。自己設(shè)計(jì)電路需要自己印制電路板。我想到可以編寫手機(jī)app來遙控,我雖然學(xué)習(xí)過安卓開發(fā),但關(guān)于藍(lán)牙部分我從未學(xué)習(xí)過,很感興趣,所以選擇了使用藍(lán)牙。2.電機(jī)驅(qū)動(dòng)有兩種方式:①自己設(shè)計(jì)電路來放大信號(hào),從而驅(qū)動(dòng)電機(jī)。②使用電機(jī)驅(qū)動(dòng)模塊??刂菩酒l(fā)出的信號(hào)是一定要經(jīng)過放大才能驅(qū)動(dòng)電機(jī)的。如果自己設(shè)計(jì)電路,就要涉及印制電路的工作,包括打孔、覆膜、成膜、脫膜,因?yàn)槲覍?duì)設(shè)計(jì)和印制電路沒有什么經(jīng)驗(yàn)和把握,加上有一個(gè)編寫app的任務(wù),時(shí)間算上去比較緊迫,所以選擇了簡(jiǎn)單的驅(qū)動(dòng)模塊方式來驅(qū)動(dòng)電機(jī)。3.2芯片模塊選擇控制芯片的選擇是一件重要的事情。C51和STM32的芯片是最為基礎(chǔ)通用的,其中c51是課程內(nèi)學(xué)過的,而STM32沒有學(xué)過?,F(xiàn)如今,c51單片機(jī)的使用通常是在大規(guī)模的復(fù)雜項(xiàng)目中,而stm32芯片以其小規(guī)模、低成本、易入門,在本次學(xué)習(xí)型開發(fā)上有著巨大的先天優(yōu)勢(shì)。也因?yàn)槭忻嫔嫌泻芏鄐tm32芯片的項(xiàng)目,而我卻沒有學(xué)過,所以想在本次設(shè)計(jì)中好好學(xué)習(xí)一下。STM32控制芯片有很多不同的型號(hào),如何選用,我的標(biāo)準(zhǔn)是,要一個(gè)熱門通用的最小型芯片。既然是做最簡(jiǎn)單的遙控小車,芯片必然不需要很大。圖3-1STM芯片型號(hào)上圖3-1為STM32的各種型號(hào)。STM8是8位系統(tǒng),32是32位系統(tǒng),我感覺8位顯然是不那么夠用。而STM32分為H7、F7、F4、F2、F3、F1、F0、L4+、L4、L1、L0好幾種型號(hào)。其中,F(xiàn)0、F1、F3為主流產(chǎn)品,L0、L1、L4、L4+為超低功耗產(chǎn)品,F(xiàn)2、F4、F7、H7為高性能產(chǎn)品。其中F101和F103最為主流,而F103C8T6的核心板十分小型,支持SWD燒寫,比較簡(jiǎn)單。下圖3-2為型號(hào)命名規(guī)則,我選擇的stm32f103c8t6為增強(qiáng)型芯片子系列、48引腳、64K字節(jié)flash、LQFP封裝、工作溫度為-40°~85°。圖3-2型號(hào)命名規(guī)則圖3-3F103C8T6核心板孔位圖上圖3-3為c8t6的核心板孔位圖,上側(cè)為B1、0、10、11、A0~7、C13~15,下側(cè)為B12~15、A8~15、B3~9,左側(cè)為USB接口,右側(cè)為SWD燒寫的四個(gè)接口,中間為各種核心接口和芯片。3.3車體設(shè)計(jì)和工具使用1.車體設(shè)計(jì)雖然這只是簡(jiǎn)單的小車,不是小汽車,不需要車體設(shè)計(jì)學(xué)習(xí)基礎(chǔ),但實(shí)際上車體設(shè)計(jì)是不可小覷的。最主要的問題是底板的材料,材料的質(zhì)量好壞其實(shí)是非常影響小車開起來的效果和使用壽命的。我有以下幾種設(shè)想:①木材②PCB③菲林片④塑料面板木材不太好看,可能也不太牢固,塑料面板安裝比較費(fèi)勁,容易散架。我在網(wǎng)上看到了線程的PCB小車底板,孔位和大小都很合理,如下圖3-4:圖3-4底盤2.工具及使用工具:電烙鐵、熱熔膠槍。圖3-5電烙鐵因?yàn)樵趯?shí)際過程中,我遭遇了很大的困難(詳情見下文第七章調(diào)試與測(cè)試),所以特別指出做小車的注意事項(xiàng):①在電機(jī)安裝在底板下之前對(duì)其進(jìn)行焊接。②確認(rèn)購買好的電烙鐵進(jìn)行焊接。焊接方法:一般來說是從針的兩個(gè)方向焊接的,一面是電烙鐵,一面是焊錫,但是劣質(zhì)電烙鐵和焊盤通常焊不上。就會(huì)變成焊錫與焊槍在同一側(cè),這樣容易虛焊,一定要當(dāng)心,最好拿一個(gè)微型放大鏡檢查。虛焊容易導(dǎo)致很多莫名其妙的(接觸不良)錯(cuò)誤。圖3-6熱熔膠、紅黑線、杜邦線、備用電池盒3.4軟件選擇1.藍(lán)牙遙控app:安卓開發(fā)常用軟件:MyEclipse、Eclipse等。我選擇Eclipse的原因是:方便安裝、使用簡(jiǎn)單、在之前課程中已經(jīng)安裝過。2.控制系統(tǒng):我學(xué)過c語言的keilC51,本次使用KeilMDK(version5),就能夠編寫stm32芯片的程序了。3.燒寫:這是個(gè)非常重要的問題。因?yàn)橹挥卸ㄏ铝诵酒吞?hào),知道這塊板支持什么燒寫模式,才能夠定下燒寫模式,才能夠定下燒寫軟件。燒寫其實(shí)有很多種方法,C51單片機(jī)其實(shí)就比較通用com口、flash、boot等串口來燒寫文件系統(tǒng),而stm32的燒寫方式則有J-link、ST-link、SWD、SPI、JTAG等。F103C8T6核心板支持SWD模式,可以使用STlink進(jìn)行燒寫,故而,我決定使用ST-link官方燒寫軟件。4硬件原理4.1STM32F103C8T6芯片圖4-1主控模塊(c8t6核心板)接口原理圖GPIO口就是通用IO接口,有PA~G。其中,PA9為輸出口,PA10為輸入口,我使用PB12~15連接電機(jī)。如下圖4-2,我使用STlink連接PC和SWD接口來實(shí)現(xiàn)仿真和燒寫。在拿到排針和核心板的時(shí)候,我需要先用電烙鐵把引腳焊起來,焊接方法如前頁。圖4-2功能分布圖上圖4-2為實(shí)物圖,孔圖在上章已經(jīng)介紹過。下圖4-3為核心板的詳細(xì)參數(shù),因?yàn)槭呛诵陌澹允亲頼ini的一個(gè)型號(hào),適合用作完成簡(jiǎn)易遙控小車。圖4-3參數(shù)介紹4.2HC05藍(lán)牙模塊圖4-4HC05藍(lán)牙模塊引腳接口STATE狀態(tài)引腳,正面有小燈閃爍表示狀態(tài):無連接狀態(tài)為快閃,連接狀態(tài)變?yōu)槁W。板載3.3V穩(wěn)壓芯片,輸入電壓直流3.6V-6V;未配對(duì)時(shí),電流約30mA(因LED燈閃爍,電流處于變化狀態(tài))。配對(duì)成功后,電流大約10mA。我連接TXD(輸出端)到c8t6的A10口(輸入口),GND和VCC接在主控板上即可??諘绲貛в行鬏斁嚯x10米。按下按鍵再給藍(lán)牙模塊通電可以進(jìn)入AT模式,設(shè)置參數(shù)和查詢信息??梢酝ㄟ^AT命令切換主機(jī)和從機(jī)模式。模塊默認(rèn)波特率為9600、默認(rèn)配對(duì)密碼為1234、默認(rèn)名稱為HC-05。帶透明熱縮管保護(hù)。4.3L298N電機(jī)驅(qū)動(dòng)模塊圖4-5L298N電機(jī)驅(qū)動(dòng)模塊上圖4-5為L298N實(shí)物圖,輸出AB口接兩個(gè)電機(jī),供電口接紅黑電源線。下圖4-6為原理圖,電機(jī)驅(qū)動(dòng)電路是一個(gè)放大電路,通過放大控制信號(hào)來驅(qū)動(dòng)電機(jī)。圖4-6L298N原理圖圖4-7輸入口與電機(jī)狀態(tài)根據(jù)上圖4-7L298N的資料數(shù)據(jù),只要了解輸入口與電機(jī)狀態(tài)的關(guān)系,就可以知道如何編寫控制程序了。IN1、2控制一個(gè)電機(jī)(右),IN3、4控制另一個(gè)(左)。4.4馬達(dá)、輪胎與電池馬達(dá)是直流減速馬達(dá)(俗稱TT馬達(dá)),電路圖如下,由圖可知馬達(dá)電路的原理,是一個(gè)放大電路。圖4-8馬達(dá)電路圖圖4-9馬達(dá)設(shè)計(jì)圖上圖4-9為馬達(dá)設(shè)計(jì)圖,我這里遇到了一個(gè)馬達(dá)和輪胎的適配性的問題,如果離地的時(shí)候輪胎轉(zhuǎn)得沒有問題,但是在地上跑卻不能正常運(yùn)行,是馬達(dá)和輪胎接觸不好。考慮換一個(gè)輪胎。各模塊的電壓不同,我設(shè)計(jì)用電池盒(蓄電池)向L298N通過12V接口供電,并向主控芯片供電,主控芯片向HC05用3.3V接口供電。我采用4節(jié)1.5V的5號(hào)電池供電,肯定是夠用的。而且我選擇的電池盒自帶開關(guān),是小車電源安全的保障。下圖4-10為供電流向圖。圖4-10供電流向圖4.5STlink燒寫器圖4-11燒寫器燒寫器連接芯片的SWD接口,IO、GUN、CLK、3.3V四個(gè)接口就夠了。SWD燒寫以其簡(jiǎn)單為優(yōu)勢(shì),可以通過最少的四根接線完成燒寫。5控制系統(tǒng)設(shè)計(jì)5.1原理圖和數(shù)據(jù)流程圖圖5-1控制系統(tǒng)原理圖上圖5-1為使用protues8畫的控制系統(tǒng)原理圖,畫得比較簡(jiǎn)單,由三個(gè)模塊(藍(lán)牙模塊未畫出)和兩個(gè)電機(jī)組成。藍(lán)牙模塊因?yàn)檎也坏狡鋷煳募?,從而不能?dǎo)入。下圖5-2為藍(lán)牙模塊原理圖。圖5-2HC05原理圖下圖5-2為數(shù)據(jù)流程圖,HC05從app上接收到數(shù)據(jù),通過輸入輸出口傳給C8T6,再通過L298N化為合格的高低電平信號(hào)。圖5-3數(shù)據(jù)流程圖5.2詳細(xì)設(shè)計(jì)①IO口定義位帶(bit-band)操作:支持了位帶操作后,可以使用普通的加載/存儲(chǔ)指令來對(duì)單一的比特進(jìn)行讀寫。圖5-4位帶操作優(yōu)勢(shì)支持位帶操作的兩個(gè)內(nèi)存區(qū)的范圍是:0x2000_0000‐0x200F_FFFF(SRAM區(qū)中的最低1MB)0x4000_0000‐0x400F_FFFF(片上外設(shè)區(qū)中的最低1MB)對(duì)SRAM位帶區(qū)的某個(gè)比特,記它所在字節(jié)地址為A,位序號(hào)為n(0<=n<=7),則該比特在別名區(qū)的地址為:AliasAddr=0x22000000+((A-0x20000000)*8+n)*4=0x22000000+(A-0x20000000)*32+n*4對(duì)于片上外設(shè)位帶區(qū)的某個(gè)比特,記它所在字節(jié)的地址為A,位序號(hào)為n(0<=n<=7),則該比特在別名區(qū)的地址為:AliasAddr=0x42000000+((A-0x40000000)*8+n)*4=0x42000000+(A-0x40000000)*32+n*4上式中,“*4”表示一個(gè)字為4個(gè)字節(jié),“*8”表示一個(gè)字節(jié)中有8個(gè)比特。圖5-5位帶操作②初始化輸出口圖5-6PB口的定義和初始化圖5-7PB12~15的初始化定義為PB輸出口設(shè)定模式、速度、初始化和reset。③串口定義圖5-8串口定義對(duì)串口初始化并使能串口,確定字長、停止位、校驗(yàn)、模式、中斷。對(duì)藍(lán)牙模塊傳來的數(shù)據(jù)進(jìn)行處理的函數(shù)也在串口(usart)的初始化之中,這是個(gè)比較重要的部分,使用GetITConfig函數(shù)來判斷中斷,然后使用ReceiveData函數(shù)進(jìn)行寄存器的讀取寫入。④主函數(shù)圖5-9主函數(shù)流程圖在串口經(jīng)過讀取的數(shù)據(jù)再傳入主函數(shù),進(jìn)行實(shí)際的電機(jī)控制。5.3仿真與燒寫我在proteus8上畫了原理圖,但鑒于沒有HC05,而且涉及藍(lán)牙的連接控制,在proteus8上就不太好仿真了。Keil5也是可以連接STlink并連接真機(jī)仿真的,但網(wǎng)上說不太好用,而且看上去比較麻煩。我感覺沒什么大問題,所以我直接燒寫之后測(cè)試了。圖5-10燒寫成功6藍(lán)牙遙控app設(shè)計(jì)6.1需求分析界面:①上、左、下、右、停五個(gè)按鍵界面②狀態(tài)標(biāo)題欄③藍(lán)牙連接菜單功能:①藍(lán)牙連接②狀態(tài)(thread)③數(shù)據(jù)傳送6.2詳細(xì)設(shè)計(jì) 圖6-1功能服務(wù)類 圖6-2界面1.生命周期本項(xiàng)目有2個(gè)activity、1個(gè)service,activity的生命周期如下圖6-3所示,先要經(jīng)過創(chuàng)建(create)、啟動(dòng)(start)、(重新開始resume)、(暫停pause)、停止stop、銷毀destory。圖6-3生命周期上圖6-3為一個(gè)activity的生命周期,下面從兩大activity開始介紹流程和功能:圖6-4生命周期與狀態(tài)參數(shù)主界面進(jìn)行create和start,然后進(jìn)行連接操作,轉(zhuǎn)到設(shè)備界面,進(jìn)行操作后傳參回到主界面。2.狀態(tài)參數(shù)STATE_NONE 無連接STATE_LISTEN start后監(jiān)聽中STATE_CONNECTING 正在連接STATE_CONNECTED 已連接MESSAGE_STATE_CHANGE 狀態(tài)變化MESSAGE_DEVICE_NAME 記錄連接上的設(shè)備名MESSAGE_TOAST 藍(lán)牙丟失/連接不上REQUEST_CONNECT_DEVICE 待連接設(shè)備REQUEST_ENABLE_BT 藍(lán)牙已連接3.線程圖6-5線程類根據(jù)不同的線程狀態(tài)決定操作,有三個(gè)線程:accept、connect、connected。Accept線程主要負(fù)責(zé)藍(lán)牙設(shè)備的預(yù)連接,connect主要負(fù)責(zé)連接,connected主要負(fù)責(zé)寫操作。4.操作流程①初始化:新建listview、藍(lán)牙適配、按鍵監(jiān)聽②連接→顯示已配對(duì)→搜索并顯示→選擇→返回參數(shù)③按鍵監(jiān)聽→service.write()→線程(write)→connectedthread.write()(完成對(duì)藍(lán)牙設(shè)備的數(shù)據(jù)傳送)連接功能//Theon-clicklistenerforalldevicesintheListViewsprivateOnItemClickListenermDeviceClickListener=newOnItemClickListener(){publicvoidonItemClick(AdapterView<?>av,Viewv,intarg2,longarg3){//Canceldiscoverybecauseit'scostlyandwe'reabouttoconnectmBtAdapter.cancelDiscovery();//GetthedeviceMACaddress,whichisthelast17charsintheViewStringinfo=((TextView)v).getText().toString();Stringaddress=info.substring(info.length()-17);//CreatetheresultIntentandincludetheMACaddressIntentintent=newIntent();intent.putExtra(EXTRA_DEVICE_ADDRESS,address);//SetresultandfinishthisActivitysetResult(Activity.RESULT_OK,intent);finish();}};2)搜索并顯示://Iftherearepaireddevices,addeachonetotheArrayAdapterif(pairedDevices.size()>0){findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);for(BluetoothDevicedevice:pairedDevices){mPairedDevicesArrayAdapter.add(device.getName()+"\n"+device.getAddress());}}else{StringnoDevices=getResources().getText(R.string.none_paired).toString();mPairedDevicesArrayAdapter.add(noDevices);}6.3藍(lán)牙連接功能NYNY圖6-4藍(lán)牙連接流程圖點(diǎn)擊搜索按鈕,搜索按鈕會(huì)消失,找到的設(shè)備會(huì)出現(xiàn)。7測(cè)試與調(diào)試兩個(gè)系統(tǒng)的調(diào)試步驟:①單個(gè)模塊的調(diào)試:先把a(bǔ)pp和控制程序在各自的仿真環(huán)境下測(cè)試部分功能。為連接好的小車做通電測(cè)試。②把有關(guān)模塊結(jié)合在一起調(diào)試:把a(bǔ)pp和HC05連接上,燒寫控制程序,一起測(cè)試,測(cè)試全部功能。③綜合調(diào)試:測(cè)試小車的安全、性能和強(qiáng)度。第二步看上去是比較困難的,原因如下:(1)模塊相互調(diào)用時(shí)接口會(huì)引入許多新問題。(2)一個(gè)模塊對(duì)另一個(gè)模塊可能造成不良影響。(3)幾個(gè)子功能組合起來不能并實(shí)現(xiàn)主功能。(4)誤差不斷積累達(dá)到不可接受的程度。7.1藍(lán)牙app的連接和搜索 圖7-1連接界面1 圖7-2連接界面2上圖7-1為主界面有兩個(gè)標(biāo)題欄、5個(gè)按鍵和兩個(gè)菜單按鈕。圖7-2為初始連接設(shè)備界面,自動(dòng)搜索已匹配設(shè)備并顯示在Listview里,可以直接進(jìn)行選擇,如果沒有要的設(shè)備,可以點(diǎn)擊下面“查找設(shè)備”按鍵。 圖7-3連接成功 圖7-4搜索上圖7-3為連接成功的界面,右上角狀態(tài)標(biāo)題顯示為“連接到:XXX”,并彈出廣播“connectedtoXXX”。圖7-4為點(diǎn)擊搜索按鍵后的連接界面,會(huì)顯示出搜索到的設(shè)備和地址。Ps:地址為17位。7.2藍(lán)牙app的前后左右停功能(后臺(tái)測(cè)試)圖7-5調(diào)試的log記錄導(dǎo)出備份上圖7-5為log的debug調(diào)試記錄導(dǎo)出,第一列為日期,第二列為時(shí)間,第三列“I/E”為類型,第四列為debug名稱,冒號(hào)后的第五列為內(nèi)容。7.3小車連接通電測(cè)試第一次通上電就燒起來了,很可能是因?yàn)榻泳€問題。圖7-6電池盒電線燒壞后殘余零件第二次我買了一些零件重新接線后,通電成功!圖7-7通電成功!由于郵寄使得引腳變松,我不得不重新做第三次,通電成功。圖7-8小車37.4整體(控制系統(tǒng)+藍(lán)牙app)調(diào)試①不能直接切換別的按鍵,要點(diǎn)一下停止,否則HC05會(huì)失去連接(無電)。猜測(cè)原因:電壓/電線連接。按理來說前后轉(zhuǎn)是可以直接切換的,和藍(lán)牙模塊并無關(guān)系。解決方法:接觸問題。結(jié)果:未解決②小車拿著測(cè)試,一切正常,但在地上跑的時(shí)候會(huì)有各種錯(cuò)誤。猜測(cè)原因:輪胎和馬達(dá)匹配不良。解決方法:換一對(duì)輪胎。結(jié)果:已解決③藍(lán)牙連接偶爾有自動(dòng)斷開的情況,HC05通電正常。猜測(cè)原因:電線連接問題。解決方法:重新接線或者固定或者焊接。結(jié)果:已解決④郵到學(xué)校后:一個(gè)馬達(dá)不會(huì)轉(zhuǎn)了;藍(lán)牙變得只能接收一個(gè)命令,然后就自動(dòng)斷開連接。過了一天:經(jīng)過重新插拔、調(diào)整角度,藍(lán)牙的“?!惫δ軙r(shí)而失靈。左側(cè)馬達(dá)依舊不轉(zhuǎn)。猜測(cè)原因:馬達(dá)問題,或者接線問題。解決方法:重新接線,測(cè)試馬達(dá)。結(jié)果:藍(lán)牙和馬達(dá)都是因?yàn)榻泳€和郵寄運(yùn)輸問題,使焊盤脫焊了,而且本來就因?yàn)殡娎予F不太好而沒焊好。重新焊接主控芯片后解決。7.5性能測(cè)試①安全性:安全性即小車是否安全。首先,我的接線避免了各種觸碰短接的可能性,接口和芯片為止都用熱熔膠或螺絲固定住。除非人為故意破壞,不然是不太可能短接引起安全事故的。圖7-9HC05熱熔膠固定圖7-10馬達(dá)熱熔膠固定其次,小車的電壓是5V。人體的安全電壓是36V(潮濕壞境下12V),安全電壓為10mA。所以小車不會(huì)對(duì)人體產(chǎn)生危害。②性能測(cè)試:因?yàn)槭亲詈?jiǎn)單的小車,所以沒有在調(diào)速方面進(jìn)行設(shè)計(jì)和編寫。小車的速度視在什么地方跑而定,平地速度為5m/s。③強(qiáng)度測(cè)試:強(qiáng)度測(cè)試分為2項(xiàng),抗摔和抗壓。抗摔:因?yàn)椴皇窃揭靶≤?,最好還是在平地跑,爬陡坡和石礫地還是比較困難的??箟海阂?yàn)樾≤嚊]有車頂,所以應(yīng)該是不抗壓的,壓壞電線就不好了。8總結(jié)時(shí)光如風(fēng),呼嘯而過又消失無蹤。在這個(gè)充滿青春記憶的熟悉大學(xué)校園里,一草一木都承載著我和同學(xué)的同窗情誼。我們一同學(xué)習(xí),在知識(shí)的廣闊天空里翱翔,獲取無盡的經(jīng)驗(yàn)和能力,也為了各自的目標(biāo)奮斗,最終在這里分道揚(yáng)鑣。在大四這一年我經(jīng)歷著成長的巨變,作為一個(gè)即將走入社會(huì)的畢業(yè)生,我開始明確自己的方向,變成一個(gè)需要肩負(fù)起責(zé)任的大人。我的專業(yè)并沒有對(duì)電路設(shè)計(jì)有一個(gè)比較深入的涉及,所以我感覺電路對(duì)我來說真的很陌生,學(xué)習(xí)仿佛無從下手。但我想往這方面發(fā)展,所以在本次的畢業(yè)設(shè)計(jì)中,我選擇了嵌入式的題目,以便對(duì)電子和電路有了更多的了解。我相信不著急慢慢來,打下扎實(shí)沉穩(wěn)的基礎(chǔ),功夫就會(huì)不負(fù)有心人,水滴可以穿石,積少可以成多,我一定可以得到我想要的知識(shí)。在這半年里,我從剛開始的一頭霧水,到后來的一知半解,再到最后的屢次失敗,其實(shí)都是莫大的進(jìn)步。初期,我著手了解軟件的選擇和硬件的基礎(chǔ)知識(shí),然后購買零件動(dòng)手做小車,再編寫軟件進(jìn)行遙控和電機(jī)控制,最后通過調(diào)試,獲得了階段性的勝利。之所以說是階段性,是因?yàn)殡m然小車成功運(yùn)行,但本次還有未解決的問題,而且我覺得以后我還可以學(xué)習(xí)更多高級(jí)技術(shù),來讓小車功能更完善。比如PWM調(diào)速技術(shù),可以通過編程對(duì)電機(jī)進(jìn)行更好的調(diào)速控制;還有PID技術(shù),我覺得只有入門這項(xiàng)高級(jí)控制技術(shù),才算是摸到了自動(dòng)化的門檻。磨刀不誤砍柴功,在這次設(shè)計(jì)里,我覺得最重要的坎坷就是焊接部分,首先我買了一個(gè)不好的焊槍,焊得不是很牢固,導(dǎo)致出現(xiàn)了一兩個(gè)莫名其妙的問題。后來郵寄到學(xué)校,出現(xiàn)了更多莫名其妙的問題,找了很久才發(fā)現(xiàn)焊錫脫落了。于是我重新找焊槍焊了,這些莫名其妙的問題就幾乎都消失了。所以說做一個(gè)實(shí)物,手工活真的是基礎(chǔ)又重要。其實(shí)嵌入式的技術(shù)知識(shí)非常的多而精深?yuàn)W妙,比如FATFS文件系統(tǒng)涉及很多基層文件、CAN控制器的通信實(shí)現(xiàn)、FLASH和SD卡的使用等等,還有很多很多技術(shù)讓我去熟悉和掌握,還有很多很多地方等待著我去跌倒。以后,我會(huì)殫精竭力地在職業(yè)生涯中升級(jí)自己,掌握更多的技能和細(xì)節(jié)經(jīng)驗(yàn),迎接激烈的競(jìng)爭(zhēng),走上更好的人生。參考文獻(xiàn)劉火良.楊森.STM32庫開發(fā)實(shí)戰(zhàn)指南.北京:機(jī)械工業(yè)出版社.2017.沈紅衛(wèi).STM32單片機(jī)應(yīng)用與全案例實(shí)踐.北京:電子工業(yè)出版社.2017.姚文詳(英).ARMCortex-M3權(quán)威指南.北京:北京航空航天大學(xué)出版社.2009.柯博文.Android5.1實(shí)戰(zhàn)指南.北京:清華大學(xué)出版社.2015.ShibuKizhakkeVallathal(?。?嵌入式系統(tǒng)設(shè)計(jì)與開發(fā)實(shí)踐.北京:清華大學(xué)出版社.2017.無線電編輯部.智能小車機(jī)器人制作大全.北京:人民郵電出版社.2017.劉軍張洋左忠航.STM32F7原理與應(yīng)用——寄存器版(下).北京:北京航空航天大學(xué)出版社.2017.周柱.基于STM32的智能小車研究[D].西南交通大學(xué).2011.何立民.單片機(jī)技術(shù)的現(xiàn)狀與未來[J].中國計(jì)算機(jī)報(bào).2012年NO:30.趙振德.多功能遙控智能小車的制作[J].電子制作.2011年4期.李瀚霖等.智能小車研究與設(shè)計(jì)[J].科技致富向?qū)?2011年26期.尹念東.智能車輛的研究及前景[J].上海汽車.2002.2.童詩白華成英.模擬電子技術(shù)基礎(chǔ).北京:高等教育出版社.2006姜寶華齊強(qiáng).基于單片機(jī)的無線遙控智能小車的設(shè)計(jì)與制作[J].計(jì)算機(jī)測(cè)量與控制.2013,(2):24-25.王晶.智能小車運(yùn)動(dòng)控制技術(shù)研究.武漢理工大學(xué).2009致謝經(jīng)過緊張的設(shè)計(jì)和開發(fā),我基本實(shí)現(xiàn)了遙控小車的簡(jiǎn)單功能,前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn),對(duì)這一嵌入式課題加深了很多理解。由于設(shè)計(jì)時(shí)間緊湊,雖然在開發(fā)過程中解決了很多意想不到的困難,但還是有幾個(gè)問題沒有解決,我會(huì)在以后多加學(xué)習(xí),彌補(bǔ)這一遺憾。主要是硬件接線方面,因?yàn)槲液翢o經(jīng)驗(yàn),所以有很多低級(jí)而莫名其妙的奇怪錯(cuò)誤,在此過程和畢業(yè)論文的寫作過程中,我要感謝張秀坤老師的悉心指導(dǎo)和諄諄完善建議。老師對(duì)我的影響很大,她耐心的指導(dǎo)和不斷的鼓勵(lì)促使我增強(qiáng)了堅(jiān)韌不拔的精神意志,才能在這段歷程中堅(jiān)持了下來,并最終完成了畢業(yè)設(shè)計(jì)。所以在此,我對(duì)老師表示衷心的感謝,讓我學(xué)到了終生受益的東西。我就像一匹學(xué)步的小馬,想著有一天可以馳騁在遼闊的大草原。在今后日子中,我將跨過山川河流,經(jīng)過春天的百花,踏著夏天的明月,穿過秋天的清風(fēng),在冬天的雪夜中不斷前行,繼續(xù)學(xué)習(xí)深入實(shí)踐,不斷提升自我,做一個(gè)出色的大人。附錄【app】1.Bluetoothchat.java片段 publicvoidonClick(Viewv){ //TODOAuto-generatedmethodstub switch(v.getId()){ caseR.id.button0: value[0]=0; break; caseR.id.button1: value[0]=1; break; caseR.id.button2: value[0]=3; break; caseR.id.button3: value[0]=5; break; caseR.id.button4: value[0]=7; break; default: break; } } mChatService.write(value); } } privatevoidsetupChat(){ Log.d(TAG,"setupChat()"); //InitializetheBluetoothChatServicetoperformbluetoothconnections mChatService=newBluetoothChatService(this,mHandler); } privatevoidensureDiscoverable(){ if(D) Log.d(TAG,"ensurediscoverable"); if(mBluetoothAdapter.getScanMode()!=BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){ IntentdiscoverableIntent=newIntent( BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra( BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300); startActivity(discoverableIntent); } } //TheHandlerthatgetsinformationbackfromtheBluetoothChatService privatefinalHandlermHandler=newHandler(){ @Override publicvoidhandleMessage(Messagemsg){ switch(msg.what){ caseMESSAGE_STATE_CHANGE: if(D) Log.i(TAG,"MESSAGE_STATE_CHANGE:"+msg.arg1); switch(msg.arg1){ caseBluetoothChatService.STATE_CONNECTED: mTitle.setText(R.string.title_connected_to); mTitle.append(mConnectedDeviceName);// mConversationArrayAdapter.clear(); break; caseBluetoothChatService.STATE_CONNECTING: mTitle.setText(R.string.title_connecting); break; caseBluetoothChatService.STATE_LISTEN: caseBluetoothChatService.STATE_NONE: mTitle.setText(R.string.title_not_connected); break; } break; caseMESSAGE_DEVICE_NAME: //savetheconnecteddevice'sname mConnectedDeviceName=msg.getData().getString(DEVICE_NAME); Toast.makeText(getApplicationContext(), "Connectedto"+mConnectedDeviceName, Toast.LENGTH_SHORT).show(); break; caseMESSAGE_TOAST: Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),Toast.LENGTH_SHORT) .show(); break; } } }; publicvoidonActivityResult(intrequestCode,intresultCode,Intentdata){ if(D) Log.d(TAG,"onActivityResult"+resultCode); switch(requestCode){ caseREQUEST_CONNECT_DEVICE: //WhenDeviceListActivityreturnswithadevicetoconnect if(resultCode==Activity.RESULT_OK){ //GetthedeviceMACaddress Stringaddress=data.getExtras().getString( DeviceListActivity.EXTRA_DEVICE_ADDRESS); //GettheBLuetoothDeviceobject BluetoothDevicedevice=mBluetoothAdapter .getRemoteDevice(address); //Attempttoconnecttothedevice mChatService.connect(device); } break; caseREQUEST_ENABLE_BT: //WhentherequesttoenableBluetoothreturns if(resultCode==Activity.RESULT_OK){ //Bluetoothisnowenabled,sosetupachatsession setupChat(); }else{ //UserdidnotenableBluetoothoranerroroccured Log.d(TAG,"BTnotenabled"); Toast.makeText(this,R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show(); finish(); } } } @Override publicbooleanonCreateOptionsMenu(Menumenu){ MenuInflaterinflater=getMenuInflater(); inflater.inflate(R.menu.option_menu,menu); returntrue; } @Override publicbooleanonOptionsItemSelected(MenuItemitem){ switch(item.getItemId()){ caseR.id.scan: //LaunchtheDeviceListActivitytoseedevicesanddoscan IntentserverIntent=newIntent(this,DeviceListActivity.class); startActivityForResult(serverIntent,REQUEST_CONNECT_DEVICE); returntrue; caseR.id.discoverable: //Ensurethisdeviceisdiscoverablebyothers ensureDiscoverable(); returntrue; } returnfalse; }}bluetoothchatservice.java片段/***Thisthreadrunswhilelisteningforincomingconnections.Itbehaves*likeaserver-sideclient.Itrunsuntilaconnectionisaccepted*(oruntilcancelled).*/privateclassAcceptThreadextendsThread{//ThelocalserversocketprivatefinalBluetoothServerSocketmmServerSocket;publicAcceptThread(){BluetoothServerSockettmp=null;//Createanewlisteningserversockettry{tmp=mAdapter.listenUsingRfcommWithServiceRecord(NAME,MY_UUID);}catch(IOExceptione){Log.e(TAG,"listen()failed",e);}mmServerSocket=tmp;}publicvoidrun(){if(D)Log.d(TAG,"BEGINmAcceptThread"+this);setName("AcceptThread");BluetoothSocketsocket=null;//Listentotheserversocketifwe'renotconnectedwhile(mState!=STATE_CONNECTED){try{//Thisisablockingcallandwillonlyreturnona//successfulconnectionoranexceptionsocket=mmServerSocket.accept();}catch(IOExceptione){Log.e(TAG,"accept()failed",e);break;}//Ifaconnectionwasacceptedif(socket!=null){synchronized(BluetoothChatService.this){switch(mState){caseSTATE_LISTEN:caseSTATE_CONNECTING://Situationnormal.Starttheconnectedthread.connected(socket,socket.getRemoteDevice());break;caseSTATE_NONE:caseSTATE_CONNECTED://Eithernotreadyoralreadyconnected.Terminatenewsocket.try{socket.close();}catch(IOExceptione){Log.e(TAG,"Couldnotcloseunwantedsocket",e);}break;}}}}if(D)Log.i(TAG,"ENDmAcceptThread");}}/***Thisthreadrunsduringaconnectionwitharemotedevice.*Ithandlesallincomingandoutgoingtransmissions.*/privateclassConnectedThreadextendsThread{privatefinalBluetoothSocketmmSocket;privatefinalInputStreammmInStream;privatefinalOutputStreammmOutStream;publicConnectedThread(BluetoothSocketsocket){Log.d(TAG,"createConnectedThread");mmSocket=socket;InputStreamtmpIn=null;OutputStreamtmpOut=null;//GettheBluetoothSocketinputandoutputstreamstry{tmpIn=socket.getInputStream();tmpOut=socket.getOutputStream();}catch(IOExceptione){Log.e(TAG,"tempsocketsnotcreated",e);}mmInStream=tmpIn;mmOutStream=tmpOut;}publicvoidrun(){Log.i(TAG,"BEGINmConnectedThread");byte[]buffer=newbyte[1024];intbytes;//KeeplisteningtotheInputStreamwhileconnectedwhile(true){try{//ReadfromtheInputStreambytes=mmInStream.read(buffer);//SendtheobtainedbytestotheUIActivity}catch(IOExceptione){Log.e(TAG,"disconnected",e);connectionLost();break;}}}/***WritetotheconnectedOutStream.*@parambufferThebytestowrite*/publicvoidwrite(byte[]buffer){try{mmOutStream.write(buffer);//SharethesentmessagebacktotheUIActivity}catch(IOExceptione){Log.e(TAG,"Exceptionduringwrite",e);}}Devicelistactivity.java片段@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);//SetupthewindowrequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);setContentView(R.layout.device_list);//SetresultCANCELEDincasetheuserbacksoutsetResult(Activity.RESULT_CANCELED);//InitializethebuttontoperformdevicediscoveryButtonscanButton=(Button)findViewById(R.id.button_scan);scanButton.setOnClickListener(newOnClickListener(){publicvoidonClick(Viewv){doDiscovery();v.setVisibility(View.GONE);}});//Initializearrayadapters.Oneforalreadypaireddevicesand//onefornewlydiscovereddevicesmPairedDevicesArrayAdapter=newArrayAdapter<String>(this,R.layout.device_name);mNewDevicesArrayAdapter=newArrayAdapter<String>(this,R.layout.device_name);//FindandsetuptheListViewforpaireddevicesListViewpairedListView=(ListView)findViewById(R.id.paired_devices);pairedListView.setAdapter(mPairedDevicesArrayAdapter);pairedListView.setOnItemClickListener(mDeviceClickListener);//FindandsetuptheListViewfornewlydiscovereddevicesListViewnewDevicesListView=(ListView)findViewById(R.id.new_devices);newDevicesListView.setAdapter(mNewDevicesArrayAdapter);newDevicesListView.setOnItemClickListener(mDeviceClickListener);//RegisterforbroadcastswhenadeviceisdiscoveredIntentFilterfilter=newIntentFilter(BluetoothDevice.ACTION_FOUND);this.registerReceiver(mReceiver,filter);//Registerforbroadcastswhendiscoveryhasfinishedfilter=newIntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);this.registerReceiver(mReceiver,filter);//GetthelocalBluetoothadaptermBtAdapter=BluetoothAdapter.getDefaultAdapter();//GetasetofcurrentlypaireddevicesSet<BluetoothDevice>pairedDevices=mBtAdapter.getBondedDevices();//Iftherearepaireddevices,addeachonetotheArrayAdapterif(pairedDevices.size()>0){findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);for(BluetoothDevicedevice:pairedDevices){mPairedDevicesArrayAdapter.add(device.getName()+"\n"+device.getAddress());}}else{StringnoDevices=getResources().getText(R.string.none_paired).toString();mPairedDevicesArrayAdapter.add(noDevices);}}@OverrideprotectedvoidonDestroy(){super.onDestroy();//Makesurewe'renotdoingdiscoveryanymoreif(mBtAdapter!=null){mBtAdapter.cancelDiscovery();}//Unregisterbroadcastlistenersthis.unregisterReceiver(mReceiver);}/***StartdevicediscoverwiththeBluetoothAdapter*/privatevoiddoDiscovery(){if(D)Log.d(TAG,"doDiscovery()");//IndicatescanninginthetitlesetProgressBarIndeterminateVisibility(true);setTitle(R.string.scanning);//Turnonsub-titlefornewdevicesfindView

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論