因為自己做畢設的緣故,用到超聲波hcsr04模組,在網上查詢了相關的**,發現關於超聲波測距大體上有兩種寫法。在自己除錯改進後,想把這兩種方法都貼出來,和大家一起討論學習。
對了,我用的是stm32f103zet6。
首先還是簡單介紹下超聲波測距原理。
(1)超聲波模組的trig引腳給最少10us高電平訊號,觸發測距。
(2)模組自動傳送8個40khz的方波,自動檢測是否有訊號返回;
(3)有訊號返回, 通過echo口輸出乙個高電平, 高電平持續的時間就是超聲波從發射到返回的時間。
測試距離=(高電平時間*聲速(340m/s))/2。
因此只要檢測echo連線的微控制器引腳高電平持續時間 便可以得到超聲波從發射到返回的時間。
這邊簡單講講兩種方法思路。
第一種方法是採用定時器的輸入捕獲功能,直接將echo引腳接到stm32具有輸入捕獲功能的管腳,配置好定時器輸入捕獲功能,就可以讀取到高電平時間。
第二種方法思路類似,只不過不採用輸入捕獲,直接配置好乙個定時器,當判斷echo接的微控制器引腳有高電平時,開啟定時器;當高電平結束後,關閉定時器。然後讀取定時器一共定時多少時間從而獲得高電平時間。
這兩種方法我都試了,超聲波模組的測距都沒有問題,第二種方法思路似乎比較清楚(我個人覺得),但是第一種方法明顯更加簡便(因為直接應用了stm32定時器自帶的功能)。
說到底難點還是在定時器配置這塊,建議大家多看看手冊和參考資料。
方法一:定時器輸入捕獲
在這一方法中,我是將pa1的定時器5通道2作為輸入捕獲通道,也就是將echo接到pa1
trig接到了pc1作為觸發
主程式main.c部分
#include
"led.h"
#include
"delay.h"
#include
"sys.h"
#include
"usart.h"
#include
"timer.h"
#include
"hcsr04.h"
extern u8 tim5ch2_capture_sta;
//輸入捕獲狀態
extern u16 tim5ch2_capture_val;
//輸入捕獲值
intmain
(void)}
}
定時器配置timer.c部分
tim_icinittypedef tim5_icinitstructure;
void
tim5_cap_init
(u16 arr,u16 psc)
u8 tim5ch2_capture_sta=0;
//輸入捕獲狀態
u16 tim5ch2_capture_val;
//輸入捕獲值
//定時器5中斷服務程式
void
tim5_irqhandler
(void
)else tim5ch2_capture_sta++;}
}if(tim_getitstatus
(tim5, tim_it_cc2)
!= reset)
//捕獲2發生捕獲事件
else
//還未開始,第一次捕獲上公升沿}}
tim_clearitpendingbit
(tim5, tim_it_cc2|tim_it_update)
;//清除中斷標誌位
}
超聲波初始化**
#include
"hcsr04.h"
#define trig pcout(1)
void
hcsr04_trig_send
(void
)void
hcsr04_trig_init
(void
)
方法二:定時器計時這個方法中,我將trig接到pb6作為觸發,echo接到pb7。只要檢測pb7電平狀態來開關定時器。
主函式main.c
#include
"led.h"
#include
"delay.h"
#include
"sys.h"
#include
"lcd.h"
#include
"hcsr04.h"
#include
"usart.h"
intmain
(void
)}
hcsr04模組配置和定時器配置
#include
"hcsr04.h"
#define trig pbout(6)
#define echo pbin(7)
u8 mshccount =0;
//ms計數
void
hcsr04_init
(void
)void
tim3_irqhandler
(void
)//tim3中斷
}static
void
open_tim3()
//開啟定時器
static
void
close_tim3()
//關閉定時器
u32 getechotimer
(void
)float
get_distance
(void
) distance = sum/
5.0;
return distance;
}
兩種方法大部分關鍵**我都貼出來了,大家可以一起討論學習,也可以自己試試。
下面放個除錯成功的截圖
基於STM32F4的US 100超聲波測距
開發板是乙個叫icore的板子,但是晶元是f4的,總體大同小異,只是引腳定義不一樣,改一改就可以直接用。先拔掉跳線帽轉到串列埠觸發模式下,通過給感測器傳送0x55就可以接收到距離資料,串列埠中斷裡面拿兩個數放到陣列裡面計算就可以了 distance.c檔案 void usart6 init u32 ...
在STM32上驅動超聲波測距模組
include sys.h include stm32f10x.h include delay.h include usart.h include time.h void hcsr04 init u16 arr,u16 psc u8 tim2ch1 capture sta 0 輸入捕獲狀態 u16 ...
STM32驅動超聲波測距感測器
先貼 以後再補說明 tim icinittypedef tim5 icinitstructure void tim5 cap init u16 arr,u16 psc u8 tim5ch1 capture sta 0 輸入捕獲狀態 u16 tim5ch1 capture val 輸入捕獲值 定時器5...