1. 程式人生 > >基於stm32的超聲波測距

基於stm32的超聲波測距

首先來看模組圖 


在某寶上一搜就能找到,關於它的使用也是非常簡單,先看資料手冊裡面需要注意的幾點 

1 基本的引數


在實際測試當中,最大測量三米多的距離還是可以,最小距離我沒有做測試,我測的最小距離是50釐米,再往下沒有繼續測。 

測距的基本原理 


這裡的基本原理其實應該是它的使用方法,如果你仔細看它的資料手冊會發現這種測距模組還有另外一種使用方法:USART通訊。

看文字不是很直觀,簡單粗暴來看圖





在寫程式的時候沒有使用USART的方法,因為上圖的這種驅動方式我認為比較簡單,後面的程式也是按照這個時序圖來編寫的。


注意:上圖中關於測距的公式,在程式中我沒有使用他給的公式,這一點在後面會提到。




3 實物圖的連線 
實物圖的連線就不上圖了,購買此模組的時候一般賣家會給你相應的資料。 

直接上程式:

主函式:

int main(void)
{
	  unsigned int count=0;
	  float distance=0;
	  float distancebuf[]={0}; //這裡的陣列沒有意義,是在除錯程式的時候,怕測的距離有誤差,把連續幾次測到的數值放入陣列中求平均值,以提高精度
		/* USART1 config 115200 8-N-1 */
    USART1_Config();
    Distance_Config();  //距離轉換函式,在上面的說明中有提到,但是具體的實現和上面的公式是不相同的
    CLI() ;//關閉總中斷
	  SEI(); //開啟總中斷
	  Tim3_Config();  //定時器初始化
	
	  
	  GPIO_ResetBits(GPIOA,GPIO_Pin_5);  //先拉低電平
	
	  while(1)
		{
    
			  GPIO_SetBits(GPIOA,GPIO_Pin_5);  //再拉高電平,這裡拉低拉高電平是根據上面給出的測距原理來寫的
			  Delay(30);  //延時30個us,注意這裡使用的是粗略的延時函式,測距原理中說是延時10個us,這裡給30個us也無妨
			//  Delay(20);
			//  Delay(20);
			 GPIO_ResetBits(GPIOA,GPIO_Pin_5); 

       TIM3->CNT=0;  //TIM3的計數器清零

       while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0); //等待ECHO的高電平
		

       TIM_Cmd(TIM3,ENABLE);  //執行TIM3進行計數
       
			while((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 1) && (TIM3->CNT < TIM3->ARR-10));
			 
			  TIM_Cmd(TIM3,DISABLE);  
       		
        count=TIM3->CNT;

        printf("count=%d",count);			
			  distance=ChangeDistance(count);
			  printf(" µ±Ç°¾àÀëΪ£º%f\n",distance);
			  Delay(20000); 
				Delay(20000); //這裡的延時沒有具體的意義,可以去掉
			  while(1);  //程式測距一次後卡死在這裡
				
     }
}
距離轉換函式
float ChangeDistance(unsigned int cout1)
{
    float distance=0;
	  printf("cou1=%d\n",cout1);
	  distance=cout1/58.0;
	
	  return distance;
}
引數是TIM3->CNT的計數,也就是高電平的時間,distance是測距距離

注意:distance的單位是釐米

關於轉換的公式為什麼是cout1/58.0  這裡我也不是很清楚安靜安靜安靜

另外:當ECHO引腳輸出高電平後,另一種思路是採用上升沿觸發定時器中斷的方式來計算高電平時間的,我認為沒有必要再配置一次中斷,使用while()來等待這個高電平的方法完全可以。當然不容忽視的一個問題是,如果始終檢測不到高電平,程式會卡死在while()語句這裡,因此有必要加上一個時間的判斷。

通過串列埠列印相應的測量結果。

模組的資料就不上傳了,在某寶店裡一般都有相應的下載連結。

其他的具體細節,例如定時器的配置,引腳的配置請參考我上傳的程式,如有疑惑歡迎留言。

http://download.csdn.net/detail/qq_27312943/9541979

注意:1 有的超聲波模組是有溫度校準的,有溫度校準的模組測距精度要高一些。

            2 模組再穩定下來之後測距是比較準確的,即便是我上面寫的程式碼,也需要穩定一下再測距才可以,舉個例子,當你將超聲波模組對著牆時,剛上電測到的距離並不準確,但是很短時間後測距就會變得非常精準。

           3 上面的程式採用的是電平觸發的方式,我看到有的說使用串列埠的方式會使精確度更高,但我沒有做相關的實驗。

           4 想要提高測距精度的另一種方法就是多次測量,去掉最大值,最小值後取平均值的方法,我在另一份程式中採用的是測五次距離,然後取出平均值得方法,需要注意多次測量的週期最好大於60ms