找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 51864|回復(fù): 8
打印 上一主題 下一主題
收起左側(cè)

基于安卓手機(jī)藍(lán)牙控制的智能小車設(shè)計(jì)論文,帶源程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:310862 發(fā)表于 2018-4-18 14:48 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
一個(gè)基于安卓手機(jī)藍(lán)牙控制的智能小車,帶源程序哦。喜歡的可以下載來看下。

設(shè)計(jì)(論文)題目:
基于安卓手機(jī)藍(lán)牙控制的智能小車設(shè)計(jì)

隨著物聯(lián)網(wǎng)的興起,Android手機(jī)以其獨(dú)有的開放性優(yōu)勢(shì)正在為我們提供更多優(yōu)質(zhì)便捷的技術(shù)成果。本課題研究的是基于安卓手機(jī)藍(lán)牙控制的智能小車設(shè)計(jì),基于手機(jī)平臺(tái),借助于藍(lán)牙技術(shù),設(shè)計(jì)和實(shí)現(xiàn)了一種無線遙控小車新的解決方案。設(shè)計(jì)以手機(jī)控制平臺(tái)、藍(lán)牙通訊模塊、電機(jī)驅(qū)動(dòng)模塊等硬件模塊組成的遙控小車。實(shí)現(xiàn)小車的前進(jìn)、后退、前左轉(zhuǎn)彎、前右轉(zhuǎn)彎、后左轉(zhuǎn)彎、后右轉(zhuǎn)彎等實(shí)時(shí)控制功能。為遙控玩具小車的設(shè)計(jì)提出了一種新的思路,同時(shí)可以為將來智能家居的遙控設(shè)計(jì)提供一定的參考意義。
闡述一種通過手機(jī)藍(lán)牙遙控小車行走的軟、硬件設(shè)計(jì)。手機(jī)藍(lán)牙作為客戶端,小車上的藍(lán)牙模塊HC-06作為服務(wù)端?蛻舳瞬捎肊clipse開發(fā)環(huán)境,JAVA編程,服務(wù)端采用單片機(jī)控制。雙方通過串口進(jìn)行通信,單片機(jī)驅(qū)動(dòng)直流電機(jī)控制小車行動(dòng)。實(shí)驗(yàn)結(jié)果表明,小車可以接收手機(jī)遙控信號(hào)并靈活地進(jìn)行前行、倒退、左轉(zhuǎn)、右轉(zhuǎn)和停止等功能。
本文介紹了基于安卓手機(jī)的藍(lán)牙智能小車控制要實(shí)現(xiàn)的功能,接著闡述該系統(tǒng)電路的設(shè)計(jì)及原理的說明,包括了方案的設(shè)計(jì)、重要元器件的介紹、電路設(shè)計(jì)的說明(包括單片機(jī)控制電路、電機(jī)驅(qū)動(dòng)電路)安卓手機(jī)軟件界面設(shè)計(jì)、軟件設(shè)計(jì)流程以及系統(tǒng)的調(diào)試。最后總結(jié)了基于安卓的藍(lán)牙智能小車控制設(shè)計(jì)完成的任務(wù),分析系統(tǒng)出現(xiàn)的不足。

目  錄

前  言 1
第一章 緒論2
  第一節(jié) 國內(nèi)外研究現(xiàn)狀2
  第二節(jié) 發(fā)展趨勢(shì)分析4
第三節(jié) 本章小結(jié)4
第二章 設(shè)計(jì)方案分析5
  第一節(jié) 設(shè)計(jì)方案分析確定5
第二節(jié) 本章小結(jié)8
第三章   安卓操作系統(tǒng)概述 9
第一節(jié) 安卓操作系統(tǒng)發(fā)展歷史及趨勢(shì)  9
第二節(jié) Android開發(fā)環(huán)境搭建 9
一、 Android的基本介紹 9
二、 Android系統(tǒng)構(gòu)架10
三、 Android開發(fā)包及其工具的安裝和配置11
第三節(jié) 本章小結(jié)13
第四章  系統(tǒng)硬件電路設(shè)計(jì) 14
第一節(jié) 單片機(jī)最小系統(tǒng)14
第二節(jié) 電機(jī)驅(qū)動(dòng)模塊17
第三節(jié) 藍(lán)牙模塊21
第四節(jié) 本章小結(jié)22
第五章  系統(tǒng)軟件程序設(shè)計(jì) 23
  第一節(jié) 主程序設(shè)計(jì)23
第二節(jié) 手機(jī)端程序設(shè)計(jì)25
手機(jī)界面程序設(shè)計(jì)27
手機(jī)監(jiān)聽程序設(shè)計(jì)28
第三節(jié) 本章小結(jié)29
第六章  系統(tǒng)整體的調(diào)試31
  第一節(jié)  調(diào)試的方案31
第二節(jié)  硬件電路調(diào)試31
    一、 獨(dú)立元件的檢測(cè)31
    二、 單片機(jī)最小系統(tǒng)的調(diào)試33
三、 電源電路的測(cè)試34
    四、 驅(qū)動(dòng)電路的調(diào)試34
第三節(jié)  軟件調(diào)試37
  第四節(jié)  系統(tǒng)整體調(diào)試38
第五節(jié)  本章小結(jié)40
結(jié)    論 41
致    謝43
參考文獻(xiàn) 44
附    錄 46
  一、英文原文46
  二、英文翻譯54
三、源程序60

前  言


遙控小車是玩具市場(chǎng)一種很常見的玩具,但是每個(gè)小車都有自己特定的遙控器,原裝遙控器壞了很難與其它型號(hào)的進(jìn)行匹配。現(xiàn)在手機(jī)使用十分普遍,如果利用手機(jī)這個(gè)平臺(tái),通過軟件編程,可以很方便的在一個(gè)硬件平臺(tái)實(shí)現(xiàn)多種小車的遙控器。藍(lán)牙,是一種支持短距離通信的無線電技術(shù)。則可以通過手機(jī)藍(lán)牙來控制我們的玩具小車[1、2]。
隨著家用電器的越來越普及和人們生活節(jié)奏的加快,人們對(duì)電器的依賴性進(jìn)一步提高,對(duì)電器的功能要求也進(jìn)一步增大。現(xiàn)有每個(gè)普通家庭中的遙控器包括空調(diào)遙控器、電視遙控器、DVD遙控器、汽車遙控器、門窗遙控器等,門類繁多且不通用,而另一方面,手機(jī)已成為人人必備的工具,如果可以用我們必備的手機(jī)去遙控所有這些家用電器,可擺脫將來對(duì)專用紅外遙控面板的依賴,一機(jī)在手,萬物盡在掌握之中。因此,本論文先設(shè)計(jì)一種手機(jī)對(duì)智能遙控車的控制方案,利用本系統(tǒng)的控制模塊可擴(kuò)展至對(duì)所有家電的控制[2]。
Andriod是一個(gè)完全開放的標(biāo)準(zhǔn)平臺(tái),在2007年11月5日這天,谷歌公司正式向外界展示了這款名為Android的操作系統(tǒng),并且在這天谷歌宣布建立一個(gè)全球性的聯(lián)盟組織,該組織由34家手機(jī)制造商、軟件開發(fā)商、電信運(yùn)營商以及芯片制造商共同組成。這一聯(lián)盟將支持谷歌發(fā)布的手機(jī)操作系統(tǒng)以及應(yīng)用軟件,將共同開發(fā)Android系統(tǒng)的開放源代碼。本程序是基于Android 2.1系統(tǒng),所用開發(fā)工具為Eclipse集成開發(fā)環(huán)境,Eclipse是著名的跨平臺(tái)的自由集成開發(fā)環(huán)境(IDE)。最初主要用來Java語言開發(fā),但是目前亦有人通過插件使其作為其他計(jì)算機(jī)語言比如C++、Python和Android的開發(fā)工具,在此開發(fā)環(huán)境下開發(fā)軟件非常的方便。

章  緒論

第一節(jié)  國內(nèi)外研究現(xiàn)狀
一、國外研究現(xiàn)狀
1984年,世界上第一幢智能建筑在美國康涅迪格州落成,這棟意義非凡的建筑只是對(duì)一座舊式大樓的一定程度的改造而完成的。它只是采用計(jì)算機(jī)系統(tǒng)對(duì)大樓的空調(diào)、電梯、照明等設(shè)備進(jìn)行監(jiān)控,并提供語音通信、電子郵件、情報(bào)資料等方面的信息服務(wù)。2000年,新加坡有近30個(gè)社區(qū)的約5000戶家庭采用了這種家庭智能化系統(tǒng),而美國的安裝住戶高達(dá)4萬戶。2003年,網(wǎng)絡(luò)化家居的建設(shè)帶來了高達(dá)4500億美元的市場(chǎng)價(jià)值,這其中有3700億美元是智能家電硬件產(chǎn)品的價(jià)值,剩余的部分則是軟件和技術(shù)支持服務(wù)的費(fèi)用,F(xiàn)在,國外的智能家居系統(tǒng)技術(shù)己日趨成熟,預(yù)計(jì)今年,50%以上的新房將具有一定的“智能型家居”功能。于此同時(shí),由于技術(shù)的日益標(biāo)準(zhǔn)化,這些新型智能家居系統(tǒng)將比比爾.蓋茨耗資6000萬美元的高端別墅便宜得多。
在智能家居系統(tǒng)研發(fā)方面,美國及一些歐洲國家一直處于領(lǐng)先地位。近年來,以美國微軟公司及摩托羅拉公司等為首的一批國外知名企業(yè),先后擠身于智能家居的研發(fā)中。例如:微軟公司開發(fā)的“夢(mèng)幻之家”、摩托羅拉公司開發(fā)的“居所之門”、IBM公司開發(fā)的“家庭主任”等均已日趨成穩(wěn)得技術(shù)強(qiáng)占家居市場(chǎng)。此外,日韓新等國的龍頭企業(yè)紛紛致力于家居智能化的開發(fā),對(duì)家居市場(chǎng)更是躍躍欲試。
目前市場(chǎng)上出現(xiàn)得智能家居控制系統(tǒng)主要有:
(1)X-10系統(tǒng)(美國),該系統(tǒng)是利用電力線作為網(wǎng)絡(luò)平臺(tái),采用集中控制方式實(shí)現(xiàn)。這套系統(tǒng)的功能較為強(qiáng)大,與其它家居控制系統(tǒng)如ABB、C_BUS等比起來更容易接收,使用也相對(duì)簡(jiǎn)單。因?yàn)閷?shí)現(xiàn)同樣的功能,X-10家居控制系統(tǒng)是利用220v電力線將發(fā)射器發(fā)出的X-10信號(hào)傳送給接收器從而實(shí)現(xiàn)智能化的控制,因此采用這套系統(tǒng)不需要額外的布線,這也是這套系統(tǒng)的最大的一個(gè)優(yōu)勢(shì),因?yàn)槠渌到y(tǒng)基本上都需要布低壓線,在墻上或地面開槽、鉆孔,施工難度大、費(fèi)用高、工期長。但由于缺乏在國內(nèi)市場(chǎng)推廣的條件且價(jià)格昂貴,該系統(tǒng)在國內(nèi)應(yīng)用極少。
(2)EIB系統(tǒng)(德國),該系統(tǒng)采用預(yù)埋總線及中央控制方式實(shí)現(xiàn)控制功能。但由于其工程要求復(fù)雜嚴(yán)苛,并且價(jià)格較高,因此一直無法打開國內(nèi)市場(chǎng)[3]。
(3)8X系統(tǒng)(新加坡),該系統(tǒng)采用預(yù)處理總線跟集中控制方式來實(shí)現(xiàn)功能。它的優(yōu)點(diǎn)在于利用的產(chǎn)品對(duì)系統(tǒng)進(jìn)行擴(kuò)展,系統(tǒng)較為成熟,比較適合中國國情。但是由于系統(tǒng)架構(gòu)、靈活性及產(chǎn)品價(jià)格等方面還難以達(dá)到要求,所以目前在國內(nèi)還較少應(yīng)用。
二、國內(nèi)研究現(xiàn)狀
20世紀(jì)90年代后期,我國的智能小區(qū)日益興起。眾所周知,我國的智能化住宅建設(shè)最早起于上海、廣州和深圳等沿海城市,并逐漸向內(nèi)陸發(fā)展。在97香港回歸之際,在建設(shè)部“97跨世紀(jì)住宅小區(qū)案競(jìng)賽活動(dòng)”中,上海中皇廣場(chǎng)被建設(shè)部科技委員會(huì)列為全國首家“智能住宅示范工程”,揭開了全國智能小區(qū)發(fā)展的序幕。1999年,建設(shè)部勘察設(shè)計(jì)司、建設(shè)部住宅產(chǎn)業(yè)化辦公室聯(lián)合組織實(shí)施全國住宅小區(qū)智能化技術(shù)示范工程,標(biāo)志著我國住宅小區(qū)智能化進(jìn)入了一個(gè)新階段。隨著信息化走進(jìn)了千家萬戶,由國家經(jīng)貿(mào)委牽頭成立了家庭信息網(wǎng)絡(luò)技術(shù)委員會(huì),而信息網(wǎng)絡(luò)技術(shù)體系研究及產(chǎn)品開發(fā)已經(jīng)被列為了國家技術(shù)創(chuàng)新的重點(diǎn)專項(xiàng)計(jì)劃。據(jù)建設(shè)部要求,截止今年,我國將有70%以上的家庭擁有Internet入網(wǎng)設(shè)備,大中城市中50%的住宅要實(shí)現(xiàn)智能化。
我國的智能家居相對(duì)于國外起步較晚, 尚未形成一定的國家標(biāo)準(zhǔn)。目前,主要采用國外的一些技術(shù)產(chǎn)品,但也有一些企業(yè)推出了自己的產(chǎn)品,主要有:
(1)e家庭(海爾),該系列產(chǎn)品以海爾電腦作為控制中心,各種網(wǎng)絡(luò)家電作為終端設(shè)備,海爾移動(dòng)電話作為移動(dòng)數(shù)字控制中心。海爾在技術(shù)上同微軟合作,利用微軟的Windows Me技術(shù)和海爾的網(wǎng)絡(luò)家電,使“e家庭”已具雛形,已推出了網(wǎng)絡(luò)洗衣機(jī)、網(wǎng)絡(luò)冰箱、網(wǎng)絡(luò)空調(diào)、網(wǎng)絡(luò)微波爐等一系列網(wǎng)絡(luò)家電。
(2)e-home數(shù)字家園(清華同方),該智能家居控制系統(tǒng)是專門針對(duì)中國家庭設(shè)計(jì)的,遵循國際技術(shù)標(biāo)準(zhǔn),采用嵌入式軟、硬件技術(shù),提供網(wǎng)絡(luò)、網(wǎng)絡(luò)節(jié)點(diǎn)及末端設(shè)備。產(chǎn)品以功能模塊開發(fā)為主,基于國外成熟的智能家居標(biāo)準(zhǔn)之上。其智能家居控制系統(tǒng)主要有以下三個(gè)部分:
A系列:遵循EIB協(xié)議的家庭控制產(chǎn)品,適用于中高檔住宅區(qū)。
B系列:遵循X-10協(xié)議的家庭控制產(chǎn)品,適用于中檔住宅區(qū)。
易家三代:配電箱集中安裝式家庭控制產(chǎn)品。
國內(nèi)各大軟、硬件機(jī)構(gòu)正在積極的研制、開發(fā)更為符合市場(chǎng)的智能化家居設(shè)備,以解決當(dāng)前智能化產(chǎn)品實(shí)用性差、使用復(fù)雜及產(chǎn)品價(jià)格昂貴等缺點(diǎn),而技術(shù)創(chuàng)新性也逐步向國際先進(jìn)水平靠攏,這樣的未來值得期待[4]。


  • 發(fā)展趨勢(shì)
