6.1.2 開發(fā)所需的軟件包 1、java JDK 6.0最好下載新版。它可從Sun公司的官網(wǎng)下載。
2、Android SDK 這是Android開發(fā)必需的。
3、Eclipse 3.5最好使用這個(gè)版。它可從Eclipse官網(wǎng)下載。
4、Eclipse所需的插件ADT-0.9.7它可從google網(wǎng)站上下載。
6.1.3 搭建Android開發(fā)環(huán)境準(zhǔn)備好開以上軟件包之后,我們便可以搭建Android的開發(fā)環(huán)境了。
第一步:安裝java JDK 6.0。
第二步:把下載好的Eclipse 3.5解壓。
第三步:Android SDK 安裝。
Android SDK可以通過SDK下載器自動(dòng)下載和配置,適合網(wǎng)絡(luò)好,下載速度快的情況下;也可以借助工具下載SDK文件,手工配置,適合網(wǎng)絡(luò)不是很好,下載速度慢的情況下。
第四步、Eclipse集成開發(fā)環(huán)境(IDE)搭建
1、打開Eclipse,選擇菜單:Help->Install New Software...
2、彈出“Available Software”對(duì)話框,點(diǎn)擊“Add...”按鈕
3、彈出“Add Repository”對(duì)話框。中Name中輸入ADT,然后點(diǎn)擊Archive把路徑設(shè)置到下載的ADT-0.9.7文件的位置,然后安裝。
4、安裝成功后,安裝提示重啟Eclipse,即完成整個(gè)安裝過程。
第五步:Android SDK 配置,即配制Android 虛擬設(shè)備,亦即嵌入式開發(fā)中常用的模擬器。
6.1.4 測(cè)試所配的開發(fā)環(huán)境- 新建項(xiàng)目:打開Eclipse,選擇File > New > Project > Android Project,便會(huì)打開新建項(xiàng)目界面,如圖6.1所示。
在Project name中輸入工程的名字,build target中選擇所用的平臺(tái),Application name為應(yīng)用程序的名稱,create activity為活動(dòng)類的名稱。
1.092.jpg (37.93 KB, 下載次數(shù): 176)
下載附件
2016-4-11 19:49 上傳
圖6.1 新建項(xiàng)目
2、配制運(yùn)行方式:點(diǎn)擊Run Configurations會(huì)出現(xiàn)配制運(yùn)行方式界面,如圖6.2所示。然后點(diǎn)擊Android application新建一個(gè)動(dòng)行方式,在右邊project中輸入要運(yùn)行的工程名稱。至此運(yùn)行方式配制完成。
1.093.jpg (17.77 KB, 下載次數(shù): 160)
下載附件
2016-4-11 19:49 上傳
圖6.2 配制運(yùn)行方式
3、運(yùn)擊會(huì)行,便會(huì)出下如下界面,如圖6.3:
1.094.jpg (18.39 KB, 下載次數(shù): 172)
下載附件
2016-4-11 19:49 上傳
圖6.3 運(yùn)行界面
至此,Android的開發(fā)環(huán)境已搭建成功。
6.2 Android藍(lán)牙通信設(shè)計(jì)藍(lán)牙是一種支持設(shè)備短距離通信(一般10m內(nèi))的無線電技術(shù)。能在包括移動(dòng)電話、PDA、無線耳機(jī)、筆記本電腦、相關(guān)外設(shè)等眾多設(shè)備之間進(jìn)行無線信息交換。利用“藍(lán)牙”技術(shù),能夠有效地簡(jiǎn)化移動(dòng)通信終端設(shè)備之間的通信,從而數(shù)據(jù)傳輸變得更加迅速高效,為無線通信拓寬道路。
本設(shè)計(jì)分為信號(hào)采集模塊和Android顯示終端,兩部分采用藍(lán)牙技術(shù)進(jìn)行無線通信。Android顯示終端實(shí)現(xiàn)波形的顯示和示波器參數(shù)的設(shè)置。
6.2.1 Android設(shè)備中藍(lán)牙模塊的使用- 使用藍(lán)牙的響應(yīng)權(quán)限
[html]view plaincopyprint
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
//直接打開系統(tǒng)的藍(lán)牙設(shè)置面板
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 0x1);
//直接打開藍(lán)牙
adapter.enable();
//打開本機(jī)的藍(lán)牙發(fā)現(xiàn)功能(默認(rèn)打開120秒,可以將時(shí)間最多延長(zhǎng)至300秒)
Intent discoveryIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//設(shè)置持續(xù)時(shí)間(最多300秒)
使用BluetoothAdapter的startDiscovery()方法來搜索藍(lán)牙設(shè)備。
startDiscovery()方法是一個(gè)異步方法,調(diào)用后會(huì)立即返回。該方法會(huì)進(jìn)行對(duì)其他藍(lán)牙設(shè)備的搜索,該過程會(huì)持續(xù)12秒。該方法調(diào)用后,搜索過程實(shí)際上是在一個(gè)System Service中進(jìn)行的,所以可以調(diào)用cancelDiscovery()方法來停止搜索(該方法可以在未執(zhí)行discovery請(qǐng)求時(shí)調(diào)用)。請(qǐng)求Discovery后,系統(tǒng)開始搜索藍(lán)牙設(shè)備,在這個(gè)過程中,系統(tǒng)會(huì)發(fā)送以下三個(gè)廣播:
ACTION_DISCOVERY_START:開始搜索
ACTION_DISCOVERY_FINISHED:搜索結(jié)束
ACTION_FOUND:找到設(shè)備
這個(gè)Intent中包含兩個(gè)extra fields:EXTRA_DEVICE和EXTRA_CLASS,分別包含BluetooDevice和BluetoothClass。我們可以自己注冊(cè)相應(yīng)的BroadcastReceiver來接收響應(yīng)的廣播,以便實(shí)現(xiàn)某些功能。
功能代碼如下:
// 創(chuàng)建一個(gè)接收ACTION_FOUND廣播的BroadcastReceiver
private final BroadcastReceivermReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// 發(fā)現(xiàn)設(shè)備
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// 從Intent中獲取設(shè)備對(duì)象
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 將設(shè)備名稱和地址放入array adapter,以便在ListView中顯示
mArrayAdapter.add(device.getName() + "" + device.getAddress());
}
}
};
// 注冊(cè)BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // 不要忘了之后解除綁定
6.2.2 藍(lán)牙數(shù)據(jù)通信如果打算建議兩個(gè)藍(lán)牙設(shè)備之間的連接,則必須實(shí)現(xiàn)服務(wù)器端與客戶端的機(jī)制。當(dāng)兩個(gè)設(shè)備在同一個(gè)RFCOMM channel下分別擁有一個(gè)連接的BluetoothSocket,這兩個(gè)設(shè)備才可以說是建立了連接。服務(wù)器設(shè)備與客戶端設(shè)備獲取BluetoothSocket的途徑是不同的。服務(wù)器設(shè)備是通過accepted一個(gè)incoming connection來獲取的,而客戶端設(shè)備則是通過打開一個(gè)到服務(wù)器的RFCOMM channel來獲取的。
通過調(diào)用BluetoothAdapter的listenUsingRfcommWithServiceRecord(String, UUID)方法來獲取BluetoothServerSocket,并調(diào)用BluetoothServerSocket的accept()方法監(jiān)聽連接請(qǐng)求,如果收到請(qǐng)求,則返回一個(gè)BluetoothSocket實(shí)例(此方法為block方法,應(yīng)置于新線程中)。如果不想在accept其他的連接,則調(diào)用BluetoothServerSocket的close()方法釋放資源。
通過搜索可以得到服務(wù)器端的BluetoothService,并通過調(diào)用BluetoothService的listen
UsingRfcommWithServiceRecord(String, UUID)方法獲取BluetoothSocket(該UUID應(yīng)該同于服務(wù)器端的UUID)。調(diào)用BluetoothSocket的connect()方法,如果UUID同服務(wù)器端的UUID匹配,并且連接被服務(wù)器端accept,則connect()方法返回。
3、數(shù)據(jù)通信
可以分別通過BluetoothSocket的getInputStream()和getOutputStream()兩種方法獲取InputStream和OutputStream,并使用read(bytes[])和write(bytes[])方法分別進(jìn)行讀寫操作。其中,read(bytes[])方法會(huì)一直block,直到從數(shù)據(jù)流中讀取到信息;而write(bytes[])方法并不是經(jīng)常的block,比如在另一設(shè)備沒有及時(shí)read或者中間緩沖區(qū)已滿的情況下,write方法會(huì)block。
6.3 Android上繪制波形利用SurfaceView類來實(shí)現(xiàn)波形的繪制。SurfaceView是視圖(View)的繼承類,這個(gè)視圖里內(nèi)嵌了一個(gè)專門用于繪制的Surface控件?梢酝ㄟ^SurfaceHolder接口訪問這個(gè)surface,getHolder()方法可以得到這個(gè)接口。surfaceview的核心在于提供了兩個(gè)線程:UI線程和渲染線程。SurfaceView的性質(zhì)決定了其比較適合一些場(chǎng)景:需要界面迅速更新、對(duì)幀率要求較高的情況。
6.3.1 SurfaceView的使用只要繼承SurfaceView類并實(shí)現(xiàn)SurfaceHolder.Callback接口就可以實(shí)現(xiàn)一個(gè)自定義的SurfaceView。SurfaceHolder.Callback在底層的Surface狀態(tài)發(fā)生變化的時(shí)候通知View,SurfaceHolder.Callback具有如下的接口:
1、surfaceCreated(SurfaceHolder holder):當(dāng)Surface第一次創(chuàng)建后會(huì)立即調(diào)用該函數(shù)。程序可以在該函數(shù)中做些和繪制界面相關(guān)的初始化工作,一般情況下都是在另外的線程來繪制界面,所以不要在這個(gè)函數(shù)中繪制Surface。
2、surfaceChanged(SurfaceHolder holder,int format,int width,int height):當(dāng)Surface的狀態(tài)(大小和格式)發(fā)生變化的時(shí)候會(huì)調(diào)用該函數(shù),在surfaceCreated調(diào)用后該函數(shù)至少會(huì)被調(diào)用一次。
3、surfaceDestroyed(SurfaceHolder holder):當(dāng)Surface被摧毀前會(huì)調(diào)用該函數(shù),該函數(shù)被調(diào)用后不能繼續(xù)使用Surface,一般在該函數(shù)中清理使用的資源。通過SurfaceView的getHolder()函數(shù)可以獲取SurfaceHolder對(duì)象,Surface就在SurfaceHolder對(duì)象內(nèi)。雖然Surface保存了當(dāng)前窗口的像素?cái)?shù)據(jù),但是在使用過程中是不直接和Surface打交道的,由SurfaceHolder的CanvaslockCanvas( )或Canvas的lockCanvas(Rect dirty)函數(shù)來獲取Canvas對(duì)象,通過在Canvas上繪制內(nèi)容來修改Surface中的數(shù)據(jù)。當(dāng)在Canvas中繪制完成后,調(diào)用函數(shù)unlockCanvasAndPost(Canvas canvas)來通知系統(tǒng)Surface已經(jīng)繪制完成,這樣系統(tǒng)會(huì)把繪制完的內(nèi)容顯示出來。為了充分利用不同平臺(tái)的資源,發(fā)揮平臺(tái)的最優(yōu)效果,可以通過SurfaceHolder的setType函數(shù)來設(shè)置繪制的類型,可接收如下的參數(shù):
SURFACE_TYPE_NORMAL:用RAM緩存原生數(shù)據(jù)的普通Surface。
SURFACE_TYPE_HARDWARE:適用于DMA(Direct memory access )引擎和硬件加速的Surface。
SURFACE_TYPE_GPU:適用于GPU加速的Surface。
SURFACE_TYPE_PUSH_BUFFERS:表明該Surface不包含原生數(shù)據(jù),Surface用到的數(shù)據(jù)由其他對(duì)象提供,在Camera圖像預(yù)覽中就使用該類型的Surface,有Camera負(fù)責(zé)提供給預(yù)覽Surface數(shù)據(jù),這樣圖像預(yù)覽會(huì)比較流暢。如果設(shè)置這種類型則就不能調(diào)用lockCanvas來獲取Canvas對(duì)象了。
6.3.2 繪制波形子程序該子程序的功能是,先繪制8*8的顯示網(wǎng)格,然后把接收到的波形數(shù)據(jù)在SurfaceView中顯示出來。功能程序如下:
void DrawWave(int length) {
Canvas canvas = sfh.lockCanvas(new Rect(0, 0, 480,480));//獲取畫布
Canvas.drawColor(Color.BLACK); //清除畫布
Paint mPaint = new Paint(); //獲取畫筆
mPaint.setColor(Color.GRAY); //設(shè)置畫筆為黃色
mPaint.setStrokeWidth(1); //設(shè)置畫筆粗細(xì)
oldY=0;
//繪制8*8的網(wǎng)格
for (int i = 0; i <= 8; i++) {// 繪畫橫線
canvas.drawLine(0, oldY, 479, oldY, mPaint);
oldY = oldY+60;}
oldX=0;
for (int i = 0; i <= 8; i++) {// 繪畫縱線
canvas.drawLine(oldX, 0, oldX, 479, mPaint);
oldX = oldX+60;}
//繪制波形
mPaint.setColor(Color.YELLOW);// 畫筆設(shè)置為綠色
for (int x = 0; x < length; x++) {
y = data_osc[ i];//讀取y軸數(shù)值,波形數(shù)據(jù)保存在數(shù)組ata_osc[]中
canvas.drawPoint(x, y, mPaint);//描點(diǎn)
}
sfh.unlockCanvasAndPost(canvas);//解鎖畫布,提交畫好的圖像
}
結(jié) 論經(jīng)過三個(gè)月的努力,終于完成了本畢業(yè)設(shè)計(jì)。總結(jié)這三個(gè)月來的工作,主要有以下幾個(gè)方面:
1、綜述了現(xiàn)階段數(shù)字存儲(chǔ)示波器技術(shù)及產(chǎn)品的國內(nèi)外發(fā)展?fàn)顩r,對(duì)數(shù)字存儲(chǔ)示波器的原理、工作方式、顯示方式等的基本概念及技術(shù)發(fā)展進(jìn)行了介紹。
2、針對(duì)設(shè)計(jì)的任務(wù)和要求,確定了存儲(chǔ)示波器波形采樣和數(shù)據(jù)處理及波形重組的硬件和軟件方案。
3、對(duì)整機(jī)各部分關(guān)鍵電路進(jìn)行相關(guān)理論分析、計(jì)算和設(shè)計(jì)。
4、本系統(tǒng)由單片機(jī)主控,高速A/D轉(zhuǎn)換器ADS830進(jìn)行模數(shù)轉(zhuǎn)換,用FIFO緩存芯片IDT7203來實(shí)現(xiàn)波形的存儲(chǔ)。通過軟件對(duì)轉(zhuǎn)換后的數(shù)字信號(hào)進(jìn)行處理,并通過藍(lán)牙把波形數(shù)據(jù)發(fā)送到Android設(shè)備上進(jìn)行顯示。
5、完成了作品的制作與調(diào)試;論述了儀器的測(cè)試方法,完成數(shù)據(jù)測(cè)試及測(cè)試結(jié)果分析。
采用Android設(shè)備作為顯示平臺(tái),是本設(shè)計(jì)最大的一個(gè)特點(diǎn)。本設(shè)計(jì)的基本思路是,由單片機(jī)對(duì)ADC采樣到的數(shù)據(jù)進(jìn)行處理,再通過藍(lán)牙把波形數(shù)據(jù)發(fā)送到Android設(shè)備上進(jìn)行顯示。同時(shí)由于Android設(shè)備都采用觸摸屏,因此示波器的參數(shù)可以很方便的通過觸摸屏進(jìn)行設(shè)置。本設(shè)計(jì)采用Android設(shè)備取代液晶屏,并使用藍(lán)牙進(jìn)行數(shù)據(jù)傳輸,充分利用了Android設(shè)備的硬件資源。其優(yōu)點(diǎn)是降低了系統(tǒng)開發(fā)成本,并大大減小了系統(tǒng)硬件體積,完全實(shí)現(xiàn)了本設(shè)計(jì)小巧便攜的設(shè)計(jì)宗旨。
本系統(tǒng)的數(shù)據(jù)采集系統(tǒng)、數(shù)據(jù)處理系統(tǒng)和波形顯示系統(tǒng)等模塊都經(jīng)過了軟硬件的調(diào)試。雖然整個(gè)系統(tǒng)的實(shí)現(xiàn)方案基本完成,但是還有一些不夠理想的地方,仍然有不少的工作需要繼續(xù)。比如需要進(jìn)一步改善測(cè)量精度、模擬帶寬以及系統(tǒng)噪聲等性能;添加等效采樣、波形回調(diào)以及數(shù)據(jù)導(dǎo)出等功能。
參 考 文 獻(xiàn)
[1] 張永瑞. 電子測(cè)量技術(shù)基礎(chǔ)[M] . 西安:西安電子科技大學(xué)出版社,2006:131-133.
[2] 朱明強(qiáng). 基于單片機(jī)及CPLD的數(shù)字存儲(chǔ)示波器的研究與設(shè)計(jì)[D] . 北京:北京交通大學(xué),2008.
[3] 王彥斌. 數(shù)字存儲(chǔ)示波器中模擬通道設(shè)計(jì)[D] . 成都:電子科技大學(xué),2008.
[4] 馮靜亞,于強(qiáng),呂朝暉,羅福山. 虛擬示波器的軟件設(shè)計(jì)與應(yīng)用[J] . 計(jì)算機(jī)工程與設(shè)計(jì),2007,28(1):211-273.
[5] 張虹. 泰克公司推出可分析帶寬達(dá)20GHz信號(hào)的Signal Vu軟件[J] . 中國無線電,2008,9(7):23-25.
[6] 趙茂泰. 簡(jiǎn)易數(shù)字存儲(chǔ)示波器評(píng)述[J] . 電子世界,2002,5(11):40-42.
[7] 徐俊毅. 力科推出帶寬可達(dá)30GHz的WaveMaster8Zi系列示波器[J] . 電子與電腦,2009,5(13):53-56.
[8] 蒙玉寶. 40Gsps隨機(jī)取樣數(shù)字示波器關(guān)鍵技術(shù)預(yù)先研究[D] . 成都:電子科技大學(xué),2003.
[9] 楊豐盛. Android應(yīng)用開發(fā)揭秘[M] . 北京:機(jī)械工業(yè)出版社,2009:15-16.
[10] 陳景波,楊放,姚定江. 基于CompuScope 82G型高速數(shù)據(jù)采集卡的虛擬示波器設(shè)計(jì)[J] . 國外電子元器件,2006,11(2):60-62.
[11] H.Troy Nagle,D.Carroll,J.David Irwin . DIGITAL LOGIC CIRCUIT ANALYSIS & DESIGN[M] . 北京:清華大學(xué)出版,2009:57-71.
[12] V.V.Panasyuk. Electronic oscillograph unit for recording failure diagrams in the impact testing of metals[J] . Soviet Materials Science,2001,9(5):10-12.
[13] 劉楊斌,劉其峰,華慧. 基于AT89S52單片機(jī)的簡(jiǎn)易數(shù)字示波器設(shè)計(jì)[J] . 現(xiàn)代電子技術(shù),2011,14(14):17-18.
[14] 賈春霞,張洪艷. 數(shù)字存儲(chǔ)示波器現(xiàn)狀初探[J] . 儀器儀表用戶,2004,8(15):25-26.
[15] 張根柱,陳勇鋼. 數(shù)字存儲(chǔ)示波器[J] . 現(xiàn)代技術(shù)開發(fā),1999,5(12):49-50.
[16] J. Molenaar,R. Voorhorst. Study on Remote Control Techniques to the Digital Storage Oscilloscope[J] . Energy Procedia,2012,16(9):34-35.
[17] 劉巖. 數(shù)字示波器的設(shè)計(jì)[J] . 電腦知識(shí)與技術(shù),2008,12(20):21-22.
[18] R. P. Patterson. Design and Implementation of Multifunctional Virtual Oscilloscope Using USB Data-Acquisition Card[J] . Procedia Engineering,2012,10(25):40-42.
[19] W. A. Grind. Patent Application Titled "Oscilloscope with Internally Generated Mixed Signal Oscilloscope Demo Mode Stimulus, and Integrated Demonstration" Under Review[J] . Journal of Engineering,2012,9(17):7-8.
致 謝在這里要衷心感謝我的指導(dǎo)老師蘇成悅教授的悉心指導(dǎo)和多方關(guān)懷。蘇老師思維敏銳,視野開闊,創(chuàng)新性強(qiáng)。他淵博的學(xué)識(shí),嚴(yán)謹(jǐn)?shù)闹螌W(xué)作風(fēng),執(zhí)著的敬業(yè)精神都深深地影響著我。我深深感受到他對(duì)研究的精益求精,對(duì)學(xué)生的鼓勵(lì)和愛護(hù)。他對(duì)工作和生活的態(tài)度將是我一生學(xué)習(xí)的榜樣。
此外,還需要感謝我身邊的同學(xué)們。在設(shè)計(jì)過程中碰到的問題,我都會(huì)找同學(xué)一起來討論解決。同學(xué)們都很熱情、很積極的參與到討論中,而且大部分問題在討論之后都得到了解決。除了學(xué)習(xí)之外,在生活上同學(xué)們對(duì)我的幫助也是非常大的。在此,我衷心感謝各位親愛的同學(xué)們。
附錄 A 實(shí)物圖
1.095.jpg (28.79 KB, 下載次數(shù): 131)
下載附件
2016-4-11 19:49 上傳
圖A1 信號(hào)采集模塊
1.096.jpg (48.52 KB, 下載次數(shù): 161)
下載附件
2016-4-11 19:49 上傳
圖A2 系統(tǒng)測(cè)試圖
附錄 B 系統(tǒng)主程序設(shè)計(jì)源碼
#include "STM32Lib\stm32f10x.h"
#include "hal.h"
extern void SetLevel(u8 pulse);
extern void Adc1_Init(u8 ADC_CH_x,u8 ADC_CH_SMP);
extern u16 Get_Adc(u8 ADC_CH_x);
u16 data_test_16;
u8 data_test_8;
u8 Data_osc[320]; //波形數(shù)據(jù)
u8 Data_osc_full=0;
u8 Data_set[10];
//延遲函數(shù)
void Delay(u16 speed)
{
u16 i;
while(speed!=0)
{
speed--;
for(i=0;i<400;i++);
}
}
//設(shè)置水平掃描速度
void shuiping(u8 sp)
{
if(sp >= 12)
sp=12;
if(sp <= 1)
sp=1;
//設(shè)置不同采樣速率
switch(sp)
{
case 1:TIM1->PSC=0; break;
case 2:TIM1->PSC=1; break;
case 3:TIM1->PSC=3; break;
case 4:TIM1->PSC=9; break;
case 5:TIM1->PSC=19; break;
case 6:TIM1->PSC=39; break;
case 7:TIM1->PSC=99; break;
case 8:TIM1->PSC=199; break;
case 9:TIM1->PSC=399; break;
case 10:TIM1->PSC=999; break;
case 11:TIM1->PSC=1999; break;
case 12:TIM1->PSC=3999; break;
default :break;
}
}
//設(shè)置水平靈敏度
void SetAGC(u16 pulse)
{
if(pulse >= 3)
pulse=3;
if(pulse <= 1)
pulse=1;
//設(shè)置不同的增益
switch(pulse)
{
case 1: TIM4->CCR1=255;break;
case 2: TIM4->CCR1=195;break;
case 3: TIM4->CCR1=153;break;
}
}
int main(void)
{
u16 i_osc=0;
u16 i_start=0;
ChipHalInit(); //片內(nèi)硬件初始化
ChipOutHalInit(); //片外硬件初始化
SetLevel(128); //初始化垂直基線
SetAGC(2); //初始化垂直靈敏度
shuiping(6); //初始化水平靈敏度
while(1)
{
if(Data_osc_full==1)
{
Data_osc_full=0;
while(!(Data_osc[i_start]<=160&& Data_osc[i_start+1]>=160))
{
i_start++;
if(i_start>=150)
break;
}
if(i_start < 150)
{
for( i_osc=0; i_osc<160; i_osc++)
{
USART2_Putc(Data_osc[i_osc + i_start]);
}
}
Delay(500); //延時(shí),等待Android系統(tǒng)處理完畢數(shù)據(jù)
TIM1->CR1 |= 0x0001; //開啟定時(shí)器TIM1
}
}
}
附錄 C Android藍(lán)牙服務(wù)程序設(shè)計(jì)源碼
package com.test.BTClient;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
public class DeviceListActivity extends Activity {
// 調(diào)試用
private static final String TAG = "DeviceListActivity";
private static final boolean D = true;
// 返回時(shí)數(shù)據(jù)標(biāo)簽
public static String EXTRA_DEVICE_ADDRESS = "設(shè)備地址";
// 成員域
private BluetoothAdapter mBtAdapter;
private ArrayAdapter mPairedDevicesArrayAdapter;
private ArrayAdapter mNewDevicesArrayAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 創(chuàng)建并顯示窗口,并設(shè)置窗口顯示模式為窗口方式
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.device_list);
// 設(shè)定默認(rèn)返回值為取消
setResult(Activity.RESULT_CANCELED);
// 設(shè)定掃描按鍵響應(yīng)
Button scanButton = (Button) findViewById(R.id.button_scan);
scanButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
doDiscovery();
v.setVisibility(View.GONE);
}
});
// 初使化設(shè)備存儲(chǔ)數(shù)組
mPairedDevicesArrayAdapter = new ArrayAdapter(this,
R.layout.device_name);
mNewDevicesArrayAdapter = new ArrayAdapter(this,
R.layout.device_name);
// 設(shè)置已配隊(duì)設(shè)備列表
ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
pairedListView.setAdapter(mPairedDevicesArrayAdapter);
pairedListView.setOnItemClickListener(mDeviceClickListener);
// 設(shè)置新查找設(shè)備列表
ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
newDevicesListView.setOnItemClickListener(mDeviceClickListener);
// 注冊(cè)接收查找到設(shè)備action接收器
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
// 注冊(cè)查找結(jié)束action接收器
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
// 得到本地藍(lán)牙句柄
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
}
@Override
protected void onDestroy() {
super.onDestroy();
// 關(guān)閉服務(wù)查找
if (mBtAdapter != null) {
mBtAdapter.cancelDiscovery();
}
// 注銷action接收器
this.unregisterReceiver(mReceiver);
}
public void OnCancel(View v){
finish();
}
//開始服務(wù)和設(shè)備查找
private void doDiscovery() {
if (D) Log.d(TAG, "doDiscovery()");
// 在窗口顯示查找中信息
setProgressBarIndeterminateVisibility(true);
setTitle("查找設(shè)備中...");
// 顯示其它設(shè)備(未配對(duì)設(shè)備)列表
findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
// 關(guān)閉再進(jìn)行的服務(wù)查找
if (mBtAdapter.isDiscovering()) {
mBtAdapter.cancelDiscovery();
}
//并重新開始
mBtAdapter.startDiscovery();
}
// 選擇設(shè)備響應(yīng)函數(shù)
private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
public void onItemClick(AdapterView av, View v, int arg2, long arg3) {
// 準(zhǔn)備連接設(shè)備,關(guān)閉服務(wù)查找
mBtAdapter.cancelDiscovery();
// 得到mac地址
String info = ((TextView) v).getText().toString();
String address = info.substring(info.length() - 17);
// 設(shè)置返回?cái)?shù)據(jù)
Intent intent = new Intent();
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
// 設(shè)置返回值并結(jié)束程序
setResult(Activity.RESULT_OK, intent);
finish();
}
};
// 查找到設(shè)備和搜索完成action監(jiān)聽器
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// 查找到設(shè)備action
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// 得到藍(lán)牙設(shè)備
BluetoothDevice device =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 如果是已配對(duì)的則略過,其余的在添加到列表中進(jìn)行顯示
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
mNewDevicesArrayAdapter.add(device.getName() + "" +
device.getAddress());
}else{ //添加到已配對(duì)設(shè)備列表
mPairedDevicesArrayAdapter.add(device.getName() + "" +
device.getAddress());
}
// 搜索完成action
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
setProgressBarIndeterminateVisibility(false);
setTitle("選擇要連接的設(shè)備");
if (mNewDevicesArrayAdapter.getCount() == 0) {
String noDevices = "沒有找到新設(shè)備";
mNewDevicesArrayAdapter.add(noDevices);
}
}
}
};
}