這是我大三時的電子課程設計,做的聲音定位系統,課設具體要求如下:
附件里包含了,整個系統的源碼,設計報告(含原理圖)
本次設計采用 STC89C52RC 單片機進行運算處理和驅動 LCD12864 液晶顯示
屏顯示定位結果,即利用單片機內部定時器 0 計時,由外部中斷 0、外部中斷 1和定時器 1觸發,檢測接收信號的下降沿,通過這種方式計算聲音傳播后,不同模塊接收到信號的時間差,通過時間差計算出聲源信號到接收模塊距離,然后由單片機編程計算出聲源的位置坐標,最終顯示在液晶屏上。 STC89C52RC 單片機小系統電路和 LCD12864驅動電路如下圖所示:
五、算法與程序設計
5.1數據處理原理:
本算法基于時間差算出未知點的坐標點。從理論上分析,只需三個已知點就可以對聲音源進行定位,我們首先先將問題簡化為二維平面內對聲音源進行定位。 如下圖所示,在一個平面內分布有三個傳感器A、 B和C坐標分別為(0,350)、(0,0)、(500,0)。當平面內某處 S(x,y)發出聲音時,3 個傳感器將先后接收到信號,設信號到達A,B的時間差為 t1,到達B,C的時間差為 t2,則有:
六、測試方案
6.1 主要的測試儀器、儀表
本次主要使用的測試儀器與儀表有,函數信號發生器、示波器與數字萬用表。
6.2 測試方法
在硬件測試中,按鍵發聲模塊通過示波器測試電路輸出波形,調節電位器改變電阻值來調節觸發時間,保證發出的聲響持續時間為 1s;另外使用數字萬用表測量按鍵發聲模塊的功耗。聲音接收模塊通過數字萬用表,測量當發聲模塊距接收模塊不同距離時,比較器輸出電壓,直至調節電位器,改變比較器靈敏度使輸出電壓在要求距離內能受到信號,并以下降沿觸發單片機。聲響模塊和接收模塊都可以使用函數發生器和示波器來檢測電路的連接是否正常。
在軟件測試中,我們組軟件調試的中心思想是分模塊調試。先將程序分為三個接受模塊,算法模塊,顯示模塊,我們在分塊調試時,將各個模塊的輸出都顯示出來以便于觀察各模塊是否正確。運用這種方法,可以將軟件上的錯誤精確定位到某一個環節,大大提高了調試的效率。以下是具體方法:
1、將程序中的標志位signalA,signalB,signalC 通過LCD屏幕顯示出來,以方便
觀察是否所有傳感器都收到了信號。
2、將各信號間的時間差通過 LCD 屏幕顯示出來,以方便觀察各傳感器的響應速度以及接受信號的先后順序是否與實際一致。
3、在接入傳感器前,先用另一片單片機模仿傳感器發出的信號,并通過程序設置時間差等參數,用于檢查算法是否正確。
七、系統調試
7.1 按鍵發聲模塊
測試輸出電流(通過測量蜂鳴器串聯的 1Ω的電阻得到電流值),從圖中可知
為0.042A:
7.2 聲音接收模塊
當聲響模塊離接收模塊距離較近時,接收模塊輸出電壓達到 3.6V 左右。
當聲響模塊離接收模塊較遠時(但坐標仍屬于坐標紙的范圍),接收模塊輸出電壓將會變小。這個時候就需要調節電位器,改變電阻值以減小比較器 LM358 輸入端參考電壓的值。
7.3 LCD 液晶顯示模塊
進行測試時,LCD12864 液晶顯示模塊除了顯示坐標 X 與 Y的值外,還會顯示A、B、C 三個聲音接收模塊的中斷觸發標志值(如下圖顯示屏中第一行所顯示的內容,其中顯示值為 0 表示未觸發,為 1 則表示已觸發),以及 A、B 和 C 三個聲音接收模塊依次收到信號時的計時時刻(其中從右到左依次為0us,65us和68us,此時模塊 C 最先收到聲音信號) ,這樣方便系統調試。 下圖坐標 X 與Y值在誤差范圍內,滿足測量要求。
從表 8.2 可以看出,當電位器阻值較小時即比較器輸入端參考電壓接近 0 時更易收到信號,但實際上這樣做也更容易受到干擾。接收模塊 C 相較于A、B 模塊了,由于焊接工藝的問題,靈敏度較低。合理調節電位器阻值之后,三個模塊最終都能受到信號,滿足設計要求。
8.3 聲源實測坐標記錄表
對處于不同坐標的聲源進行了實際測量,最終得到了以下的一些實測數據如下
從表中可以看出,除個別點外,坐標紙的四個方向邊緣區域以及中間區域共取了5個點,其實測坐標基本滿足設計要求。而個別點的誤差可能是由于接收模塊放置的位置不準確或聲源放置地不準確而產生。
九、總結
本次設計以 STC89C52 為核心部件,利用了聲音檢測與辨識技術,利用嚴密的數學方法實現和確定了聲源的準確定位。在系統設計過程中,力求硬件電路簡單,降低硬件成本,節約功耗。
在這次課程設計中,我們遇到了許多問題,這些問題我們之前從未遇到過,
但最終我們都找到了解決這些問題的辦法,這對我們來說是一次很好的鍛煉。在程序設計與軟件調試的過程之中,由于我們同時使用了 STC89C52 單片機中的四個中斷進行控制處理,對于單片機各個中斷的優先級與觸發的考慮更為復雜,但只要結合函數信號發生器模擬聲音信號觸發單片機得到調試結果,并且根據這些結果不斷改正程序,就能得到最優的程序設計。另外在程序設計過程,由于子程序中數據處理十分重要,我們查閱了許多的資料,對于 C51中的數據類型以及常用的庫函數也更加的熟悉。 在硬件調試過程中,出現了聲音接收模塊電路不穩定,易受到干擾,以及放大電路難以調試的問題。對于接下來課程設計之后,我們也會考慮重新設計相關電路,例如采用雙比較器電路進行比較放大,來提高電路的性能。
主程序源碼
- #include<reg52.h>
- #include<stdio.h>
- #include "delay.h"
- #include "lcd.h"
- #include<math.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define BOOL bit
- #define BYTE unsigned char
- #define WORD unsigned int
- uchar signalA,signalB,signalC;
- uchar wolsignalA,wolsignalB,wolsignalC;
- uchar wolCount,obv;
- unsigned int posX,posY; //坐標取值
- code unsigned char byValidShow[] = {" V值: "};
- code unsigned char DispX[] = {" X軸: "};
- code unsigned char DispY[] = {" Y軸: "};
- void Init_Show() //LCD初始化顯示子程序
- {
- Delay400Ms();
- LCDInit();
- LCDClear();
- Delay5Ms();
- LCDClear();
- //DisplayListChar(0,1,byValidShow);
- DisplayListChar(0,2,DispX);
- DisplayListChar(0,3,DispY);
- Delay5Ms();
- }
- void Init_isr() //中斷初始化設置子程序
- {
- EA = 0;
- TMOD = 0x62;
- /*外部中斷0*/
- IT0 = 1; EX0 = 1;
- /*外部中斷1*/
- IT1 = 1; EX1 = 1;
- /* 計數器 0*/
- TH1 = 0xFF; TL1 = 0xFF; TR1 = 1; ET1 = 1;
- /* 定時器 1*/
- TH0 = 246; TL0 = 246; TR0 = 0; ET0 = 0;
- /***********/
- IE0=0;IE1=0;TF1=0;TF0=0;
- EA = 1;
- }
- void signalchuli(float m,float n) //坐標定位計算程序
- {
- BOOL r1=0;
- BOOL r2=0; //方程是否成立變量
- BOOL suc=0; //解題是否成功變量
- float x,y;
- for(x=10;x<=500;x+=10)
- {
- for(y=10;y<=350;y+=10)
- {
- if(fabs(sqrt(x*x+(350-y)*(350-y))- sqrt(x*x+y*y)-m)<=20.0)
- r1=1;
- //else r1=0;
- if(fabs(sqrt(x*x+y*y)-sqrt(y*y+(500-x)*(500-x)) -n)<=20.0)
- r2=1;
- //else r2=0;
- if(r1&&r2)
- {
- suc=1;
- break;
- }
- else
- {
- r1=0;
- r2=0;
- }
- }
- if(suc)
- break;
- }
-
- posX=x;
- posY=y;
-
- }
- void main()
- {
- float cha1,cha2;
- uchar cha1_temp,cha2_temp;
- EA=0;
- Init_Show();
- Init_isr();
- while(1)
- {
- if( signalA && signalB && signalC)
- {
- EA = 0;
- TR0=0;
- obv++;
- cha1_temp = wolsignalA - wolsignalB;
- cha2_temp = wolsignalB - wolsignalC;
- if(wolsignalA < wolsignalB)
- {
- cha1_temp = 65536 - cha1_temp;
- cha1 = -(3.4*cha1_temp);
- }
- else
- {
- cha1 = 3.4*cha1_temp;
- }
- if(wolsignalB < wolsignalC)
- {
- cha2_temp = 65536 - cha2_temp;
- cha2 = -(3.4*cha2_temp);
- }
- else
- {
- cha2 = 3.4*cha2_temp;
- }
- signalchuli(cha1,cha2);
- DisplayADData(4,2,posX);
- DisplayADData(4,3,posY); //顯示坐標
- signalA = 0;
- signalB = 0;
- signalC = 0;
- wolCount = 0;
- Init_isr();
- }
- DisplayADData(0,4,wolsignalA);
- DisplayADData(3,4,wolsignalB);
- DisplayADData(6,4,wolsignalC); //顯示時間插值,方便調試
- DisplayADData(0,1,signalA);
- DisplayADData(3,1,signalB);
- DisplayADData(6,1,signalC); //顯示觸發標志位,方便調試
- }
- }
- void JsA_isr() interrupt 0 //外部中斷0,下降沿觸發
- {
- EX0 = 0;
- if(wolCount == 0)
- {
- wolsignalA = 0;
- TR0 = 1;
- ET0 = 1;
- }
- else
- {
- wolsignalA = wolCount;
- }
- signalA = 1;
- }
- void JsB_isr() interrupt 2 //外部中斷1,下降沿觸發
- {
-
- if(wolCount == 0)
- {
- wolsignalB = 0;
- TR0 = 1;
- ET0 = 1;
- }
- else
- {
- wolsignalB = wolCount;
- }
- signalB =1;
- EX1 = 0;
- }
- void Timer1_isr() interrupt 3 //計數器1,工作方式2
- {
- if(wolCount == 0)
- {
- wolsignalC = 0;
- TR0 = 1;
- ET0 = 1;
- }
- else
- {
- wolsignalC = wolCount;
- }
- signalC = 1;
- ET1 = 0;
- }
- void Timer0_isr() interrupt 1 //定時器0,工作方式2 , 10us
- {
- wolCount++;
- }
復制代碼 仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
全部資料51hei下載地址:
聲音定位系統.rar
(1.6 MB, 下載次數: 353)
2018-6-25 16:44 上傳
點擊文件名下載附件
|