智能家居的發(fā)展分為三個(gè)階段:
首先是家庭電子化(Home Electronics)階段,這個(gè)時(shí)期主要是面向單個(gè)的電器,家庭電器之間并沒有形成網(wǎng)絡(luò),亦沒有大的聯(lián)系。
其次是住宅自動(dòng)化(Home Automation)階段,這個(gè)時(shí)期是面向功能的階段,一部分的家庭電器之間形成了簡(jiǎn)單的網(wǎng)絡(luò),主要是為了實(shí)現(xiàn)某個(gè)特定單一的功能,例如單一的自動(dòng)抄表功能。
最后是家居智能化(歐洲稱為Smart Home,美國稱為 Wise House)階段,這個(gè)時(shí)期是面向系統(tǒng)設(shè)計(jì)的階段,系統(tǒng)通過家庭分布總線把住宅內(nèi)各種與信息相關(guān)的通信設(shè)備、家用電器、報(bào)警裝置并到網(wǎng)絡(luò)節(jié)點(diǎn)中進(jìn)行集中的監(jiān)控、管理,保持家電與環(huán)境的協(xié)調(diào),提供生活、工作、學(xué)習(xí)以及娛樂的各種優(yōu)質(zhì)服務(wù),營造一種溫馨舒適的家庭氛圍。
智能家居控制系統(tǒng)提供高效、舒適的家居環(huán)境,確保住戶的生命財(cái)產(chǎn)安全;集中或遠(yuǎn)程調(diào)節(jié)家居環(huán)境的溫度、濕度以及風(fēng)的速度等,同時(shí)檢查空氣成分,提高空氣質(zhì)量;調(diào)節(jié)音響,電視等娛樂設(shè)施,愉悅心情;合理利用太陽能活周遭環(huán)境的變化,盡可能的節(jié)約能耗,達(dá)到合理利用資源;提供現(xiàn)代化的通信、信息服務(wù)。
節(jié)  本章小結(jié)
Internet和移動(dòng)通信的迅速發(fā)展,使人們對(duì)各種數(shù)據(jù)和移動(dòng)服務(wù)的需求快速增長。藍(lán)牙技術(shù)作為一個(gè)全球開放性無線標(biāo)準(zhǔn),通過把各種語言和數(shù)據(jù)設(shè)備用無線鏈路連接起來,使人們能夠隨時(shí)隨地實(shí)現(xiàn)個(gè)人區(qū)域內(nèi)語言和數(shù)據(jù)的交換與傳輸,隨著技術(shù)的發(fā)展和完善,藍(lán)牙必將對(duì)人們的生活和工作產(chǎn)生重大的影響。
章  設(shè)計(jì)方案分析
節(jié)  設(shè)計(jì)方案分析
  • 設(shè)計(jì)要求
本次設(shè)計(jì)要求實(shí)現(xiàn)一個(gè)手機(jī)可以遠(yuǎn)程通過藍(lán)牙控制小車的前進(jìn)、后退、左轉(zhuǎn)和右轉(zhuǎn)。要求學(xué)生對(duì)單片機(jī)和安卓手機(jī)開發(fā)有一定程度的理解,熟悉單片機(jī)定時(shí)器/計(jì)數(shù)器以及中斷的使用,會(huì)基本的C語言和java,熟練掌握keil 51軟件的使用與程序下載以及安卓手機(jī)軟件開發(fā)環(huán)境。

  • 設(shè)計(jì)構(gòu)思
通過查找資料進(jìn)行方案論證和選擇,可以確定出該系統(tǒng)的整體構(gòu)成。本設(shè)計(jì)是以AT89C52單片機(jī)為核心,以設(shè)置手機(jī)界面來設(shè)置前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)、停止等功能。單片機(jī)控制電機(jī)驅(qū)動(dòng)來控制電機(jī)的正反轉(zhuǎn)以實(shí)現(xiàn)小車的前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)、停止。HC-06為藍(lán)牙接收模塊,通過與手機(jī)端的藍(lán)牙進(jìn)行連接配對(duì),從而接收從手機(jī)端發(fā)送過來的動(dòng)作指令。接收到的指令再傳遞給單片機(jī),單片機(jī)通過分析傳遞過來的指令不同,而跳轉(zhuǎn)到不同的子程序來控制電機(jī)驅(qū)動(dòng),從而實(shí)現(xiàn)小車的前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)、停止等不同的動(dòng)作。電源提供給單片機(jī)5V直流電,L298需要從外部接兩個(gè)電壓,一個(gè)是給電機(jī)的,另一個(gè)給L298芯片的[5]。

、系統(tǒng)框圖
通過查找資料進(jìn)行方案論證和選擇,可以確定出該系統(tǒng)的整體構(gòu)成,本系統(tǒng)的系統(tǒng)框圖如圖2.1所示。
圖2.1 系統(tǒng)框圖

單片機(jī)的選擇

單片機(jī)芯片選型時(shí),總的原則是:
(1)芯片含有功能或數(shù)量略大于設(shè)計(jì)需求,設(shè)計(jì)需求盡可能用芯片完成,少用外圍器件。
(2)技術(shù)性:要從單片機(jī)的技術(shù)指標(biāo)角度,對(duì)單片機(jī)芯片進(jìn)行選擇,以保證單片機(jī)應(yīng)用系統(tǒng)在一定的技術(shù)指標(biāo)下可靠運(yùn)行;
(3)實(shí)用性:要從單片機(jī)的供貨渠道、信譽(yù)程序等角度,對(duì)單片機(jī)的生產(chǎn)廠家進(jìn)行選擇以保證單片機(jī)應(yīng)用系統(tǒng)在能長期、可靠運(yùn)行;
(4)可開發(fā)性:選用的單片機(jī)要有可靠的可以開發(fā)手段,如程序開發(fā)工具、仿真調(diào)試手段等。
單片機(jī)僅用于控制電機(jī)驅(qū)動(dòng),用51結(jié)構(gòu)的有Atmel的AT89CXX系列、AT89SXX系列、AT89C20系列(20引腳)或STC的所有單片機(jī)都可以實(shí)現(xiàn)。根據(jù)在學(xué)校比較流行的學(xué)習(xí)單片機(jī)是AT89CXX系列,而且AT89C52單片機(jī)便宜,購買方便,故單片機(jī)選用AT89C52單片機(jī)[6]。

電機(jī)驅(qū)動(dòng)的選擇
底盤和最小系統(tǒng)確定好了后,小車還是跑不起來——缺少電機(jī)驅(qū)動(dòng)。單片機(jī)的I/O是驅(qū)動(dòng)不了電機(jī)的,因此我選用的是L298N電機(jī)專用驅(qū)動(dòng)芯片。L298N通過單片機(jī)的I/O輸入改變芯片控制端的電平,即可以對(duì)電機(jī)進(jìn)行正反轉(zhuǎn),停止的操作,輸入引腳與輸出引腳的邏輯關(guān)系圖如表2.1所示。

表2.1 L298N模塊邏輯關(guān)系圖

EnA

Ln1

Ln2

運(yùn)轉(zhuǎn)狀態(tài)

0

X

X

停止

1

1

0

正傳

1

0

1

反轉(zhuǎn)

1

1

1

立停

1

0

0

停止


L298N電機(jī)驅(qū)動(dòng)模塊性能特點(diǎn):
1、可實(shí)現(xiàn)電機(jī)正反轉(zhuǎn)及調(diào)速。
2、啟動(dòng)性能好,啟動(dòng)轉(zhuǎn)矩大。
3、工作電壓可達(dá)到36V,4A。
4、可同時(shí)驅(qū)動(dòng)兩臺(tái)直流電機(jī)。
5、適合應(yīng)用于機(jī)器人設(shè)計(jì)及智能小車的設(shè)計(jì)[7]。
藍(lán)牙模塊的選擇
本模塊分主機(jī)和從機(jī),主機(jī)能和從機(jī)配對(duì)通信,從機(jī)與從機(jī)之間或主機(jī)與主機(jī)之間不能通信,從機(jī)能和電腦、手機(jī)等的藍(lán)牙配對(duì)通信,購買時(shí)默認(rèn)為從機(jī)。我們?cè)谧鲋悄苄≤嚳刂茣r(shí),藍(lán)牙模塊主要是實(shí)現(xiàn)接收從手機(jī)端發(fā)送過來的指令,所以我們需要的是從機(jī)模塊。藍(lán)牙串口在模塊功能上,偶數(shù)命名的互相兼容,從機(jī)命名的也互相兼容,也就是說,HC-04與HC-06,HC-03與HC-05在功能上是兼容的。HC-04與HC-06是比較早的版本,用戶不可以自己切換主機(jī)或者從機(jī),AT指令集很少,包括修改藍(lán)牙名(限于從機(jī)),修改密碼,修改波特率,詢問版本號(hào)等幾個(gè)基本功能。在本次設(shè)計(jì)中我們只需實(shí)現(xiàn)簡(jiǎn)單的通信,因此選用HC-06模塊。HC-06模塊只記憶最后一次配對(duì)過的從機(jī),并只與該從機(jī)配對(duì),直到KEY(26腳)高電平觸發(fā)時(shí)放棄記憶,26腳默認(rèn)應(yīng)該為低電平。
、電源的選擇
電源給單片機(jī)及電機(jī)驅(qū)動(dòng)等使用5V直流電的器件提供電源,供系統(tǒng)正常工作。
方案一:使用開關(guān)電源將220V交流電轉(zhuǎn)為5V直流電給系統(tǒng)供電。開關(guān)電源的體積小,重量輕。但由于需要耐壓不小于220V的電容等特殊的元器件,日常生活中較難找全器件,開關(guān)電源的散熱比較差,不適宜長時(shí)間工作。故此方案不適宜。
方案二:用變壓器降壓經(jīng)整流橋整流和7805穩(wěn)壓后給系統(tǒng)供電。變壓器相對(duì)比較重,但他的電路穩(wěn)定,適宜長時(shí)間供電。能做到交流電供電正常時(shí)就能給系統(tǒng)正常供電。但在交流電失電時(shí)系統(tǒng)會(huì)停止工作,這時(shí)的時(shí)鐘也會(huì)停止走時(shí)。在重新供電時(shí)系統(tǒng)會(huì)重啟,從而造成原先設(shè)置的數(shù)據(jù)丟失。故此方案存在漏洞,不適宜使用。
方案三:使用交流電和干電池混合給系統(tǒng)供電。在交流電不失效的情況下由交流電轉(zhuǎn)5V直流電供電,在交流電失效情況下由干電池供電。這樣就能解決運(yùn)行成本過高或者在交流電失效時(shí)丟失原先設(shè)置數(shù)據(jù)的問題。
方案四:使用干電池給系統(tǒng)供電。干電池供電能讓系統(tǒng)穩(wěn)定的工作,時(shí)鐘的走時(shí)不受交流電的影響。干電池的價(jià)格相對(duì)交流電而言較貴,用干電池單獨(dú)供電會(huì)造成使用成本提高的問題。但綜合情況考慮到小車要前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)等問題,因此不可能采用交流電源來供電,最終決定兩個(gè)電源都采用干電池供電比較合理,因此采用方案四提供電源。


節(jié)  本章小結(jié)
通過查找相關(guān)資料,首先確定要完成該設(shè)計(jì)需要到的硬件有單片機(jī)最小系統(tǒng)、藍(lán)牙模塊(只需實(shí)現(xiàn)接收數(shù)據(jù),不用發(fā)送數(shù)據(jù)的從機(jī)模塊HC-06)、電機(jī)驅(qū)動(dòng)模塊。通過分析該設(shè)計(jì)需要實(shí)現(xiàn)的功能,而選擇適合的芯片型號(hào)及供電的方式。最后綜合分析后繪制了該系統(tǒng)的硬件接線圖。


章  安卓操作系統(tǒng)概述

第一節(jié)  安卓操作系統(tǒng)的發(fā)展歷史及趨勢(shì)
Android系統(tǒng)一開始并不是由谷歌研發(fā)出來的,Android系統(tǒng)原來的公司名字就叫做Android,谷歌公司在2005收購了這個(gè)僅成立22月的高科技企業(yè)。Android系統(tǒng)也開始由谷歌接手研發(fā),Android系統(tǒng)的負(fù)責(zé)人以及Android公司的CEO安迪·魯賓成為谷歌公司的工程部副總裁,繼續(xù)負(fù)責(zé)Android項(xiàng)目的研發(fā)工作。在2007年11月5日這天,谷歌公司正式向外界展示了這款名為Android的操作系統(tǒng),并且在這天谷歌宣布建立一個(gè)全球性的聯(lián)盟組織,該組織由34家手機(jī)制造商、軟件開發(fā)商、電信運(yùn)營商以及芯片制造商共同組成。這一聯(lián)盟將支持谷歌發(fā)布的手機(jī)操作系統(tǒng)以及應(yīng)用軟件,將共同開發(fā)Android系統(tǒng)的開放源代碼[8]。

第二節(jié)Android開發(fā)環(huán)境搭建

  • Android的基本介紹
Android是一種基于Linux的自由及開放源代碼的操作系統(tǒng),主要使用于移動(dòng)設(shè)備,如智能手機(jī)平板電腦,由Google公司和開放手機(jī)聯(lián)盟領(lǐng)導(dǎo)及開發(fā)。尚未有統(tǒng)一中文名稱,中國大陸地區(qū)較多人使用“安卓”或“安致”。Android操作系統(tǒng)最初由Andy Rubin開發(fā),主要支持手機(jī)。2005年8月由Google收購注資。2007年11月,Google與84家硬件制造商、軟件開發(fā)商及電信營運(yùn)商組建開放手機(jī)聯(lián)盟共同研發(fā)改良Android系統(tǒng)。隨后Google以Apache開源許可證的授權(quán)方式,發(fā)布了Android的源代碼。第一部Android智能手機(jī)發(fā)布于2008年10月。Android逐漸擴(kuò)展到平板電腦及其他領(lǐng)域上,如電視、數(shù)碼相機(jī)游戲機(jī)等。2011年第一季度,Android在全球的市場(chǎng)份額首次超過塞班系統(tǒng),躍居全球第一。 2012年11月數(shù)據(jù)顯示,Android占據(jù)全球智能手機(jī)操作系統(tǒng)市場(chǎng)76%的份額,中國市場(chǎng)占有率為90%。其具有以下特點(diǎn):
①開放性:在優(yōu)勢(shì)方面,Android平臺(tái)首先就是其開發(fā)性,開發(fā)的平臺(tái)允許任何移動(dòng)終端廠商加入到Android聯(lián)盟中來。顯著的開放性可以使其擁有更多的開發(fā)者,隨著用戶和應(yīng)用的日益豐富,一個(gè)嶄新的平臺(tái)也將很快走向成熟。開發(fā)性對(duì)于Android的發(fā)展而言,有利于積累人氣,這里的人氣包括消費(fèi)者和廠商,而對(duì)于消費(fèi)者來講,最大的受益正是豐富的軟件資源。開放的平臺(tái)也會(huì)帶來更大競(jìng)爭(zhēng),如此一來,消費(fèi)者將可以用更低的價(jià)位購得心儀的手機(jī)。
②不受束縛:在過去很長的一段時(shí)間,特別是在歐美地區(qū),手機(jī)應(yīng)用往往受到運(yùn)營商制約,使用什么功能接入什么網(wǎng)絡(luò),幾乎都受到運(yùn)營商的控制。自從2007年iPhone上市后,用戶可以更加方便地連接網(wǎng)絡(luò),運(yùn)營商的制約減少。隨著EDGE、HSDPA這些2G至3G移動(dòng)網(wǎng)絡(luò)的逐步過渡和提升,手機(jī)隨意接入網(wǎng)絡(luò)已不是運(yùn)營商口中的笑談。
③豐富的硬件這一點(diǎn)還是與Android平臺(tái)的開放性相關(guān),由于Android的開放性,眾多的廠商會(huì)推出千奇百怪,功能特色各具的多種產(chǎn)品。功能上的差異和特色,卻不會(huì)影響到數(shù)據(jù)同步、甚至軟件的兼容,如同從諾基亞Symbian風(fēng)格手機(jī)一下改用蘋果iPhone,同時(shí)還可將Symbian中優(yōu)秀的軟件帶到iPhone上使用、聯(lián)系人等資料更是可以方便地轉(zhuǎn)移。
④方便開發(fā):Android平臺(tái)提供給第三方開發(fā)商一個(gè)十分寬泛、自由的環(huán)境,不會(huì)受到各種條條框框的阻擾,可想而知,會(huì)有多少新穎別致的軟件會(huì)誕生。
⑤Google應(yīng)用:在互聯(lián)網(wǎng)的Google已經(jīng)走過10年度歷史,從搜索巨人到全面的互聯(lián)網(wǎng)滲透,Google服務(wù)如地圖、郵件、搜索等已經(jīng)成為連接用戶和互聯(lián)網(wǎng)的重要紐帶,而Android平臺(tái)手機(jī)將無縫結(jié)合這些優(yōu)秀的Google服務(wù)。

