日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

基于STM32F103HAL库的声音定位系统

發布時間:2023/12/15 windows 67 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于STM32F103HAL库的声音定位系统 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


這是一道學校出的電賽題目,要求在100*100cm的平面上實現定位實現聲音定位。由于一米太大了,我們就做了40cm的,下面的講解我按照40厘米的寫。用到的處理器是stm32f103c8t6接下來分享一下調試心得。
硬件部分需要制作發聲裝置和接收裝置,詳細可以參考這個文章.
需要知道的是,揚聲器發出的聲音經過接收裝置,得到的是一個方波信號,所以單片機需要根據這些方波求出距離

解題思路

一.直線

既然我們說,接收模塊得到的是方波信號,那么單片機肯定可以檢測到方波的下降沿和上升沿,在直線上,聲源距離接收模塊越近,聲音先到達,就先接收到下降沿,相反,聲源距離接收模塊遠,就后接受到下降沿,這樣我們可以得到時間差。接下來就是小學數學了(手動狗頭),根據兩個時間可以算出距離。
用C語言描述就是這樣

傳入參數:兩個下降沿分別到兩個接收器之間的時間差 傳出參數:距離 float Find_Line(float ltime) {float S=0,timeall=0,timefst=0;timeall=0.0012; //單位是秒,根據ltime單位做調整 0.4/346timefst=(timeall+ltime)/2;S=0.4*(timefst/timeall);return S; }

二.平面

在平面上,就需要三個接收模塊,這樣就能得出兩個時間差。
像下面這幅圖

用C語言描述是這樣,得到的arv1和arv2就是坐標值,
整個函數就是解方程的思路,用窮舉法求出合適的值,我在后面又對得到的值做了求平均處理。

//傳入參數:兩個時間差 void Find_Square(float ctime1,float ctime2) {int count,i=0;for(x=0.0; x<=40.0; x++){for(y=0.0; y<=40.0;y++){if(fabs(sqrt(x*x+(y-40)*(y-40))-sqrt(x*x +y*y)-34000*ctime1)<3 && fabs(sqrt(x*x +y*y)-sqrt((40-x)*(40-x)+y*y)-34000*ctime2)<3) { a[i]=x;b[i]=y;i++;count =i;printf("x=%.2f y=%.2f count=%d\n",x,y,count);} else{printf("方程無解");}}} // count=Del_Zero(a,count); // Del_Zero(b,count);for(int i=0; i< count; i++){sum1=sum1+a[i];sum2=sum2+b[i];arv1=sum1/count;arv2=sum2/count;printf("a[i]=%.2f b[i]=%.2f count=%d %f\n",a[i],b[i],count,sum1);}printf("arv1=%.2f arv2=%.2f\n",arv1,arv2);sum1=0;sum2=0; }

二.單片機獲取時間

其實解題思路不難,難點就在于獲取到準確的時間,我使用的獲取方法是外部中斷,當單片機的一個IO口檢測到下降沿,定時器開始計時,另一個IO口檢測到下降沿停止計時,這樣就得到時間差

1.cubemx配置

1.外部中斷


2.定時器
由于晶振是72MHZ,而且接收到下降沿的時間在微秒級別,所以將單位時間設置為100us(72000000/72/100=10000hz)(1/10000=100us)

/*** 函數功能: 按鍵外部中斷回調函數* 輸入參數: GPIO_Pin:中斷引腳* 返 回 值: 無* 說 明: 無*/ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {if(GPIO_Pin==GPIO_PIN_0)//A{if(time1==0){wosignA=0;HAL_TIM_Base_Start_IT(&htim2); //使能剛剛配置的定時器}else{wosignA=time1+255*time2;//HAL_TIM_Base_Stop_IT(&htim2);}signA=1; }if(GPIO_Pin==GPIO_PIN_1)//B{if(time1==0){wosignB=0;HAL_TIM_Base_Start_IT(&htim2); //使能剛剛配置的定時器}else{wosignB=time1+255*time2;//HAL_TIM_Base_Stop_IT(&htim2);}signB=1;//EXTI->IMR &= ~(GPIO_PIN_1); }if(GPIO_Pin==GPIO_PIN_11)//B{if(time1==0){wosignC=0;HAL_TIM_Base_Start_IT(&htim2); //使能剛剛配置的定時器}else{wosignC=time1+255*time2;//HAL_TIM_Base_Stop_IT(&htim2); //使能剛剛配置的定時器}signC=1;//EXTI->IMR &= ~(GPIO_PIN_1); }} /*** 函數功能: 定時器中斷回調函數* 輸入參數: * 返 回 值: 無* 說 明: 無*/ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if (htim->Instance == htim2.Instance){time1++; if(time1==255){time2++;time1=0;}//定時器計數255次溢出一次}if (htim->Instance == htim1.Instance){} } key=read_key();if(key==1) {mode=1;OLED_Clear();}if(key==2) {mode=2;OLED_Clear();}if(key==3) {mode=3;OLED_Clear();}if(mode==1){if(signA&&signB){EXTI->IMR &= ~(GPIO_PIN_0);//關閉外部中斷EXTI->IMR &= ~(GPIO_PIN_1);HAL_TIM_Base_Stop_IT(&htim2);if(wosignA<wosignB){t1=wosignB;}else {t1=wosignA;}if(t1>11){t1=11;}s=Find_Line(fabs((float)(t1))*100/1000000);printf("%d %d %f %d %d %d %d\n",time1,time2,s,wosignA,wosignB,wosignC,t1);OLED_ShowFloat(0,0,s,2,4,16);HAL_Delay(100);EXTI->IMR |= GPIO_PIN_0; //開啟外部中斷EXTI->IMR |= GPIO_PIN_1;signA=0;signB=0;time1=0;time2=0;}} //printf("%d %d %d %d %d %d\n",signA,signB,signC,wosignC,wosignA,wosignB);if(mode==2){if(signA&&signB&&signC){EXTI->IMR &= ~(GPIO_PIN_0);EXTI->IMR &= ~(GPIO_PIN_1);EXTI->IMR &= ~(GPIO_PIN_11);HAL_TIM_Base_Stop_IT(&htim2);if((wosignA<wosignB)&&(wosignB<wosignC)){t2=wosignB;t3=wosignC;}if((wosignA<wosignC)&&(wosignB>wosignC)){t2=wosignC;t3=wosignB;}if((wosignB<wosignA)&&(wosignA<wosignC)){t2=wosignA;t3=wosignC;}if((wosignB<wosignC)&&(wosignC<wosignA)){t2=wosignC;t3=wosignA;}if((wosignC<wosignA)&&(wosignA<wosignB)){t2=wosignA;t3=wosignB;}if((wosignC<wosignB)&&(wosignB<wosignA)){t2=wosignB;t3=wosignA;}if(t2>11){t2=11;}if(t3>11){t3=11;} // t2=wosignA-wosignB; // t3=wosignB-wosignC;printf("%d %d %f %d %d %d %d %d\n",time1,time2,s,wosignA,wosignB,wosignC,t2,t3);Find_Square((float)t2/10000,(float)t3/10000);OLED_ShowFloat(0,0,arv1,2,4,16);OLED_ShowFloat(0,2,arv2,2,4,16);//HAL_Delay(100);EXTI->IMR |= GPIO_PIN_0; EXTI->IMR |= GPIO_PIN_1;EXTI->IMR |= GPIO_PIN_11;signA=0;signB=0;signC=0;time1=0;time2=0;}}if(mode==3){goto MENU;}}

可以用自己的按鍵,設置標志位做兩個模式,完成持續監測。

成品的誤差稍微有些大,不乏溫度,濕度,以及硬件誤差,和單片機檢測誤差,沒有濾波等等,總的來說,大體方向是對的,我們的作品還能進一步完善。
在調試的時候,單片機PB10引腳接收不到方波信號,拆了板子打電表,查不出問題,結果換了個引腳,好了,,,,,

總結

以上是生活随笔為你收集整理的基于STM32F103HAL库的声音定位系统的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。