這個(gè)是全網(wǎng)最詳細(xì)的STM32項(xiàng)目教學(xué)視頻。
第一篇在這里:
視頻在這里
15.1-超聲波測(cè)距
完成超聲波測(cè)距功能、測(cè)量數(shù)據(jù)顯示在OLED屏幕上
硬件介紹
使用:HC-SR04 超聲波測(cè)距模塊
注意: 繪制PCB注意四個(gè)引腳順序 Vcc Trig Echo Gnd
供電3.3V-5V(最好5V)
通過超聲波的硬件介紹我們知道
MCU給Trig腳一個(gè)大于10us的高電平脈沖;然后讀取Echo腳的高電平信號(hào)時(shí)間,通過公式:距離 = T* 聲速/2 就可以算出來距離。
Trig(PB5)我們配置為GPIO輸出
Echo(PA6)我們配置GPIO輸入功能
注:這里大家可能會(huì)問,為什么不使用定時(shí)器捕獲功能?
原因:
- 留一個(gè)定時(shí)器 方便以后擴(kuò)展FreeRTOS使用
- 或者擴(kuò)展其他舵機(jī)、電機(jī)等
軟件初始化
設(shè)置PB5輸出模式然后起別名
設(shè)置PA6輸入模式、
然后生成代碼
自己新建HC_SR04.c和HC_SR04.h 然后加入工程,指定路徑
防止溢出 把之前使用的數(shù)組調(diào)整大一些
因?yàn)槲覀儾贿m用定時(shí)器所以我們需要自己寫一個(gè)us級(jí)延時(shí)函數(shù)
/*******************
* @brief us級(jí)延時(shí)
* @param usdelay:要延時(shí)的us時(shí)間
* @return
*
*******************/
void HC_SR04_Delayus(uint32_t usdelay)
{
__IO uint32_t Delay = usdelay * (SystemCoreClock / 8U / 1000U/1000);//SystemCoreClock:系統(tǒng)頻率
do
{
__NOP();
}
while (Delay --);
}
/*******************
* @brief HC_SR04讀取超聲波距離
* @param 無(wú)
* @return 障礙物距離單位:cm (靜止表面平整精度更高)
*注意:兩個(gè)HC_SR04_Read()函數(shù)調(diào)用的時(shí)間間隔要2ms及以上,測(cè)量范圍更大 精度更高
*******************/
float HC_SR04_Read(void)
{
uint32_t i = 0;
float Distance;
HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_SET);//輸出15us高電平
HC_SR04_Delayus(15);
HAL_GPIO_WritePin(HC_SR04_Trig_GPIO_Port,HC_SR04_Trig_Pin,GPIO_PIN_RESET);//高電平輸出結(jié)束,設(shè)置為低電平
while(HAL_GPIO_ReadPin(HC_SR04_Echo_GPIO_Port,HC_SR04_Echo_Pin) == GPIO_PIN_RESET)//等待回響高電平
{
i++;
HC_SR04_Delayus(1);
if(i>100000) return -1;//超時(shí)退出循環(huán)、防止程序卡死這里
}
i = 0;
while(HAL_GPIO_ReadPin(HC_SR04_Echo_GPIO_Port,HC_SR04_Echo_Pin) == GPIO_PIN_SET)//下面的循環(huán)是2us
{
i = i+1;
HC_SR04_Delayus(1);//1us 延時(shí),但是整個(gè)循環(huán)大概2us左右
if(i >100000) return -2;//超時(shí)退出循環(huán)
}
Distance = i*2*0.033/2;//這里乘2的原因是上面是2微妙
return Distance ;
}
然后就可以讀距離了、連上藍(lán)牙可以顯示數(shù)據(jù)
注意:兩個(gè)HC_SR04_Read()函數(shù)調(diào)用的時(shí)間間隔要2ms及以上,測(cè)量范圍更大 精度更高
sprintf((char *)Usart3String,"HC_SR04:%.2fcmrn",HC_SR04_Read());//顯示超聲波數(shù)據(jù)
HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const char *)Usart3String),0xFFFF);//通過串口三輸出字符 strlen:計(jì)算字符串大小
然后把我們的手機(jī)藍(lán)牙和小車藍(lán)牙連接
手機(jī)顯示
15.2-避障邏輯編寫
然后我們編寫循跡邏輯,我們的邏輯時(shí)
//**************避障功能********************//
//避障邏輯
if(HC_SR04_Read() > 25)//前方無(wú)障礙物
{
motorPidSetSpeed(1,1);//前運(yùn)動(dòng)
HAL_Delay(100);
}
else{ //前方有障礙物
motorPidSetSpeed(-1,1);//右邊運(yùn)動(dòng) 原地
HAL_Delay(500);
if(HC_SR04_Read() > 25)//右邊無(wú)障礙物
{
motorPidSetSpeed(1,1);//前運(yùn)動(dòng)
HAL_Delay(100);
}
else{//右邊有障礙物
motorPidSetSpeed(1,-1);//左邊運(yùn)動(dòng) 原地
HAL_Delay(1000);
if(HC_SR04_Read() >25)//左邊無(wú)障礙物
{
motorPidSetSpeed(1,1);//前運(yùn)動(dòng)
HAL_Delay(100);
}
else{
motorPidSetSpeed(-1,-1);//后運(yùn)動(dòng)
HAL_Delay(1000);
motorPidSetSpeed(-1,1);//右邊運(yùn)動(dòng)
HAL_Delay(50);
}
}
}
這樣我們就可以使用超聲波讀取距離值了。
下篇16章我們i講解如何利用超聲波做跟隨,我們后面會(huì)定距離跟隨的功能。
聯(lián)系:Q,1930299709