二、Android系統(tǒng)構(gòu)架
Android的系統(tǒng)架構(gòu)和其操作系統(tǒng)一樣,采用了分層的架構(gòu)。從架構(gòu)圖3.1看,Androi d分為四個(gè)層,從高層到低層分別是應(yīng)用程序?qū)、?yīng)用程序框架層、系統(tǒng)運(yùn)行庫層和Linux內(nèi)核層[9]。
圖3.1 Android結(jié)構(gòu)圖

1、應(yīng)用程序
Android會(huì)同一系列核心應(yīng)用程序包一起發(fā)布,該應(yīng)用程序包包括客戶端,SMS短消息程序,日歷,地圖,瀏覽器,聯(lián)系人管理程序等。所有的應(yīng)用程序都是使用JAVA語言編寫的。
2、應(yīng)用程序框架
開發(fā)人員也可以完全訪問核心應(yīng)用程序所使用的API框架。該應(yīng)用程序的架構(gòu)設(shè)計(jì)簡(jiǎn)化了組件的重用,任何一個(gè)應(yīng)用程序都可以發(fā)布它的功能塊并且任何其它的應(yīng)用程序都可以使用其所發(fā)布的功能塊(不過得遵循框架的安全性)。同樣,該應(yīng)用程序重用機(jī)制也使用戶可以方便的替換程序組件。
3系統(tǒng)運(yùn)行庫
Android 包含一些C/C++庫,這些庫能被Android系統(tǒng)中不同的組件使用。它們通過 Android 應(yīng)用程序框架為開發(fā)者提供服務(wù)。
4系統(tǒng)內(nèi)核
Android 是運(yùn)行于Linux kernel之上,但并不是GNU/Linux。因?yàn)樵谝话鉍NU/Linux 里支持的功能,Android 大都沒有支持,包括Cairo、X11、Alsa、FFmpeg、GTK、Pango及Glibc等都被移除掉了。Android又以Bionic 取代Glibc、以Skia 取代Cairo、再以opencore取代FFmpeg等等。
、Android開發(fā)包及其工具的安裝和配置
Android的開發(fā)是可以在windows XP及其以版本、MACOS、Linux等系統(tǒng)上進(jìn)行開發(fā)的;首先呢,我們要進(jìn)入Google的官方網(wǎng)站下載windows XP版本的java開發(fā)包JDK,我們選擇的版本是JDK1.6.0以上的版本。在應(yīng)用開發(fā)平臺(tái)方面,我們采用的是eclipse,因?yàn)間oogle提供了基于eclipse的android開發(fā)插件ADT,在隨時(shí)更新的插件幫助下,可以很快幫助我們完成android手機(jī)終端的相關(guān)應(yīng)用開發(fā)。
1、安裝JDK和配置java開發(fā)環(huán)境
首先,安裝JDK時(shí),安裝包中有JDK和JRE兩部分,點(diǎn)擊安裝程序,指定安裝目錄,然后點(diǎn)擊下一步,等待安裝完成即可。安裝完成之后,點(diǎn)擊“我的電腦”,選擇“屬性”里面的“高級(jí)”選項(xiàng),選擇環(huán)境變量,找到path變量,如果沒有,就自己添加一個(gè),按后命名path就行,完成之后,點(diǎn)擊編輯,添加JDK安裝目錄的“l(fā)ib”文件路徑;之后點(diǎn)擊確定,然后再找到CLASSPATH變量,在路徑輸入“.”,然后點(diǎn)擊確定。
2、檢測(cè)安裝
安裝配置完成之后,需要測(cè)試是否安裝成功。點(diǎn)擊開始——運(yùn)行輸入“cmd”,打開命令模式。輸入“java—version”,檢測(cè)JDK安裝是否成功,如果現(xiàn)實(shí)結(jié)果,則安裝成功。
3安裝eclipse
打開安裝包,點(diǎn)擊安裝,彈出workspace對(duì)話框,確定創(chuàng)建項(xiàng)目的保存路徑。
4、SDK和ADT的安裝和配置
首先,解壓安裝包,運(yùn)行“SDK Setup.exe”。其次,在“Android SDK and Avd manager”的窗口左側(cè)選擇“setting”,選中“Force https://......”然后返回“Installed packges”,點(diǎn)擊“Update all”。點(diǎn)擊“Available Packges”,選擇要安裝的API版本以及USB驅(qū)動(dòng)和SDK文檔,我們都選擇了。
這個(gè)過程很漫長,一定要保證網(wǎng)速快的情況下來安裝,要不會(huì)出現(xiàn)安裝不了的情況,最少安裝這個(gè)也要一天的時(shí)間,所以要耐心等待。下載完成之后,選擇所有選項(xiàng),然后全部安裝,安裝完成之后,配置SDK,SDK的配置更JDK是一樣的。
5ADT的安裝和配置
啟動(dòng)eclipse,點(diǎn)擊“Help”菜單,選擇“Install New Software”之后,點(diǎn)擊“Add”按鈕,點(diǎn)擊Archive指向下載的ADT壓縮包,然后點(diǎn)擊“ok”,選中所需要安裝的插件即可。
6、Android虛擬機(jī)的搭建
打開菜單“windows”,一次選擇“Android SDK and AVD Manager”,打開界面;然后點(diǎn)擊NEW新建模擬機(jī),彈出選項(xiàng)卡,根據(jù)選項(xiàng)卡填寫自己所需要的內(nèi)容,即可創(chuàng)建。
7、建立好項(xiàng)目名后,即可啟動(dòng)虛擬機(jī)。


節(jié)  本章小結(jié)

本章主要介紹了安卓系統(tǒng)的概述和安卓開發(fā)環(huán)境的一個(gè)搭建過程。Androi d分為四個(gè)層,從高層到低層分別是應(yīng)用程序?qū)、?yīng)用程序框架層、系統(tǒng)運(yùn)行庫層和Linux內(nèi)核層。Android系統(tǒng)的主要優(yōu)點(diǎn)有:開放性、不受束縛、豐富的硬件、方便開發(fā)、Google應(yīng)用。在搭建安卓開發(fā)環(huán)境的時(shí)候,耗時(shí)相對(duì)比較漫長[10、11]。

  • 系統(tǒng)硬件電路設(shè)計(jì)

整個(gè)系統(tǒng)的硬件設(shè)計(jì)可以分為四個(gè)模塊:電源電路、單片機(jī)最小系統(tǒng)、電機(jī)驅(qū)動(dòng)模塊、藍(lán)牙模塊、。電源電路為整個(gè)系統(tǒng)供電,包括單片機(jī)AT89C52、電機(jī)驅(qū)動(dòng)、藍(lán)牙模塊、及其他外圍電路。電源電路分兩個(gè)部分:(1)接外部電源給電機(jī)供電;(2)由4節(jié)干電池作為電源,給系統(tǒng)供電,以確保單片機(jī)、電機(jī)驅(qū)動(dòng)、藍(lán)牙模塊的正常運(yùn)行。在電源電路給系統(tǒng)供電時(shí),綠色指示燈點(diǎn)亮,只是當(dāng)前供電正常。單片機(jī)最小系統(tǒng)部分是整個(gè)系統(tǒng)的智能控制部分,也是整個(gè)系統(tǒng)的核心部分。電機(jī)驅(qū)動(dòng)模塊L298需要從外部接兩個(gè)電壓,一個(gè)是給電機(jī)的,另一個(gè)給L298芯片的[12]。
節(jié)  單片機(jī)最小系統(tǒng)

單片機(jī)的最小系統(tǒng)就是讓單片機(jī)能正常工作并發(fā)揮其功能時(shí)所必須的組成部分,也可理解為是用最少的元件組成的單片機(jī)可以工作的系統(tǒng)。對(duì)51 系列單片機(jī)來說, 最小系統(tǒng)一般應(yīng)該包括: 單片機(jī)、時(shí)鐘電路、復(fù)位電路、輸入/ 輸出設(shè)備等[13、14]。

圖4.1 單片機(jī)最小系統(tǒng)框圖

圖4.2 單片機(jī)最小系統(tǒng)原理圖

、單片機(jī)AT89C52
AT89S52單片機(jī)片內(nèi)集成256字節(jié)程序運(yùn)行空間、8K字節(jié)Flash存儲(chǔ)空間,支持最大64K外部存儲(chǔ)擴(kuò)展。根據(jù)不同的運(yùn)行速度和功耗的要求,時(shí)鐘頻率可以設(shè)置在0~33M之間。片內(nèi)資源有4組I/O控制端口、3個(gè)定時(shí)器、8個(gè)中斷、軟件設(shè)置低能耗模式、看門狗和斷電保護(hù)?梢栽4V到5.5V寬電壓范圍內(nèi)正常工作。不斷發(fā)展的半導(dǎo)體工藝也讓該單片機(jī)的功耗不斷降低。同時(shí),該單片機(jī)支持計(jì)算機(jī)并口下載,簡(jiǎn)單的數(shù)字芯片就可以制成下載線。根據(jù)不同場(chǎng)合的要求,這款單片機(jī)提供了多種封裝,本次設(shè)計(jì)根據(jù)最小系統(tǒng)有時(shí)需要更換單片機(jī)的具體情況,使用雙列直插DIP-40的封裝。下面對(duì)定時(shí)開關(guān)系統(tǒng)中使用到的管腳進(jìn)行簡(jiǎn)單說明.
P0口:P0口是一個(gè)8位漏極開路的雙向I/O口。作為輸出口,每位能驅(qū)動(dòng)8個(gè)TTL邏輯電平。對(duì)P0端口寫“1”時(shí),引腳用作高阻抗輸入。當(dāng)訪問外部程序和數(shù)據(jù)存儲(chǔ)器時(shí),P0口也被作為低8位地址/數(shù)據(jù)復(fù)用。在這種模式下,P0不具有內(nèi)部上拉電阻。
P1口:P1口是一個(gè)具有內(nèi)部上拉電阻的8位雙向I/O口,P1輸出緩沖器能驅(qū)動(dòng)4個(gè)TTL邏輯電平。對(duì)P1 端口寫“1”時(shí),內(nèi)部上拉電阻把端口拉高,此時(shí)可以作為輸入口使用。作為輸入使用時(shí),被外部拉低的引腳由于內(nèi)部電阻的原因,將輸出電流(IIL)。
P2口:P2口是一個(gè)具有內(nèi)部上拉電阻的8位雙向I/O口,P2輸出緩沖器能驅(qū)動(dòng)4個(gè)TTL 邏輯電平。對(duì)P2 端口寫“1”時(shí),內(nèi)部上拉電阻把端口拉高,此時(shí)可以作為輸入口使用。作為輸入使用時(shí),被外部拉低的引腳由于內(nèi)部電阻的原因,將輸出電流(IIL)。
P3 口:P3口是一個(gè)具有內(nèi)部上拉電阻的8位雙向I/O口,P3輸出緩沖器能驅(qū)動(dòng)4個(gè)TTL邏輯電平。對(duì)P3端口寫“1”時(shí),內(nèi)部上拉電阻把端口拉高,此時(shí)可以作為輸入口使用。作為輸入使用時(shí),被外部拉低的引腳由于內(nèi)部電阻的原因,將輸出電流(IIL)。
RST——復(fù)位輸入。當(dāng)振蕩器工作時(shí),RST引腳出現(xiàn)兩個(gè)機(jī)器周期以上高電平將是單片機(jī)復(fù)位。
. 時(shí)鐘電路
在設(shè)計(jì)時(shí)鐘電路之前,讓我們先了解下51 單片機(jī)上的時(shí)鐘管腳:
XTAL1(19 腳) :芯片內(nèi)部振蕩電路輸入端。
XTAL2(18 腳) :芯片內(nèi)部振蕩電路輸出端。
XTAL1 和XTAL2 是獨(dú)立的輸入和輸出反相放大器,它們可以被配置為使用石英晶振的片內(nèi)振蕩器,或者是器件直接由外部時(shí)鐘驅(qū)動(dòng)。在XTAL1、XTAL2 的引腳上外接定時(shí)元件(一個(gè)石英晶體和兩個(gè)電容),內(nèi)部振蕩器便能產(chǎn)生自激振蕩。一般來說晶振可以在1.2 ~ 12MHz之間任選,甚至可以達(dá)到24MHz 或者更高,但是頻率越高功耗也就越大。在本實(shí)驗(yàn)套件中采用的11.0592M 的石英晶振。和晶振并聯(lián)的兩個(gè)電容的大小對(duì)振蕩頻率有微小影響,可以起到頻率微調(diào)作用。當(dāng)采用石英晶振時(shí),電容可以在20 ~ 40pF 之間選擇(本實(shí)驗(yàn)套件使用30pF);當(dāng)采用陶瓷諧振器件時(shí),電容要適當(dāng)?shù)卦龃笠恍,?0 ~ 50pF 之間。通常選取33pF 的陶瓷電容就可以了。

