基于stm32的超聲波測(cè)距
首先來看模塊圖
在某寶上一搜就能找到,關(guān)于它的使用也是非常簡(jiǎn)單,先看數(shù)據(jù)手冊(cè)里面需要注意的幾點(diǎn)
1 基本的參數(shù)
在實(shí)際測(cè)試當(dāng)中,最大測(cè)量三米多的距離還是可以,最小距離我沒有做測(cè)試,我測(cè)的最小距離是50厘米,再往下沒有繼續(xù)測(cè)。
2測(cè)距的基本原理
這里的基本原理其實(shí)應(yīng)該是它的使用方法,如果你仔細(xì)看它的數(shù)據(jù)手冊(cè)會(huì)發(fā)現(xiàn)這種測(cè)距模塊還有另外一種使用方法:USART通信。
看文字不是很直觀,簡(jiǎn)單粗暴來看圖
在寫程序的時(shí)候沒有使用USART的方法,因?yàn)樯蠄D的這種驅(qū)動(dòng)方式我認(rèn)為比較簡(jiǎn)單,后面的程序也是按照這個(gè)時(shí)序圖來編寫的。
注意:上圖中關(guān)于測(cè)距的公式,在程序中我沒有使用他給的公式,這一點(diǎn)在后面會(huì)提到。
3 實(shí)物圖的連接
實(shí)物圖的連接就不上圖了,購買此模塊的時(shí)候一般賣家會(huì)給你相應(yīng)的資料。
直接上程序:
主函數(shù):
intmain(void)
{
unsignedintcount=0;
floatdistance=0;
floatdistancebuf[]={0};//這里的數(shù)組沒有意義,是在調(diào)試程序的時(shí)候,怕測(cè)的距離有誤差,把連續(xù)幾次測(cè)到的數(shù)值放入數(shù)組中求平均值,以提高精度
/*USART1config1152008-N-1*/
USART1_Config();
Distance_Config();//距離轉(zhuǎn)換函數(shù),在上面的說明中有提到,但是具體的實(shí)現(xiàn)和上面的公式是不相同的
CLI();//關(guān)閉總中斷
SEI();//開啟總中斷
Tim3_Config();//定時(shí)器初始化
GPIO_ResetBits(GPIOA,GPIO_Pin_5);//先拉低電平
while(1)
{
GPIO_SetBits(GPIOA,GPIO_Pin_5);//再拉高電平,這里拉低拉高電平是根據(jù)上面給出的測(cè)距原理來寫的
Delay(30);//延時(shí)30個(gè)us,注意這里使用的是粗略的延時(shí)函數(shù),測(cè)距原理中說是延時(shí)10個(gè)us,這里給30個(gè)us也無妨
//Delay(20);
//Delay(20);
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
TIM3->CNT=0;//TIM3的計(jì)數(shù)器清零
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==0);//等待ECHO的高電平
TIM_Cmd(TIM3,ENABLE);//運(yùn)行TIM3進(jìn)行計(jì)數(shù)
while((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)==1)&&(TIM3->CNT
TIM_Cmd(TIM3,DISABLE);
count=TIM3->CNT;
printf("count=%d",count);
distance=ChangeDistance(count);
printf("μ±?°?àà??a£o%fn",distance);
Delay(20000);
Delay(20000);//這里的延時(shí)沒有具體的意義,可以去掉
while(1);//程序測(cè)距一次后卡死在這里
}
}
距離轉(zhuǎn)換函數(shù)
floatChangeDistance(unsignedintcout1)
{
floatdistance=0;
printf("cou1=%dn",cout1);
distance=cout1/58.0;
returndistance;
}
參數(shù)是TIM3->CNT的計(jì)數(shù),也就是高電平的時(shí)間,distance是測(cè)距距離
注意:distance的單位是厘米
關(guān)于轉(zhuǎn)換的公式為什么是cout1/58.0 這里我也不是很清楚
另外:當(dāng)ECHO引腳輸出高電平后,另一種思路是采用上升沿觸發(fā)定時(shí)器中斷的方式來計(jì)算高電平時(shí)間的,我認(rèn)為沒有必要再配置一次中斷,使用while()來等待這個(gè)高電平的方法完全可以。當(dāng)然不容忽視的一個(gè)問題是,如果始終檢測(cè)不到高電平,程序會(huì)卡死在while()語句這里,因此有必要加上一個(gè)時(shí)間的判斷。
通過串口打印相應(yīng)的測(cè)量結(jié)果。
模塊的資料就不上傳了,在某寶店里一般都有相應(yīng)的下載鏈接。
其他的具體細(xì)節(jié),例如定時(shí)器的配置,引腳的配置請(qǐng)參考我上傳的程序,如有疑惑歡迎留言。
http://download.csdn.net/detail/qq_27312943/9541979
注意:1 有的超聲波模塊是有溫度校準(zhǔn)的,有溫度校準(zhǔn)的模塊測(cè)距精度要高一些。
2 模塊再穩(wěn)定下來之后測(cè)距是比較準(zhǔn)確的,即便是我上面寫的代碼,也需要穩(wěn)定一下再測(cè)距才可以,舉個(gè)例子,當(dāng)你將超聲波模塊對(duì)著墻時(shí),剛上電測(cè)到的距離并不準(zhǔn)確,但是很短時(shí)間后測(cè)距就會(huì)變得非常精準(zhǔn)。
3 上面的程序采用的是電平觸發(fā)的方式,我看到有的說使用串口的方式會(huì)使精確度更高,但我沒有做相關(guān)的實(shí)驗(yàn)。
4 想要提高測(cè)距精度的另一種方法就是多次測(cè)量,去掉最大值,最小值后取平均值的方法,我在另一份程序中采用的是測(cè)五次距離,然后取出平均值得方法,需要注意多次測(cè)量的周期最好大于60ms