. 復(fù)位電路
在單片機(jī)系統(tǒng)中,復(fù)位電路是非常關(guān)鍵的,當(dāng)程序跑飛(運(yùn)行不正常)或死機(jī)(停止運(yùn)行)時(shí),就需要進(jìn)行復(fù)位。
MCS-5l 系列單片機(jī)的復(fù)位引腳RST( 第9 管腳) 出現(xiàn)2個(gè)機(jī)器周期以上的高電平時(shí),單片機(jī)就執(zhí)行復(fù)位操作。如果RST 持續(xù)為高電平,單片機(jī)就處于循環(huán)復(fù)位狀態(tài)。
復(fù)位操作通常有兩種基本形式:上電自動(dòng)復(fù)位和開關(guān)復(fù)位。上電瞬間,電容兩端電壓不能突變,此時(shí)電容的負(fù)極和RESET 相連,電壓全部加在了電阻上,RESET 的輸入為高,芯片被復(fù)位。隨之+5V電源給電容充電,電阻上的電壓逐漸減小,最后約等于0,芯片正常工作。并聯(lián)在電容的兩端為復(fù)位按鍵,當(dāng)復(fù)位按鍵沒有被按下的時(shí)候電路實(shí)現(xiàn)上電復(fù)位,在芯片正常工作后,通過按下按鍵使RST管腳出現(xiàn)高電平達(dá)到手動(dòng)復(fù)位的效果。一般來說,只要RST 管腳上保持10ms 以上的高電平,就能使單片機(jī)有效的復(fù)位。圖中所示的復(fù)位電阻和電容為經(jīng)典值,實(shí)際制作是可以用同一數(shù)量級(jí)的電阻和電容代替,讀者也可自行計(jì)算RC 充電時(shí)間或在工作環(huán)境實(shí)際測(cè)量,以確保單片機(jī)的復(fù)位電路可靠。
. EA/VPP(31 腳) 的功能和接法
51 單片機(jī)的EA/VPP(31 腳) 是內(nèi)部和外部程序存儲(chǔ)器的選擇管腳。當(dāng)EA 保持高電平時(shí),單片機(jī)訪問內(nèi)部程序存儲(chǔ)器;當(dāng)EA 保持低電平時(shí),則不管是否有內(nèi)部程序存儲(chǔ)器,只訪問外部存儲(chǔ)器。對(duì)于現(xiàn)今的絕大部分單片機(jī)來說,其內(nèi)部的程序存儲(chǔ)器(一般為flash)容量都很大,因此基本上不需要外接程序存儲(chǔ)器,而是直接使用內(nèi)部的存儲(chǔ)器。在本實(shí)驗(yàn)套件中,EA 管腳接到了VCC 上,只使用內(nèi)部的程序存儲(chǔ)器。這一點(diǎn)一定要注意,很多初學(xué)者常常將EA 管腳懸空,從而導(dǎo)致程序執(zhí)行不正常[15]。


  • 電機(jī)驅(qū)動(dòng)模塊
  • L298N型驅(qū)動(dòng)器的原理及應(yīng)用
L298是SGS公司的產(chǎn)品,比較常見的是15腳Multiwatt封裝的L298N,內(nèi)部同樣包含4通道邏輯驅(qū)動(dòng)電路。可以方便的驅(qū)動(dòng)兩個(gè)直流電機(jī),或一個(gè)兩相步進(jìn)電機(jī)。L298N芯片可以驅(qū)動(dòng)兩個(gè)二相電機(jī),也可以驅(qū)動(dòng)一個(gè)四相電機(jī),輸出電壓最高可達(dá)50V,可以直接通過電源來調(diào)節(jié)輸出電壓;可以直接用單片機(jī)的IO口提供信號(hào);而且電路簡(jiǎn)單,使用比較方便。L298N可接受標(biāo)準(zhǔn)TTL邏輯電平信號(hào)VSS,VSS可接4.5~7 V電壓。4腳VS接電源電壓,VS電壓范圍VIH為+2.5~46 V。輸出電流可達(dá)2.5 A,可驅(qū)動(dòng)電感性負(fù)載。1腳和15腳下管的發(fā)射極分別單獨(dú)引出以便接入電流采樣電阻,形成電流傳感信號(hào)。L298可驅(qū)動(dòng)2個(gè)電動(dòng)機(jī),OUT1,OUT2和OUT3,OUT4之間可分別接電動(dòng)機(jī),本實(shí)驗(yàn)裝置我們選用驅(qū)動(dòng)一臺(tái)電動(dòng)機(jī)。5,7,10,12腳接輸入控制電平,控制電機(jī)的正反轉(zhuǎn)。EnA,EnB接控制使能端,控制電機(jī)的停轉(zhuǎn)。其引腳圖如圖4.3所示。

圖4.3 L298N引腳圖
1、引腳說明
1、1和15和8引腳直接接。,
2、4管腳VS接2.5到46的電壓,它是用來驅(qū)動(dòng)電機(jī)的。
3、9引腳是用來接4.5到7V的電壓的,它是用來驅(qū)動(dòng)L298芯片的,L298需要從外部接兩個(gè)電壓,一個(gè)是給電機(jī)的,另一個(gè)給L298芯片的。
4、6和11引腳是它的使能端,一個(gè)使能端控制一個(gè)電機(jī),至于那個(gè)控制那個(gè)你自己焊接,你可以把它理解為總開關(guān),只有當(dāng)它們都是高電平的時(shí)候兩個(gè)電機(jī)才有可能工作。
5、5,7,10,12是298的信號(hào)輸入端和單片機(jī)的IO口相連,2,3,13,14是輸出端,輸入5和7控制輸出2和3,  輸入的10,12控制輸出的13,14。
2、驅(qū)動(dòng)原理圖

L298N是SGS公司的產(chǎn)品,內(nèi)部包含4個(gè)通道邏輯驅(qū)動(dòng)電路,是一種二相和四相電機(jī)的專用驅(qū)動(dòng)器,即內(nèi)含二個(gè)H橋的高電壓大電流雙全橋式驅(qū)動(dòng)器,接收標(biāo)準(zhǔn)TTL邏輯電平信號(hào),可以驅(qū)動(dòng)4V、2V以下的電機(jī)。

圖4.4 L298驅(qū)動(dòng)原理圖

OUT1、OUT2和OUT3、OUT4之間分別接兩個(gè)電機(jī)。IN1、IN2、IN3、IN4引腳從單片機(jī)輸入控制電平,控制電機(jī)的正反轉(zhuǎn),ENA、ENB接控制使能端,控制電機(jī)的停轉(zhuǎn)。L298N的邏輯功能如表4.1所示。

表4.1 L298邏輯功能表

IN1

IN2

IN3

IN4

左電機(jī)

右電機(jī)

電動(dòng)車運(yùn)動(dòng)狀態(tài)

1

0

1

0

正轉(zhuǎn)

正轉(zhuǎn)

前行

1

0

0

1

正轉(zhuǎn)

反轉(zhuǎn)

左轉(zhuǎn)

1

0

1

1

正轉(zhuǎn)

以電機(jī)為中心左轉(zhuǎn)

0

1

1

0

反轉(zhuǎn)

正轉(zhuǎn)

右轉(zhuǎn)

1

1

1

0

正轉(zhuǎn)

以電機(jī)為中心右轉(zhuǎn)

0

1

0

1

反轉(zhuǎn)

反轉(zhuǎn)

后退


3、直流電機(jī)實(shí)物接線圖

圖4.5 直流電機(jī)實(shí)物接線圖

4、直流電機(jī)原理圖

圖4.6 L298驅(qū)動(dòng)直流電機(jī)原理圖

  • 藍(lán)牙模塊
一、藍(lán)牙模塊HC-06介紹
1、 采用CSR主流藍(lán)牙芯片,藍(lán)牙V2.0協(xié)議標(biāo)準(zhǔn)
2、 核心串口模塊工作電壓3.3V。帶底板的可以為3.1-6.5V之間
3、 波特率為1200,2400,4800,9600, 19200,38400,57600,115200用戶可設(shè)置
4、 核心模塊尺寸大小為:28mm x 15 mm x 2.35mm。底板尺寸27mm*47mm
5、 工作電流:配對(duì)中為50MA,配對(duì)完畢通信中為28MA
6、 休眠電流:不休眠
7、 用于GPS導(dǎo)航系統(tǒng),水電煤氣抄表系統(tǒng),工業(yè)現(xiàn)場(chǎng)采控系統(tǒng)。
8、 可以與藍(lán)牙筆記本電腦、電腦加藍(lán)牙適配器、PDA等設(shè)備進(jìn)行無縫連接
9、 出廠默認(rèn)參數(shù):從機(jī),波特率:9600,N,8,1。配對(duì)密碼:1234
二、AT命令集如下
1、測(cè)試通訊
發(fā)送:AT(返回OK,一秒左右發(fā)一次) 返回:OK
2、改藍(lán)牙串口通訊波特率
發(fā)送:AT+BAUD1   返回:OK1200   發(fā)送:AT+BAUD2  返回:OK2400
1---------1200
2---------2400
3---------4800
4---------9600
5---------19200
6---------38400
7---------57600
8---------115200
9---------230400
A---------460800
B---------921600
C---------1382400
不建議用在超過115200的波特率,信號(hào)的干擾會(huì)使系統(tǒng)不穩(wěn)定。
設(shè)置超過115200后用電腦無法使用,要用單片機(jī)編程于高于115200才能使用此波特率和重新發(fā)AT命令設(shè)低波特率
用AT命令設(shè)好波特率后,下次上電使用不需再設(shè),可以掉電保存波特率。
3、改藍(lán)牙名稱
發(fā)送:AT+NAMEname
返回:OKname
參數(shù)name:所要設(shè)置的當(dāng)前名稱,即藍(lán)牙被搜索到的名稱。20個(gè)字符以內(nèi)。例:發(fā)送AT+NAMEbill_gates
返回OKname
這時(shí)藍(lán)牙名稱改為bill_gates,參數(shù)可以掉電保存,只需修改一次。PDA端刷新服務(wù)可以看到更改后的藍(lán)牙名稱。
4、改藍(lán)牙配對(duì)密碼
發(fā)送:AT+PINxxxx
返回:OKsetpin
參數(shù)xxxx:所要設(shè)置的配對(duì)密碼,4個(gè)字節(jié),此命令可用于從機(jī)或主機(jī)。從機(jī)則是適配器或手機(jī)彈出要求輸入配對(duì)密碼窗口時(shí),則手工輸入此參數(shù)就可以連接從機(jī)。主機(jī)則是在用主藍(lán)牙模塊連數(shù)碼相機(jī)時(shí),數(shù)碼相機(jī)是從機(jī),找到相機(jī)的配對(duì)密碼,再設(shè)入主藍(lán)牙模塊,則主藍(lán)牙模塊就可以自動(dòng)連接相機(jī)。
例:發(fā)送AT+PIN8888
返回OKsetpin
這時(shí)藍(lán)牙配對(duì)密碼改為8888,模塊在出廠時(shí)的默認(rèn)配對(duì)密碼是1234。參數(shù)可以掉電保存,只需修改一次。
第四節(jié) 本章小結(jié)
本章的任務(wù)主要介紹了各個(gè)模塊的核心芯片,并完成了電路設(shè)計(jì)工作,本設(shè)計(jì)由51單片機(jī)最小系統(tǒng)、HC-06藍(lán)牙模塊、L298電機(jī)驅(qū)動(dòng)模塊、電源電路、小車底板等組成。然后確定設(shè)計(jì)硬件模塊之間的電路連接圖,為實(shí)物硬件制作做足準(zhǔn)備。

章  系統(tǒng)軟件程序設(shè)計(jì)


這次設(shè)計(jì)可以用C語言編程序,也可以用匯編語言編程序,由于本次設(shè)計(jì)中程序系統(tǒng)用C語言編寫程序。此次設(shè)計(jì)所選用的單片機(jī)是AT89C52單片機(jī),其C語言語法和結(jié)構(gòu)和標(biāo)準(zhǔn)C語言基本相同,只是有了相應(yīng)的擴(kuò)充,用到的編譯軟件是Keil C。下面結(jié)合我的程序編譯簡(jiǎn)要介紹以下Keil C的編譯環(huán)境的特點(diǎn)。
Keil C51軟件提供豐富的庫函數(shù)和功能強(qiáng)大的集成開發(fā)調(diào)試工具,全Windows界面。另外重要的一點(diǎn),只要看一下編譯后生成的匯編代碼,就能體會(huì)到Keil C51生成的目標(biāo)代碼效率非常之高,多數(shù)語句生成的匯編代碼很緊湊,容易理解。在開發(fā)大型軟件時(shí)更能體現(xiàn)高級(jí)語言的優(yōu)勢(shì)。Keil C51在使用前一定要先進(jìn)行注冊(cè),否則程序過大會(huì)造成編譯時(shí)出現(xiàn)地址使用錯(cuò)誤。程序在編譯時(shí)就遇到過這種問題。在單個(gè)程序運(yùn)行時(shí)沒有錯(cuò)誤,但是一整合編譯后出現(xiàn)地址沖突現(xiàn)象。這個(gè)問題困擾了很長一段時(shí)間,通過查資料發(fā)現(xiàn)若是Keil C51軟件沒有注冊(cè)的話使用時(shí)當(dāng)程序過大就會(huì)出現(xiàn)地址沖突現(xiàn)象。在注冊(cè)完成后,程序編譯能順利通過[15]。

節(jié)  主程序的設(shè)計(jì)

在本次設(shè)計(jì)中,主程序主要是在單片機(jī)的控制下,對(duì)藍(lán)牙模塊輸入的信息進(jìn)行存儲(chǔ)分析,來控制電機(jī)驅(qū)動(dòng),以達(dá)到控制小車的前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)。在這個(gè)過程中,單片機(jī)首先進(jìn)行初始化,包括設(shè)置單片機(jī)各個(gè)端口的方向,各個(gè)變量的初始化,以及單片機(jī)振蕩頻率的校準(zhǔn)等。單片機(jī)定時(shí)對(duì)藍(lán)牙模塊串口讀數(shù)據(jù),如果串口的數(shù)據(jù)讀出,則對(duì)讀出的數(shù)據(jù)進(jìn)行分析,讀出的數(shù)據(jù)如果為A、B、C、D則分別對(duì)應(yīng)小車的前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)。小車硬件系統(tǒng)軟件設(shè)計(jì)的流程圖如圖5.1所示。





圖5.1 小車動(dòng)作流程圖

  • 手機(jī)程序的設(shè)計(jì)
本程序是基于Android 2.1系統(tǒng),所用開發(fā)工具為Eclipse集成開發(fā)環(huán)境,Eclipse是著名的跨平臺(tái)的自由集成開發(fā)環(huán)境(IDE)。最初主要用來Java語言開發(fā),但是目前亦有人通過插件使其作為其他計(jì)算機(jī)語言比如C++、Python和Android的開發(fā)工具,在此開發(fā)環(huán)境下開發(fā)軟件非常的方便。首先設(shè)計(jì)本系統(tǒng)手機(jī)端軟件的程序界面,為了盡快實(shí)現(xiàn)程序的功能,本程序沒有對(duì)軟件界面設(shè)計(jì)做特別美化的設(shè)計(jì),僅包含我們所用到的幾個(gè)按鈕和圖形顯示,以實(shí)現(xiàn)我們的功能為最大目標(biāo)。
下面介紹Android相關(guān)資源文件的作用[16、17]:
1、assets 文件夾:此文件夾也可以存放資源文件,而且/assets目錄下的資源文件不會(huì)在R.java自動(dòng)生成ID,所以讀取/assets目錄下的文件必須指定文件的路徑(url的路徑為:)。除此之外,我們還可以通過AssetManager類來訪問這些文件。打開文件時(shí),會(huì)把a(bǔ)pk文件當(dāng)做zip文件進(jìn)行解壓讀取。但是有文件大小有限制:不能超過1M(android2.2好像放寬(或者取消)了這個(gè)限制(至少可以存放>10M,具體沒有測(cè)試。))。
2、res 文件夾:主要用來存放資源。此文件夾下可以創(chuàng)建子文件,常見的有:動(dòng)畫anim,圖片drawable,顏色color,菜單menu, 布局layout,常量值values,詳細(xì)如下:
(1)anim文件夾:后綴名為.xml。動(dòng)畫文件都放在這里。
(2)drawable文件夾: 用于存放圖片資源,圖片或者xml。圖片格式,有png,9.png,jpg,gif都行。xml文件通常為自定義的形狀shape或圖片選擇器類selector似的東西,就是不同狀態(tài)下不同的圖片,用于設(shè)置background的。 對(duì)分辨率籠統(tǒng)的分,可以分為高中低三種分辨率。
(3)color文件夾:用于存放color列表,和drawable的xml一樣,表示不同狀態(tài)下的不同顏色
(4)menu文件夾:菜單資源文件夾。
(5) layout文件夾:布局文件夾。此文件夾的名字也是可以起到屏幕適配的功能的。①橫豎屏:layout-land|port;②分辨率:layout-1280x720
(6) values文件夾:存放常量值的文件夾。里面常見的xml文件為:
arrays.xml : 資源數(shù)組;colors.xml :  顏色值;dimens.xml : 像素值;
strings.xml :字符串值;tyles.xml : 樣式值。此文件夾,也有屏幕適配作用。比如:dimens在不同分辨率下的值。同樣的是加-1280x720這樣的后綴。對(duì)于strings,有各種語言的版本對(duì)應(yīng)。默認(rèn)為英文。中文的文件夾名字應(yīng)該是:values-zh-rCN,values-zh-rTW。
(7) raw文件夾:存放不需要系統(tǒng)編譯成二進(jìn)制的文件,例如字體文件等同assets文件夾類似。
(8) xml文件夾存放xml文件。
以下是手機(jī)端實(shí)現(xiàn)功能的程序流程圖如圖5.2所示。
圖5.2 藍(lán)牙通信流程圖

  • 手機(jī)界面程序設(shè)計(jì)
在設(shè)置手機(jī)界面的時(shí)候,在Eclipse集成開發(fā)環(huán)境下,首先新建一個(gè)android項(xiàng)目工程,興建路徑是File—New—android project—project name  選擇android 1.6版本,工程名命名為Bluetooth-car,選擇Create Activity,則自動(dòng)創(chuàng)建了一個(gè)Activity.在創(chuàng)建Activity時(shí),需要注意一下四個(gè)要點(diǎn):
1、一個(gè)Activity就是一個(gè)類,并且這個(gè)類要繼承Activity。
2、需要復(fù)寫Oncreate方法(當(dāng)一個(gè)Activity第一次運(yùn)行顯示在手機(jī)上或者虛擬機(jī)上的時(shí)就會(huì)調(diào)用Oncreate方法)。
3、每一個(gè)Activity都需要在Androidmanifast.xml文件當(dāng)中配置。
4、為Activity添加必要的控件。如圖5.3所示,在制作藍(lán)牙小車手機(jī)界面的時(shí)候,我用到了Textview 文本控件和 Butten按鈕控件,并且在添加控件時(shí)采用相對(duì)布局形式[18、19]。
圖5.3 手機(jī)界面圖
兩個(gè)Textview文本控件分別命名為:重慶郵電大學(xué)自動(dòng)化學(xué)院和藍(lán)牙控制系統(tǒng),在layout布局文件下可以任意改變控件的位置、字體的大小、背景圖片。改變背景圖片的方法為:首先將需要用到的背景圖片,分別拖入到drawable下,高中低分辨率都拖入一張,以便不同分辨率的手機(jī)識(shí)別,然后在layout布局文件下,打開Activity buletooth-car文件,調(diào)用添加安卓手機(jī)界面背景的語句為android:background="@drawable/background1" >,就能得到我們所修改的背景圖片。
二、手機(jī)監(jiān)聽程序設(shè)計(jì)
在Eclipes開發(fā)平臺(tái)上,首先在Layout文件中采用相對(duì)布局的形式設(shè)計(jì)完成手機(jī)界面以后,就要考慮為我們的每個(gè)Butten按鍵綁定監(jiān)聽程序,以實(shí)現(xiàn)在每個(gè)按鍵按下時(shí),就能通過手機(jī)藍(lán)牙發(fā)送相應(yīng)的數(shù)據(jù)到小車藍(lán)牙接收模塊。首先在Layout文件中,每添加一個(gè)控件,都會(huì)為這個(gè)控件設(shè)置一個(gè)ID,(如android:id="@+id/button1"),然后在R.JAVA文件就會(huì)自動(dòng)生成一個(gè)ID地址。然后在主程序里面編寫監(jiān)聽程序,當(dāng)按鍵按下的時(shí)候,通過監(jiān)聽按鍵的ID地址的不同,采用switch結(jié)構(gòu),跳轉(zhuǎn)到不同的case里,向小車藍(lán)牙模塊發(fā)送不同的數(shù)據(jù)。在程序里直接寫進(jìn)小車藍(lán)牙模塊的藍(lán)牙地址(00:12:10:31:01:70),當(dāng)程序開始運(yùn)行時(shí),將會(huì)自動(dòng)搜索該地址的藍(lán)牙芯片,當(dāng)進(jìn)行過一次配對(duì)連接以后,將會(huì)記憶該地址,以后每次只要打開手機(jī)界面,開始運(yùn)行時(shí)就會(huì)自動(dòng)進(jìn)行搜索配對(duì)連接好[20、21]。
* 按鈕點(diǎn)擊事件.
              * @param v
              */
              public void onClick(View v) {
                            switch (v.getId()) {
                            //轉(zhuǎn)寫按鈕
                            case R.id.button1:
                                          message[0] = (byte) 0x41;                                         
                                          vibrator();
                                          Toast.makeText(this, "前進(jìn)", Toast.LENGTH_LONG).show();
                                          bluesend(message);
                                          break;
                            //設(shè)置按鈕
                            case R.id.button2:
                                          message[0] = (byte) 0x44;
                                          vibrator();
                                          Toast.makeText(this, "后退", Toast.LENGTH_LONG).show();
                                          bluesend(message);
                                          break;
                            case R.id.button3:
                                          message[0] = (byte) 0x43;
                                          vibrator();
                                          Toast.makeText(this, "左轉(zhuǎn)", Toast.LENGTH_LONG).show();
                                          bluesend(message);
                                          break;
                            case R.id.button4:
                                          message[0] = (byte) 0x42;
                                          vibrator();
                                          Toast.makeText(this, "右轉(zhuǎn)", Toast.LENGTH_LONG).show();
                                          bluesend(message);
                                          break;
                            case R.id.button5:
                                          message[0] = (byte) 0x61;
                                          vibrator();                                         
                                          Toast.makeText(this, "停止", Toast.LENGTH_LONG).show();
                                          bluesend(message);
                                          break;
                                         
                            default:
                                          break;
                            }
              }


第三節(jié)  本章小結(jié)

本章主要介紹本系統(tǒng)的軟件設(shè)計(jì),其中就包括單片機(jī)端的C語言程序設(shè)計(jì)和Android手機(jī)端的JAVA程序設(shè)計(jì)。由于我們?cè)诒究齐A段都只接觸過C語言,對(duì)JAVA語言從未涉及過,所以在做起來的時(shí)候遇到了很多的困難。首先對(duì)JAVA語言的開發(fā)環(huán)境Eclipes的使用不熟悉,對(duì)新接觸語言的語法不熟悉。后來通過查找資料和對(duì)一些做好的工程例子的學(xué)習(xí)以后,有了對(duì)JAVA語言的大致的了解,就開始先學(xué)習(xí)著做簡(jiǎn)單的手機(jī)界面的程序。然后通過網(wǎng)上找到一些相關(guān)的程序進(jìn)行修改以及在指導(dǎo)老師的指導(dǎo)和修改下,完成了手機(jī)端的軟件設(shè)計(jì)。



章  系統(tǒng)整體調(diào)試


節(jié)  調(diào)試方案

根據(jù)電路原理圖、實(shí)物 圖把電路板實(shí)物做出來后,下一步就是電路板調(diào)試。電路板調(diào)試是最關(guān)鍵的一步,前面所做的電路設(shè)計(jì)的成功與否就是在調(diào)試步驟里體現(xiàn)的。本系統(tǒng)的調(diào)試主要分為硬件調(diào)試、軟件調(diào)試和系統(tǒng)整體調(diào)試等三大部分。
經(jīng)過初步對(duì)定時(shí)器的分析設(shè)計(jì)后,在制作硬件電路的同時(shí),調(diào)試也在穿插進(jìn)行。這樣有利于問題的分析和解決,不會(huì)造成問題的積累,而且不會(huì)因?yàn)橐粋(gè)小問題而影響整體電路的檢查,從而可以節(jié)約大量的調(diào)試時(shí)間。例如當(dāng)單片機(jī)控制模塊硬件部分制作好后,就可以先調(diào)試電機(jī)轉(zhuǎn)動(dòng)程序,通過電機(jī)驅(qū)動(dòng)控制電機(jī)轉(zhuǎn)動(dòng)了,則結(jié)果正確了,說明電機(jī)驅(qū)動(dòng)電路與單片機(jī)的連接電路是正確的,單片機(jī)能正常工作。軟件編程中,首先完成單元功能模塊的調(diào)試,然后進(jìn)行系統(tǒng)的調(diào)試,調(diào)試的整體思想和步驟和硬件大同小異。系統(tǒng)的整體調(diào)試是最重要的一部分,雖然軟硬件調(diào)試都通過了,但是通過藍(lán)牙傳輸數(shù)據(jù)過程中可能會(huì)出現(xiàn)新的問題。


節(jié)  硬件電路調(diào)試

硬件單元電路制作好后,在上電之前,應(yīng)該先用萬用表對(duì)各個(gè)獨(dú)立元件進(jìn)行檢查,在排除了虛焊、短路、斷路等問題后再通電進(jìn)行電路功能的調(diào)試。具體調(diào)試過程如下所述:
一、獨(dú)立元件的檢測(cè)
任何組裝好的電子電路,在通電調(diào)試之前,必須認(rèn)真檢查電路連線是否有誤。檢查的方法是對(duì)照電路圖,按一定的順序逐級(jí)對(duì)應(yīng)檢查,例如:對(duì)電路板的電阻阻值進(jìn)行確定,可以通過讀取電阻上的色環(huán)進(jìn)行確認(rèn)。特別是注意電源是否接錯(cuò),電源與地是否有短接,集成電路和晶體管的引腳是否接錯(cuò),輕輕撥一撥元器件,觀察焊點(diǎn)是否牢固等。用萬用表檢測(cè)是不是有短路和斷路現(xiàn)象。
給系統(tǒng)上電后,看下電源(綠色)燈亮不亮。假如不亮,就要檢查電源指示燈發(fā)光二極管的好壞。還要用萬用表測(cè)一下單片機(jī)等芯片的電壓是不是符合要求。假如不是,就要進(jìn)行各個(gè)芯片的檢查,看一下各個(gè)芯片的引腳有沒有焊好,芯片是否損壞。

圖6.1 驅(qū)動(dòng)模塊反面圖


圖6.2 藍(lán)牙模塊正反面圖


圖6.3 藍(lán)牙模塊調(diào)試圖

二、單片機(jī)最小系統(tǒng)的調(diào)試
單片機(jī)AT89C52最小系統(tǒng)的檢測(cè)分為硬件調(diào)試及軟件調(diào)試。量電源電壓有沒有到位,量復(fù)位RSL腳電平對(duì)不對(duì),如果是高電平復(fù)位那么平時(shí)應(yīng)該是低電平,量外部晶振有沒有起振,最小系統(tǒng)電路參考芯片PDF文檔,確認(rèn)正確。
硬件調(diào)試時(shí)用萬用表測(cè)量單片機(jī)的工作電壓及各個(gè)管腳的電壓是否達(dá)到正常工作電壓。在此檢測(cè)中還要燒入程序?qū)Ω鱾(gè)I/O口的輸出進(jìn)行測(cè)試,查看I/O口所輸出的電壓是否與程序所控制值一致。例如:編寫一個(gè)調(diào)試程序,使的所有I/O口從P1.0口開始依次賦予低電平,用萬用表測(cè)量其輸出電壓,確定是否與程序所付值一致,一致則證明正確;然后又對(duì)其依次賦予高電平,確定是否與程序所付值一致,一致則證明正確。兩次測(cè)試都正確,證明單片機(jī)最小系統(tǒng)是正常工作的。



圖6.4 單片機(jī)調(diào)試圖
、電源電路的調(diào)試
電源電路作為整個(gè)系統(tǒng)的供電電路,其輸出電壓必須在單片機(jī)的正常工作電壓范圍(4V到5.5V之間)內(nèi)。在電源通電之前,一定要檢查電路是否接錯(cuò),特別是極性電容是否有接反,防止出現(xiàn)極性電容接反而造成爆電容的現(xiàn)象。在確保器件接法無誤的情況下,接通電源,并用萬用表測(cè)量輸出電壓,得到其電壓為5.3V,符合系統(tǒng)的正常工作電壓要求。然后再在電機(jī)驅(qū)動(dòng)輸出端接上干電池, 實(shí)現(xiàn)兩個(gè)電源供電。
四、驅(qū)動(dòng)模塊的調(diào)試

驅(qū)動(dòng)模塊為驅(qū)動(dòng)電機(jī)的芯片,L298需要從外部接兩個(gè)電壓,一個(gè)是給電機(jī)的,另一個(gè)給L298芯片的。首先檢查驅(qū)動(dòng)芯片與單片機(jī)的各個(gè)連線是否都正確以后,給芯片通上電源,單片機(jī)指示燈點(diǎn)亮以后。運(yùn)行單片機(jī)上的程序,通過單片機(jī)P2口的數(shù)據(jù)變化來控制L298的IN1、IN2、IN3、IN4的電平的高低。L298輸入端的高低電平的變化,通過輸入端的LED燈的亮滅來顯示。當(dāng)運(yùn)行前進(jìn)程序的時(shí)候,IN1、IN2、IN3、IN4的值為1、0、1、0,分別點(diǎn)亮LED1和LED3,左右電機(jī)都正轉(zhuǎn),實(shí)現(xiàn)小車前進(jìn);運(yùn)行左轉(zhuǎn)程序的時(shí)候,IN1、IN2、IN3、IN4分別為1、0、0、1,分別點(diǎn)亮LED1、LED4,左電機(jī)正轉(zhuǎn),右電機(jī)反轉(zhuǎn),實(shí)現(xiàn)小車左轉(zhuǎn);運(yùn)行右轉(zhuǎn)程序的時(shí)候,IN1、IN2、IN3、IN4的值為0、1、1、0,點(diǎn)亮LED2,LED3,左電機(jī)反轉(zhuǎn),右電機(jī)正轉(zhuǎn),實(shí)現(xiàn)小車右轉(zhuǎn);運(yùn)行后退程序的時(shí)候,IN1、IN2、IN3、IN4的值分別為0、1、0、1,分別點(diǎn)亮LED2、LED4,左右電機(jī)都反轉(zhuǎn),實(shí)現(xiàn)小車后退。通過調(diào)試電機(jī)驅(qū)動(dòng)模塊能實(shí)現(xiàn)基本的功能。其調(diào)試圖如圖6.5,圖6.6,圖6.7,圖6.8所示。



圖6.5 小車前進(jìn)指示圖



圖6.6 小車后退指示圖

圖6.7 小車左轉(zhuǎn)指示圖




圖6.8 小車右轉(zhuǎn)指示圖


節(jié)  軟件調(diào)試
、C語言的調(diào)試
軟件的調(diào)試包括程序本身語法的調(diào)試和在電路板上功能的調(diào)試兩種。在編程過程中,為了得到滿足要求的用戶程序,一般都需要有一個(gè)對(duì)程序的調(diào)試過程,甚至需要經(jīng)過多次反復(fù)的調(diào)試才能完成。在調(diào)試程序前為了調(diào)試方便,避免程序出錯(cuò)時(shí)將單片機(jī)拆來拆去的麻煩,在電路板上做了一個(gè)下載口,可以將下載線直接插到電路板上進(jìn)行調(diào)試,這樣就可以一邊進(jìn)行調(diào)試,一邊修改程序。程序用Keil C軟件寫好后,先用該軟件的編譯功能編譯一下所寫的程序,檢查程序是有語法錯(cuò)誤或其他的錯(cuò)誤。如果有錯(cuò)誤則根據(jù)提示進(jìn)行分析將錯(cuò)誤改過來直至編譯成功為止。當(dāng)完成了語法調(diào)試后,再根據(jù)定時(shí)開關(guān)插座設(shè)計(jì)的功能要求修改程序完成系統(tǒng)的各個(gè)功能。在編寫程序的時(shí)候一定要根據(jù)系統(tǒng)實(shí)現(xiàn)的功能和連接方式,認(rèn)真分析,畫出系統(tǒng)主程序、時(shí)鐘程序、設(shè)置程序的流程圖,并根據(jù)畫出的流程圖一步一步的去寫出程序。
根據(jù)系統(tǒng)的特點(diǎn),軟件系統(tǒng)應(yīng)該按模塊進(jìn)行調(diào)試,當(dāng)各個(gè)模塊調(diào)試通過后再將各個(gè)模塊整合起來,進(jìn)行綜合調(diào)試,直到得到預(yù)期結(jié)果。
與純粹的C語言編程不同的是,單片機(jī)編程要考慮到硬件的設(shè)計(jì),所有程序的編寫都是根據(jù)硬件資源進(jìn)行。

二.JAVA語言的調(diào)試

將做好的工程添加進(jìn)入Eclipes開發(fā)環(huán)境中,檢查各個(gè)文件夾下面的程序有沒有出現(xiàn)打紅色X的問題以及警告,點(diǎn)開下方的problem的文件,檢查該工程有沒有出現(xiàn)問題,當(dāng)排除了所有的問題以后。配置一個(gè)2.2版本的模擬器,然后啟動(dòng)模擬器,在模擬器上運(yùn)行該工程,在模擬器上將會(huì)出現(xiàn)已經(jīng)做好的手機(jī)界面,運(yùn)行完成,調(diào)試成功。然后將手機(jī)連接到電腦上,打開安卓手機(jī)的USB接口。接下來點(diǎn)擊運(yùn)行整個(gè)工程項(xiàng)目,在手機(jī)上出現(xiàn)前面那個(gè)做好的藍(lán)牙小車控制界面。點(diǎn)擊各個(gè)按鈕,都無問題,證明該JAVA程序沒有問題[22]。

圖6.9 手機(jī)端程序運(yùn)行圖


節(jié)  系統(tǒng)整體的調(diào)試

藍(lán)牙控制小車的硬件模塊和軟件模塊分別調(diào)試通過后,接下來就可以進(jìn)行系統(tǒng)的整體測(cè)試。首先檢查各個(gè)模塊之間,以及電機(jī)驅(qū)動(dòng)與電機(jī)的連接都沒有出錯(cuò)的情況下,打開給各個(gè)模塊提供的5V電源以及打開給電機(jī)提供的另一個(gè)6V電源。此時(shí)最小系統(tǒng)模塊指示燈點(diǎn)亮,表示單片機(jī)供電正常,藍(lán)牙模塊指示燈開始閃爍,表示藍(lán)牙模塊也供電正常。此時(shí)打開安卓手機(jī)的藍(lán)牙,搜索該藍(lán)牙芯片,進(jìn)行配對(duì)。然后打開我們做好的手機(jī)界面,當(dāng)界面打開之后,開始自動(dòng)搜索藍(lán)牙芯片的地址進(jìn)行連接,當(dāng)藍(lán)牙芯片的指示燈有閃爍轉(zhuǎn)變?yōu)槌A烈院螅硎舅{(lán)牙配對(duì)連接成功。在剛開始的時(shí)候調(diào)試的時(shí)候遇到了一些問題,在電機(jī)驅(qū)動(dòng)方面,當(dāng)在手機(jī)端的界面上點(diǎn)擊前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)按鈕的時(shí)候,藍(lán)牙模塊能接受手機(jī)端發(fā)送的字符A、B、C、D的ASCII碼值,并且能夠通過串口相應(yīng)的傳遞給單片機(jī),單片機(jī)通過分析串口傳過來的數(shù)據(jù),改變P2口的值分別為65、66、67、68,來控制電機(jī)驅(qū)動(dòng)的輸入端IN1、IN2、IN3、IN4。相應(yīng)的電機(jī)驅(qū)動(dòng)端的四個(gè)指示LED燈都能根據(jù)數(shù)據(jù)的變化采取不同的量滅組合情況,來相應(yīng)控制小車的前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)[23、24、25]。

圖6.10 小車底板正面圖




圖6.11 小車底板反面圖



圖6.12 小車實(shí)體圖


節(jié)  本章小結(jié)

在調(diào)試的過程中也遇到一些問題,就是最開始電機(jī)驅(qū)動(dòng)輸出端控制的電機(jī)卻不會(huì)轉(zhuǎn)動(dòng)。通過分析,可能有兩個(gè)原因?qū)е码姍C(jī)不會(huì)轉(zhuǎn)動(dòng),其一,電機(jī)驅(qū)動(dòng)的輸出端的接線出現(xiàn)了錯(cuò)誤,導(dǎo)致電機(jī)轉(zhuǎn)動(dòng)出現(xiàn)問題;其二,電機(jī)驅(qū)動(dòng)端接的給電機(jī)供電的電壓達(dá)不到驅(qū)動(dòng)電機(jī)的最低電壓,最后通過查詢資料和用萬用表測(cè)驅(qū)動(dòng)模塊的輸出端的各個(gè)引腳的高低電平,發(fā)現(xiàn)輸出端的電平也能隨輸入端的改變而變化,當(dāng)最后測(cè)試VCC和GND兩端,發(fā)現(xiàn)無明顯的壓降,再用萬用表的測(cè)電阻值測(cè)兩端的阻值,發(fā)現(xiàn)問題是電機(jī)驅(qū)動(dòng)模塊輸出端的供電端VCC與GND端短路,導(dǎo)致外接電源不能給電機(jī)供電。最后我通過直接從芯片的引腳接線到電源端,則電機(jī)能夠正常轉(zhuǎn)動(dòng)。





結(jié)  論


本次畢業(yè)設(shè)計(jì)是一個(gè)基于單片機(jī)AT89C52的智能小車控制,包括方案選擇、軟硬件設(shè)計(jì)、單片機(jī)最小系統(tǒng)、電機(jī)驅(qū)動(dòng)電路和藍(lán)牙電路、硬件測(cè)試結(jié)果及解決在電路調(diào)試時(shí)遇到的問題。在此期間主要完成的工作包括以下幾個(gè)方面:
(1)設(shè)計(jì)初期收集電機(jī)驅(qū)動(dòng)、單片機(jī)等相關(guān)資料,對(duì)智能小車的實(shí)現(xiàn)原理有比較清晰的了解。
(2)確定系統(tǒng)框圖,對(duì)電源模塊、單片機(jī)最小系統(tǒng)模塊、藍(lán)牙電路模塊和電機(jī)及其驅(qū)動(dòng)電路模塊等的實(shí)施方案進(jìn)行比較,確定最終的智能小車控制的設(shè)計(jì)方案。
(3)根據(jù)智能小車控制的原理圖制作出電路連接圖。
(4)根據(jù)系統(tǒng)要實(shí)現(xiàn)前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)等功能編寫出小車端的軟件程序。
(5)在eclipes開發(fā)環(huán)境下,應(yīng)用JAVA程序編寫手機(jī)界面程序,并且通過模擬器來檢測(cè)手機(jī)界面程序。
(6)軟硬件調(diào)試通過后進(jìn)行整體調(diào)試,并查找該系統(tǒng)存在的缺陷,進(jìn)行完善。
(7)最終小車能夠?qū)崿F(xiàn)前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)等功能,達(dá)到老師給出的基本要求。
本次設(shè)計(jì)完成了基于安卓手機(jī)的智能小車控制系統(tǒng)。該系統(tǒng)采用51單片機(jī)AT89C52編程控制電機(jī)的正反轉(zhuǎn)來實(shí)現(xiàn)小車前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn),而電機(jī)的正反轉(zhuǎn)則由電機(jī)驅(qū)動(dòng)L298N輸出端的邏輯電平來控制。
從整個(gè)設(shè)計(jì)的過程來看前期的充分的準(zhǔn)備顯得非常的重要,經(jīng)過前期充分的準(zhǔn)備,和對(duì)嵌入式系統(tǒng)開發(fā)的學(xué)習(xí),避免了很多在后續(xù)的設(shè)計(jì)中可能出現(xiàn)的問題。
MCU端的軟硬件設(shè)計(jì)因?yàn)榕c所學(xué)知識(shí)相關(guān)性較大,所以出現(xiàn)的問題較少,MCU底板設(shè)計(jì)時(shí)鑒于電路簡(jiǎn)單,且易于焊接,故未采用PCB制版也相應(yīng)的節(jié)約了成本。特別值得一提的是為了提高系統(tǒng)在硬件上的安全性和穩(wěn)定性,我特別添加了硬件保護(hù)裝置,以提高系統(tǒng)的硬件防碰撞的能力。
主要的問題出現(xiàn)在android端的軟件設(shè)計(jì)上,由于對(duì)android開發(fā)環(huán)境的不熟悉,缺乏一些在編寫JAVA程序時(shí)的一些技巧性問題,所以剛剛開始時(shí)總是出現(xiàn)很多問題,并且出現(xiàn)的問題都需要查找相關(guān)資料才能解決。通過學(xué)習(xí)一些android相關(guān)的學(xué)習(xí)視頻,最后對(duì)android環(huán)境有了一個(gè)系統(tǒng)的了解在開發(fā)的過程中也得心應(yīng)手些。
Android端圖形界面的設(shè)計(jì)也是一大難點(diǎn),基于Java的圖形界面設(shè)計(jì)不論是從設(shè)計(jì)平臺(tái)還是Java語言的掌握都是一想挑戰(zhàn),但幸于Java軟件的開發(fā)技術(shù)已經(jīng)成熟,且可查閱的資料多且詳盡,所以圖形界面的設(shè)計(jì)達(dá)到設(shè)計(jì)時(shí)的五項(xiàng)按鍵要求,功能實(shí)現(xiàn)良好,除界面的友好程度可以更加優(yōu)化外,其余完成任務(wù)。
總體來看,我進(jìn)行了比較充分的準(zhǔn)備,在實(shí)踐過程中通過查閱相關(guān)資料和咨詢有關(guān)人員,克服了系統(tǒng)設(shè)計(jì)過程中的絕大多數(shù)困難,基本都以達(dá)到設(shè)計(jì)要求,并通過了軟件測(cè)試。

致  謝


畢業(yè)設(shè)計(jì)完成了,在這個(gè)過程中我學(xué)到了很多東西。首先我要感謝我的導(dǎo)師羅萍老師,他在我完成論文的過程中,給予了我很大的幫助。在論文開始的初期,我對(duì)于論文的結(jié)構(gòu)以及文獻(xiàn)選取等方面都有很多問題,是在老師的幫助下進(jìn)行修改和完善的。本畢業(yè)設(shè)計(jì)是在羅萍老師悉心的關(guān)懷與指導(dǎo)下完成,在此對(duì)老師獻(xiàn)上最衷心地感謝。羅萍老師從畢業(yè)設(shè)計(jì)一開始就對(duì)我們嚴(yán)格要求,每周的周一都會(huì)和我們開見面會(huì),詢問我們的畢設(shè)進(jìn)度并了解我們遇到的困難,積極協(xié)助我們解決設(shè)計(jì)過程中的各種難題,并要求我們每天記錄在畢業(yè)設(shè)計(jì)中所作的工作進(jìn)度及遇到的問題,讓我們?nèi)グl(fā)現(xiàn)問題,解決問題。在我遇到難已解決的問題心中急躁時(shí),羅萍老師總是及時(shí)的給予鼓勵(lì),使我能夠有勇敢的克服困難,把畢設(shè)繼續(xù)進(jìn)行下去。羅萍老師對(duì)學(xué)生的高度關(guān)注和對(duì)工作高度負(fù)責(zé)的精神值得我們尊敬,也是我今后走向工作崗位的榜樣。通過本次畢業(yè)設(shè)計(jì),我不僅是對(duì)我們所學(xué)知識(shí)的一個(gè)匯總,同時(shí)也是考驗(yàn)我們學(xué)習(xí)能力和動(dòng)手能力的一個(gè)平臺(tái);讓我們能學(xué)到更多的相關(guān)知識(shí),更重要的是學(xué)到了面對(duì)困難的不放棄、不氣餒的態(tài)度,不驕不躁的辦事風(fēng)格,奮發(fā)向上的精神,這些在我今后的生活和學(xué)習(xí)中都是一筆寶貴的財(cái)富。
最后,我要再次感謝在畢業(yè)設(shè)計(jì)過程中對(duì)我提供過制作電路板等工具的同學(xué)和老師,以及在畢業(yè)設(shè)計(jì)中對(duì)我進(jìn)行過指導(dǎo)的所有老師和同學(xué)。

附  


一、英文原文
Application Fundamentals
Android applications are written in the Java programming language. The compiled Java code — along with any data and resource files required by the application — is bundled by the aapt tool into an Android package, an archive file marked by an .apk suffix. This file is the vehicle for distributing the application and installing it on mobile devices; it's the file users download to their devices. All the code in a single .apk file is considered to be one application.
In many ways, each Android application lives in its own world:
1. By default, every application runs in its own Linux process. Android starts the process when any of the application's code needs to be executed, and shuts down the process when it's no longer needed and system resources are required by other applications.
2. Each process has its own virtual machine (VM), so application code runs in isolation from the code of all other applications.
3. By default, each application is assigned a unique Linux user ID. Permissions are set so that the application's files are visible only to that user and only to the application itself — although there are ways to export them to other applications as well.
It's possible to arrange for two applications to share the same user ID, in which case they will be able to see each other's files. To conserve system resources, applications with the same ID can also arrange to run in the same Linux process, sharing the same VM.
Application Components
A central feature of Android is that one application can make use of elements of other applications (provided those applications permit it). For example, if your application needs to display a scrolling list of images and another application has developed a suitable scroller and made it available to others, you can call upon that scroller to do the work, rather than develop your own. Your application doesn't incorporate the code of the other application or link to it. Rather, it simply starts up that piece of the other application when the need arises.
For this to work, the system must be able to start an application process when any part of it is needed, and instantiate the Java objects for that part. Therefore, unlike applications on most other systems, Android applications don't have a single entry point for everything in the application (no main() function, for example). Rather, they have essential components that the system can instantiate and run as needed. There are four types of components:
Activities
An activity presents a visual user interface for one focused endeavor the user can undertake. For example, an activity might present a list of menu items users can choose from or it might display photographs along with their captions. A text messaging application might have one activity that shows a list of contacts to send messages to, a second activity to write the message to the chosen contact, and other activities to review old messages or change settings. Though they work together to form a cohesive user interface, each activity is independent of the others. Each one is implemented as a subclass of the Activity base class.
An application might consist of just one activity or, like the text messaging application just mentioned, it may contain several. What the activities are, and how many there are depends, of course, on the application and its design. Typically, one of the activities is marked as the first one that should be presented to the user when the application is launched. Moving from one activity to another is accomplished by having the current activity start the next one.
Each activity is given a default window to draw in. Typically, the window fills the screen, but it might be smaller than the screen and float on top of other windows. An activity can also make use of additional windows — for example, a pop-up dialog that calls for a user response in the midst of the activity, or a window that presents users with vital information when they select a particular item on-screen.
The visual content of the window is provided by a hierarchy of views — objects derived from the base View class. Each view controls a particular rectangular space within the window. Parent views contain and organize the layout of their children. Leaf views (those at the bottom of the hierarchy) draw in the rectangles they control and respond to user actions directed at that space. Thus, views are where the activity's interaction with the user takes place.
For example, a view might display a small image and initiate an action when the user taps that image. Android has a number of ready-made views that you can use — including buttons, text fields, scroll bars, menu items, check boxes, and more.
A view hierarchy is placed within an activity's window by the Activity.setContentView() method. The content view is the View object at the root of the hierarchy. (See the separate User Interface document for more information on views and the hierarchy.)
Services
A service doesn't have a visual user interface, but rather runs in the background for an indefinite period of time. For example, a service might play background music as the user attends to other matters, or it might fetch data over the network or calculate something and provide the result to activities that need it. Each service extends the Service base class.
A prime example is a media player playing songs from a play list. The player application would probably have one or more activities that allow the user to choose songs and start playing them. However, the music playback itself would not be handled by an activity because users will expect the music to keep playing even after they leave the player and begin something different. To keep the music going, the media player activity could start a service to run in the background. The system would then keep the music playback service running even after the activity that started it leaves the screen.
It's possible to connect to (bind to) an ongoing service (and start the service if it's not already running). While connected, you can communicate with the service through an interface that the service exposes. For the music service, this interface might allow users to pause, rewind, stop, and restart the playback.
Like activities and the other components, services run in the main thread of the application process. So that they won't block other components or the user interface, they often spawn another thread for time-consuming tasks (like music playback). See Processes and Threads, later.
Broadcast receivers
A broadcast receiver is a component that does nothing but receive and react to broadcast announcements. Many broadcasts originate in system code — for example, announcements that the timezone has changed, that the battery is low, that a picture has been taken, or that the user changed a language preference. Applications can also initiate broadcasts — for example, to let other applications know that some data has been downloaded to the device and is available for them to use.
An application can have any number of broadcast receivers to respond to any announcements it considers important. All receivers extend the BroadcastReceiver base class.
Broadcast receivers do not display a user interface. However, they may start an activity in response to the information they receive, or they may use the Notification Manager to alert the user. Notifications can get the user's attention in various ways — flashing the backlight, vibrating the device, playing a sound, and so on. They typically place a persistent icon in the status bar, which users can open to get the message.
Content providers
A content provider makes a specific set of the application's data available to other applications. The data can be stored in the file system, in an SQLite database, or in any other manner that makes sense. The content provider extends the Content Provider base class to implement a standard set of methods that enable other applications to retrieve and store data of the type it controls. However, applications do not call these methods directly. Rather they use a Content Resolver object and call its methods instead. A Content Resolver can talk to any content provider; it cooperates with the provider to manage any interprocess communication that's involved.
See the separate Content Providers document for more information on using content providers.
Whenever there's a request that should be handled by a particular component, Android makes sure that the application process of the component is running, starting it if necessary, and that an appropriate instance of the component is available, creating the instance if necessary.
Activating components: intents
Content providers are activated when they're targeted by a request from a Content Resolver. The other three components — activities, services, and broadcast receivers — are activated by asynchronous messages called intents. An intent is an Intent object that holds the content of the message. For activities and services, it names the action being requested and specifies the URI of the data to act on, among other things. For example, it might convey a request for an activity to present an image to the user or let the user edit some text. For broadcast receivers, the
Intent object names the action being announced. For example, it might announce to interested parties that the camera button has been pressed.
There are separate methods for activating each type of component:
1. An activity is launched (or given something new to do) by passing an Intent object to
Context.start Activity() or Activity .start Activity For Result(). The responding activity can look at the initial intent that caused it to be launched by calling its getIntent() method. Android calls the activity's  on New Intent() method to pass it any subsequent intents. One activity often starts the next one. If it expects a result back from the activity it's starting, it calls  start Activity For Result() instead of  start Activity(). For example, if it starts an activity that lets the user pick a photo, it might expect to be returned the chosen photo. The result is returned in an Intent object that's passed to the calling activity's on Activity Result() method.
2. A service is started (or new instructions are given to an ongoing service) by passing an Intent object to Context. Start Service(). Android calls the service's onStart() method and passes it the Intent object. Similarly, an intent can be passed to Context. Bind Service() to establish an ongoing connection between the calling component and a target service. The service receives the Intent object in an on Bind() call. (If the service is not already running, bind Service() can optionally start it.) For example, an activity might establish a connection with the music playback service mentioned earlier so that it can provide the user with the means (a user interface) for controlling the playback. The activity would call bind Service() to set up that connection, and then call methods defined by the service to affect the playback.
A later section, Remote procedure calls, has more details about binding to a service.
3. An application can initiate a broadcast by passing an Intent object to methods like Context. Send Broadcast(), Context. Send Ordered Broadcast(), and Context. Send Sticky Broadcast() in any of their variations.
Android delivers the intent to all interested broadcast receivers by calling their on Receive() methods. For more on intent messages, see the separate article, Intents and Intent Filters.
Shutting down components
A content provider is active only while it's responding to a request from a Content Resolver. And a broadcast receiver is active only while it's responding to a broadcast message. So there's no need to explicitly shut down these components.
Activities, on the other hand, provide the user interface. They're in a long-running conversation with the user and may remain active, even when idle, as long as the conversation continues. Similarly, services may also remain running for a long time. So Android has methods to shut down activities and services in an orderly way:
1. An activity can be shut down by calling its finish() method. One activity can shut down another activity (one it started with start Activity For Result()) by calling finish Activity().
2. A service can be stopped by calling its stop Self() method, or by calling Context .stop Service().
Components might also be shut down by the system when they are no longer being used or when Android must reclaim memory for more active components. A later section, Component Lifecycles, discusses this possibility and its ramifications in more detail.
The manifest file
Before Android can start an application component, it must learn that the component exists. Therefore, applications declare their components in a manifest file that's bundled into the Android package, the .apk file that also holds the application's code, files, and resources.
The manifest is a structured XML file and is always named AndroidManifest.xml for all applications. It does a number of things in addition to declaring the application's components, such as naming any libraries the application needs to be linked against (besides the default Android library) and identifying any permissions the application expects to be granted.
But the principal task of the manifest is to inform Android about the application's components. For example, an activity might be declared as follows:
The name attribute of the <activity> element names the Activity subclass that implements the activity. The icon and label attributes point to resource files containing an icon and label that can be displayed to users to represent the activity.
The other components are declared in a similar way — <service> elements for services, <receiver> elements for broadcast receivers, and <provider> elements for content providers. Activities, services, and content providers that are not declared in the manifest are not visible to the system and are consequently never run. However, broadcast receivers can either be declared in the manifest, or they can be created dynamically in code (as BroadcastReceiver objects) and registered with the system by calling Context.registerReceiver().
For more on how to structure a manifest file for your application, see The Android Manifest.xml File.
Intent filters
An Intent object can explicitly name a target component. If it does, Android finds that component (based on the declarations in the manifest file) and activates it. But if a target is not explicitly named, Android must locate the best component to respond to the intent. It does so by comparing the Intent object to the intent filtersof potential targets. A component's intent filters inform Android of the kinds of intents the component is able to handle. Like other essential information about the component, they're declared in the manifest file. Here's an extension of the previous example that adds two intent filters to the activity:
The first filter in the example — the combination of the action "android.intent.action.MAIN" and the category
"android.intent.category.LAUNCHER" — is a common one. It marks the activity as one that should be represented in the application launcher, the screen listing applications users can launch on the device. In other words, the activity is the entry point for the application, the initial one users would see when they choose the application in the launcher.
The second filter declares an action that the activity can perform on a particular type of data.
A component can have any number of intent filters, each one declaring a different set of capabilities. If it doesn't have any filters, it can be activated only by intents that explicitly name the component as the target.
For a broadcast receiver that's created and registered in code, the intent filter is instantiated directly as an IntentFilter object. All other filters are set up in the manifest.
For more on intent filters, see a separate document, Intents and Intent Filters.


  • 英文翻譯
應(yīng)用程序基礎(chǔ)Android Developers
Android應(yīng)用程序使用Java編程語言開發(fā)。aapt工具把編譯后的Java代碼連同應(yīng)用程序所需的其他數(shù)據(jù)和資源文件一起打包到一個(gè)Android包文件中,這個(gè)文件使用.apk作為擴(kuò)展名。此文件是分發(fā)并安裝應(yīng)用程序到移動(dòng)設(shè)備的載體;是用戶下載到他們的設(shè)備的文件。單一.apk文件中的所有代碼被認(rèn)為是一個(gè)應(yīng)用程序。
從多個(gè)角度來看,每個(gè)Android應(yīng)用程序都存在于它自己的世界之中:
   1 默認(rèn)情況下,每個(gè)應(yīng)用程序均運(yùn)行于它自己的Linux進(jìn)程中。當(dāng)應(yīng)用程序中的任何代碼需要被執(zhí)行時(shí),Android啟動(dòng)此進(jìn)程,而當(dāng)不再需要此進(jìn)程并且其它應(yīng)用程序又請(qǐng)求系統(tǒng)資源時(shí),則關(guān)閉這個(gè)進(jìn)程。
 2 每個(gè)進(jìn)程都有其獨(dú)有的虛擬機(jī)(VM),所以應(yīng)用程序代碼與所有其它應(yīng)用程序代碼是隔離運(yùn)行的。
   3 默認(rèn)情況下,每個(gè)應(yīng)用程序均被賦予一個(gè)唯一的Linux用戶ID,并加以權(quán)限設(shè)置,使得應(yīng)用程序的文件僅對(duì)此用戶及此應(yīng)用程序可見——盡管也有其它的方法使得這些文件同樣能為其他應(yīng)用程序所訪問。
1 應(yīng)用程序組件
Android的一個(gè)核心特性就是一個(gè)應(yīng)用程序可以使用其它應(yīng)用程序的元素(如果那個(gè)應(yīng)用程序允許的話)。例如,如果你的應(yīng)用程序需要顯示一個(gè)圖片卷動(dòng)列表,而另一個(gè)應(yīng)用程序已經(jīng)開發(fā)了一個(gè)合用的而又允許別的應(yīng)用程序使用的話,你可以直接調(diào)用那個(gè)卷動(dòng)列表來完成工作,而不用自己再開發(fā)一個(gè)。你的應(yīng)用程序并沒有吸納或鏈接其它應(yīng)用程序的代碼。它只是在有需求的時(shí)候啟動(dòng)了其它應(yīng)用程序的那個(gè)功能部分。
為達(dá)到這個(gè)目的,系統(tǒng)必須能夠在一個(gè)應(yīng)用程序的任何一部分被需要時(shí)啟動(dòng)一個(gè)此應(yīng)用程序的進(jìn)程,并將那個(gè)部分的Java對(duì)象實(shí)例化。因此,不像其它大多數(shù)系統(tǒng)上的應(yīng)用程序,Android應(yīng)用程序并沒有為應(yīng)用程序提供一個(gè)單獨(dú)的入口點(diǎn)(比如說,沒有main()函數(shù)),而是為系統(tǒng)提供了可以實(shí)例化和運(yùn)行所需的必備組件。一共有四種組件類型:
1 Activity
activity是為用戶操作而展示的可視化用戶界面。例如,一個(gè)activity可以展示一個(gè)菜單項(xiàng)列表供用戶選擇,戒者顯示一些包含說明文字的照片。一個(gè)短消息應(yīng)用程序可以包括一個(gè)用于顯示要發(fā)送消息到的聯(lián)系人列表的activity,一個(gè)給選定的聯(lián)系人寫短信的activity以及翻閱以前的短信或改變?cè)O(shè)置的其他activity。盡管它們一起組成了一個(gè)內(nèi)聚的用戶界面,但其中每個(gè)activity都不其它的保持獨(dú)立。每一個(gè)都實(shí)現(xiàn)為以Activity類為基類的子類。
一個(gè)應(yīng)用程序可以只有一個(gè)activity,戒者,如剛才提到的短信應(yīng)用程序那樣,包含很多個(gè)。每個(gè)activity的作用,以及有多少個(gè)activity,當(dāng)然是取決于應(yīng)用程序及其設(shè)計(jì)的。一般情況下,總有一個(gè)應(yīng)用程序被標(biāo)記為用戶在應(yīng)用程序啟動(dòng)的時(shí)候第一個(gè)看到的。從一個(gè)activity轉(zhuǎn)向另一個(gè)靠的是用當(dāng)前的activity啟動(dòng)下一個(gè)。
每個(gè)activity都被給予一個(gè)默認(rèn)的窗口以進(jìn)行繪制。一般情況下,這個(gè)窗口是滿屏的,但它也可以是一個(gè)小的位于其它窗口之上的浮動(dòng)窗口。一個(gè)activity也可以使用附加窗口——例如,一個(gè)在activity運(yùn)行過程中彈出的供用戶響應(yīng)的對(duì)話框,戒是一個(gè)當(dāng)用戶選擇了屏幕上特定項(xiàng)目后顯示的必要信息的窗口。
窗口顯示的可視內(nèi)容是由一系列層次化view構(gòu)成的,這些view均繼承自 View 基類。每個(gè)view均控制著窗口中一塊特定的矩形區(qū)域。父級(jí)view包含并組織其子view的布局。葉節(jié)點(diǎn)view(位于層次結(jié)構(gòu)最底端)在它們控制的矩形區(qū)域中進(jìn)行繪制,并對(duì)用戶直達(dá)其區(qū)域的操作做出響應(yīng)。因此,view是activity與用戶進(jìn)行交互的界面。例如,view可以顯示一個(gè)小圖片,并在用戶指點(diǎn)它的時(shí)候產(chǎn)生動(dòng)作。Android有一些預(yù)置的view供開發(fā)者使用——包括按鈕、文本域、滾動(dòng)條、菜單項(xiàng)、復(fù)選框等等。
view層次結(jié)構(gòu)是由Activity.setContentView() 方法放入activity的窗口之中的。content view是位于層次結(jié)構(gòu)根位置的View對(duì)象。(參見獨(dú)立的用戶界面文檔以獲取關(guān)于view及層次結(jié)構(gòu)的更多信息。)
2 Service
service沒有可視化的用戶界面,而是在一段時(shí)間內(nèi)在后臺(tái)運(yùn)行。例如,一個(gè)service可以在用戶做其它事情的時(shí)候在后臺(tái)播放背景音樂、從網(wǎng)絡(luò)上獲取數(shù)據(jù)或者計(jì)算一些東西并提供給需要這個(gè)運(yùn)算結(jié)果的activity使用。每個(gè)service都繼承自Service基類。
一個(gè)媒體播放器播放播放列表中的曲目是一個(gè)不錯(cuò)的例子。播放器應(yīng)用程序可能有一個(gè)或多個(gè)activity來給用戶選擇歌曲并進(jìn)行播放。然而,音樂播放這個(gè)任務(wù)本身丌應(yīng)該由任何activity來處理,因?yàn)橛脩羝谕词乖谒麄冸x開播放器應(yīng)用程序而開始做別的事情時(shí),音樂仍在繼續(xù)播放。為達(dá)到這個(gè)目的,媒體播放器activity可以啟動(dòng)一個(gè)運(yùn)行于后臺(tái)的service。系統(tǒng)將在這個(gè)activity不再顯示于屏幕乀后,仍維持音樂播放service的運(yùn)行。
連接至(綁定到)一個(gè)正在運(yùn)行的service(如果service沒有運(yùn)行,則啟動(dòng)之)是可能的。連接之后,你可以通過那個(gè)service暴露出來的接口不service進(jìn)行通訊。對(duì)于音樂service來說,這個(gè)接口可以允許用戶暫停、回退、停止以及重新開始播放。
如同activity和其它組件一樣,service運(yùn)行于應(yīng)用程序進(jìn)程的主線程內(nèi)。所以它不會(huì)對(duì)其它組件或用戶界面有任何妨礙,它們一般會(huì)派生一個(gè)新線程來執(zhí)行一些時(shí)間消耗型任務(wù)(比如音樂回放)。參見稍后的進(jìn)程和線程。
3 Broadcast receiver
broadcast receiver是一個(gè)與注于接收廣播通知信息,并做出相應(yīng)處理的組件。許多廣播是由系統(tǒng)代碼產(chǎn)生的——例如,通知時(shí)區(qū)改變、電池電量低、拍攝了一張照片或者用戶改變了語言選項(xiàng)。應(yīng)用程序也可以發(fā)起廣播——例如,通知其它應(yīng)用程序一些數(shù)據(jù)已經(jīng)下載到設(shè)備上并處于可用狀態(tài)。
一個(gè)應(yīng)用程序可以擁有任意數(shù)量的broadcast receiver,以對(duì)所有它認(rèn)為重要的通知信息予以響應(yīng)。所有的receiver均繼承自BroadcastReceiver基類。
broadcast receiver沒有用戶界面。然而,它們可以啟動(dòng)一個(gè)activity來響應(yīng)它們收到的信息,或者也可以使用NotificationManager來通知用戶。通知可以用多種方式來吸引用戶的注意力──閃動(dòng)背光燈、震動(dòng)設(shè)備、播放聲音等等。通知一般是在狀態(tài)欄上放一個(gè)持麗的圖標(biāo),用戶可以打開它并獲取消息。
4 Content provider
content provider將一些特定的應(yīng)用程序數(shù)據(jù)供給其它應(yīng)用程序使用。數(shù)據(jù)可以存儲(chǔ)于文件系統(tǒng)、SQLite數(shù)據(jù)庫或其它有意丿的方式。content provider繼承于ContentProvider 基類,實(shí)現(xiàn)了一套使得其他應(yīng)用程序能夠檢索和存儲(chǔ)它所管理的類型數(shù)據(jù)的標(biāo)準(zhǔn)方法。然而,應(yīng)用程序并不直接調(diào)用返些方法,而是使用一個(gè) ContentResolver 對(duì)象,調(diào)用它的方法作為替代。ContentResolver可以與任何content provider進(jìn)行會(huì)話;與其合作對(duì)任何相關(guān)的進(jìn)程間通訊進(jìn)行管理。
參閱獨(dú)立的Content Providers文檔以獲得更多關(guān)于使用content provider的信息。
每當(dāng)出現(xiàn)一個(gè)需要被特定組件處理的請(qǐng)求時(shí),Android會(huì)確保那個(gè)組件的應(yīng)用程序進(jìn)程處于運(yùn)行狀態(tài),必要時(shí)會(huì)啟動(dòng)它,并確保那個(gè)組件的一個(gè)合適的實(shí)例可用,必要時(shí)會(huì)創(chuàng)建那個(gè)實(shí)例。
1.1激活組件:intent
當(dāng)接收到ContentResolver發(fā)出的請(qǐng)求后,content provider被激活。而其它三種組件——activity、service和broadcast receiver,被一種叫做intent的異步消息所激活。intent是一個(gè)保存著消息內(nèi)容的Intent對(duì)象。對(duì)于activity和service來說,它指明了所請(qǐng)求的操作名稱,并指定了用來操作的數(shù)據(jù)的URI和其它一些信息。例如,它可以承載一個(gè)對(duì)一個(gè)activity的請(qǐng)求,讓它為用戶顯示一張圖片,或者讓用戶編輯一些文本。而對(duì)于broadcast receiver來說,Intent對(duì)象指明了所通報(bào)的操作。例如,它可以對(duì)所有感興趣的對(duì)象通報(bào)照相按鈕被按下。
對(duì)于每種組件來說,激活的方法是不同的: 通過傳遞一IntentContext.startActivity()Activity.startActivityForResult(以啟動(dòng)(或指定新工作給)一個(gè)activity。相應(yīng)的activity可以通過調(diào)用自身的 getIntent() 方法來查看最刜激活它的intent。Android通過調(diào)用activity的onNewIntent()方法來傳遞給它隨后的任何intent。
  一個(gè)activity經(jīng)常啟動(dòng)另一個(gè)activity。如果它期望它所啟動(dòng)的那個(gè)activity迒回一個(gè)結(jié)果,它會(huì)調(diào)用startActivityForResult()而不是startActivity()。例如,如果它啟動(dòng)了另外一個(gè)activity以使用戶挑選一張照片,它也許想知道哪張照片被選中了。其結(jié)果將會(huì)被封裝在一個(gè)Intent對(duì)象中,并傳遞給發(fā)出調(diào)用的activity的onActivityResult() 方法。
2 通過傳遞一個(gè)Intent對(duì)象至Context.startService()以啟動(dòng)一個(gè)service(或向正在運(yùn)行的service給出一個(gè)新的指令)。Android調(diào)用此service的onStart()方法并將Intent對(duì)象傳遞給它。
與此類似,一個(gè)intent可以被傳遞給 Context.bindService()以建立一個(gè)處于調(diào)用組件和目標(biāo)service乀間的活動(dòng)連接。此service會(huì)通過onBind() 方法的調(diào)用來獲取此Intent對(duì)象(如果此service尚未運(yùn)行,bindService()會(huì)先啟動(dòng)它)。例如,一個(gè)activity可以建立一個(gè)不前述的音樂回放service的連接,這樣它就可以提供給用戶一些途徑(用戶界面)來控制回放。這個(gè)activity可以調(diào)用 bindService()來建立此連接,然后調(diào)用service中定之的方法來控制回放。
稍后的遠(yuǎn)程方法調(diào)用一節(jié)有關(guān)于如何綁定至一個(gè)service的更多細(xì)節(jié)。
3 應(yīng)用程序可以通過傳遞一個(gè)Intent對(duì)象至 Context.sendBroadcast() ,Context. sendOrderedBroadcast(), 以及Context.sendStickyBroadcast()和其它類似方法來發(fā)起一個(gè)廣播。Android會(huì)調(diào)用所有對(duì)此廣播有興趣的broadcast receiver的 onReceive()方法,將此intent傳遞給它們。
1.2 關(guān)閉組件
content provider僅在響應(yīng)來自ContentResolver的請(qǐng)求時(shí)處于活動(dòng)狀態(tài)。而broadcast receiver僅在響應(yīng)一條廣播信息的時(shí)候處于活動(dòng)狀態(tài)。所以沒有必要去顯式地關(guān)閉返些組件。
而activity則不同,它提供了用戶界面。只要會(huì)話依然持續(xù),無論會(huì)話過程有無空閑,activity同用戶進(jìn)行長時(shí)間會(huì)話且可能一直處于活動(dòng)狀態(tài)。與此相似,service也會(huì)在很長一段時(shí)間內(nèi)保持運(yùn)行。所以Android為關(guān)閉activity和service提供了一系列有序的方法。
activity可以通過調(diào)用自身的finish()方法來關(guān)閉。一個(gè)activity可以通過調(diào)用finishActivity()方法來關(guān)閉另外一個(gè)activity(它用startActivityForResult()啟動(dòng)的)。
service可以通過調(diào)用自身的stopSelf()方法,或調(diào)用 Context.stopService()來停止。
系統(tǒng)也會(huì)在組件不再被使用的時(shí)候戒者當(dāng)Android必須為更多的活動(dòng)組件回收內(nèi)存時(shí)關(guān)閉它。稍后的組件的生命周期一節(jié),將對(duì)返種可能性及結(jié)果進(jìn)行更詳細(xì)的認(rèn)論。
1.3 manifest文件
當(dāng)Android啟動(dòng)一個(gè)應(yīng)用程序組件之前,它必須知道那個(gè)組件是存在的。因此,應(yīng)用程序會(huì)在一個(gè)被打包到Android包中的manifest文件中聲明它的組件,.apk文件還將涵括應(yīng)用程序的代碼、文件以及其它資源。
manifest文件是一個(gè)結(jié)構(gòu)化的XML文件,而且對(duì)于所有應(yīng)用程序,文件名總是AndroidManifest.xml。除了聲明此應(yīng)用程序各個(gè)組件,它會(huì)做很多其他工作,比如指明應(yīng)用程序所需鏈接到的庫的名稱(除了默認(rèn)的Android庫乀外)以及標(biāo)出應(yīng)用程序期望獲得的各種權(quán)限。
但manifest文件最重要的任務(wù)是向Android報(bào)告此應(yīng)用程序的各個(gè)組件。丼例說明,一個(gè)activity可能聲明如下:
<activity>元素的name屬性指定了實(shí)現(xiàn)此activity的 Activity子類。icon和label屬性指向包含展示給用戶的此activity的圖標(biāo)和標(biāo)簽的資源文件。
其它組件也以類似的方法聲明——<service> 元素用于聲明service, <receiver> 元素用于聲明broadcast receiver,而 <provider> 元素用于聲明content provider。未在manifest文件中進(jìn)行聲明的activity、service以及content provider將不為系統(tǒng)所見,從而也就永不會(huì)被運(yùn)行。然而,broadcast receiver既可以在manifest文件中聲明,也可以在代碼中動(dòng)態(tài)創(chuàng)建(為BroadcastReceiver對(duì)象),并以調(diào)用Context.registerReceiver()的方式注冊(cè)至系統(tǒng)。
1.4 Intent過濾器
一個(gè)Intent對(duì)象可以顯式地指定一個(gè)目標(biāo)組件。如果進(jìn)行了返種指定,Android會(huì)找到這個(gè)組件(基于manifest文件中的聲明)并激活它。但如果intent沒有顯式地指定一個(gè)目標(biāo),Android就必須找到最合適的組件來響應(yīng)此intent。這個(gè)過程是通過比較Intent對(duì)象和所有潛在目標(biāo)的intent過濾器完成的。組件的intent過濾器會(huì)通知Android它所能處理的intent類型。如同組件的其它必要信息一樣,這些intent過濾器是在manifest文件中進(jìn)行聲明的。返里有一個(gè)對(duì)先前例子的擴(kuò)展,其中加入了針對(duì)activity的兩個(gè)intent過濾器:
示例中的第一個(gè)過濾器——action“android.intent.action.MAIN”和category“android.intent.category.LAUNCHER”的組合——是常見的一個(gè)。它標(biāo)明了此activity應(yīng)該在應(yīng)用程序啟動(dòng)器中顯示,就是用戶在屏幕上看到的此設(shè)備上可供啟動(dòng)的應(yīng)用程序的列表。換句話說,這個(gè)activity是應(yīng)用程序的入口點(diǎn),是用戶在啟動(dòng)器中選擇運(yùn)行這個(gè)應(yīng)用程序后所見到的第一個(gè)activity。
第二個(gè)過濾器聲明了此activity在一種特定類型的數(shù)據(jù)上可以執(zhí)行的操作。
一個(gè)組件可以擁有任意數(shù)量的intent過濾器,每個(gè)都聲明了一套不同的功能。如果組件沒有包含任何過濾器,它只能被顯式地指明作為目標(biāo)組件的intent激活。
對(duì)于在代碼中創(chuàng)建并注冊(cè)的broadcast receiver來說,intent過濾器將被直接實(shí)例化IntentFilter為對(duì)象。其它所有的過濾器都在manifest文件中設(shè)置。

四、源程序

(一)單片機(jī)程序

單片機(jī)源程序如下:


  1. #include<reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. uchar a;

  5. void init()
  6.    {
  7.      TMOD=0X20;   //設(shè)置定時(shí)器1為方式2
  8.      TH1=0xfd ;   
  9.      TL1=0xfd ;   //裝初值
  10.      TR1=1;       //啟動(dòng)定時(shí)器1
  11.      REN=1;       // 使能接收

  12.      SM0=0;
  13.      SM1=1;       //設(shè)置串口為工作方式1

  14.      EA=1;       // 打開總中斷開關(guān)
  15.      ES=1;       // 打開串口中斷開關(guān)
  16.    }
  17.             
  18.     void main()
  19.     {
  20.         init();
  21.               while(1);
  22.      }

  23.    void ser() interrupt 4
  24.                  {
  25.                  ES=0;
  26.            RI=0;   //將接受中斷標(biāo)志位清0;
  27.                                     
  28.                  a=SBUF; //將接受到的數(shù)據(jù)賦值給a
  29.                                    
  30.         switch(a)
  31.     {
  32.       case 65:  P2=0X17;  break;   //  發(fā)送的是A  前進(jìn)指令
  33.       case 66:  P2=0X1B;  break;   //  發(fā)送的是B  右轉(zhuǎn)指令
  34.       case 67:  P2=0X27;  break;   //  發(fā)送的是C  左轉(zhuǎn)指令
  35. ……………………

  36. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:

基于安卓手機(jī)藍(lán)牙控制的智能小車設(shè)計(jì).doc (5.65 MB, 下載次數(shù): 139)





分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏7 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:404522 發(fā)表于 2019-1-23 23:12 | 只看該作者
寫的太好了,謝謝分享
回復(fù)

使用道具 舉報(bào)

板凳
ID:250717 發(fā)表于 2019-3-28 16:38 | 只看該作者
寫的太好了,謝謝分享
回復(fù)

使用道具 舉報(bào)

地板
ID:531672 發(fā)表于 2019-5-9 16:03 | 只看該作者
寫的太好了,謝謝分享
回復(fù)

使用道具 舉報(bào)

5#
ID:465853 發(fā)表于 2019-5-11 22:13 | 只看該作者

寫的太好了,謝謝分享
回復(fù)

使用道具 舉報(bào)

6#
ID:372154 發(fā)表于 2019-5-31 14:53 | 只看該作者


寫的太好了,謝謝分享
回復(fù)

使用道具 舉報(bào)

7#
ID:663813 發(fā)表于 2019-12-14 15:49 | 只看該作者
您好,請(qǐng)問有源代碼嗎?  能發(fā)一份嗎?1539733963@qq.com  謝謝!
回復(fù)

使用道具 舉報(bào)

8#
ID:683229 發(fā)表于 2020-1-7 21:26 | 只看該作者
寫的太好了,謝謝分享
回復(fù)

使用道具 舉報(bào)

9#
ID:1144421 發(fā)表于 2025-2-25 23:26 | 只看該作者
您好,這個(gè)寫的太棒了 請(qǐng)問有源代碼嗎?  能發(fā)一份嗎? 謝謝!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表