【STM32】標準庫與HAL庫對照學習教程外設篇--超聲波測距傳感器
- 一、前言
- 二、準備作業
- 三、超聲波測距傳感器
- 1、原理說明
- 2、使用說明
- 四、標準庫使用傳感器
- 1、實驗程式
- 2、實驗效果
- 五、HAL庫使用傳感器
- 1、cubemx主要配置
- 2、實驗程式
- 3、實驗效果
一、前言
本篇介紹如何使用STM32控制超聲波傳感器,方法可以使用STM32的 定時器計數或者輸入捕獲功能,本篇使用的是定時器中斷,
有關定時器的知識在:
【STM32】標準庫與HAL庫對照學習教程七–定時器中斷中有詳細說明,
本篇使用串口將測驗的距離列印在電腦,有關STM32串口通信的知識可以看這篇文章:
【STM32】標準庫與HAL庫對照學習教程八–串口通信詳解
二、準備作業
- STM32開發板(我用的是普中的STM32F103ZE的Z200系列)
- STM32cubemx軟體、keil5(MDK)
- HC-SR04超聲波傳感器或者HY-SRF05超聲波傳感器
三、超聲波測距傳感器
1、原理說明
超聲波測距傳感器使用回聲測距法,傳感器由超聲波發射器、超聲波接收器、傳感器電路組成,傳感器主要用到4個引腳,VCC、Trig、Echo、GND,
測距原理是超聲波發射器向某一方向發射超聲波,在發射時刻的同時計數器開始計時,超聲波在空氣中傳播,途中碰到障礙物面阻擋就立即反射回來,超聲波接收器收到反射回的超聲波就立即停止計時,
超聲波在空氣中的傳播速度為340m/s,根據計時器記錄的時間t,就可以計算出發射點距障礙物面的距離s,即:s=340t/2,

2、使用說明
- VCC應接5V供電
- 使用時,STM32給Trig引腳輸出10us到20us的高電平,傳感器發射超聲波,
- 當接收到回聲時,Echo引腳輸出一定時間的高電平,高電平的持續時間,就是整個程序的時間,因此,距離=高電平時間*聲速/2,
- 超聲波測距模塊可測量距離范圍是2cm-400cm, 測距精度可達高到3mm;
- 為了防止回聲信號干擾,建議測量周期在60ms以上,
四、標準庫使用傳感器
1、實驗程式
main.c
#include "LED.h"
#include "Delay.h"
#include "System.h"
#include "usart.h"
#include<stdio.h>
#include "ultrasonic.h"
/*************************************************
*函式名: main
*函式功能: 主函式
*輸入: 無
*回傳值: 無
**************************************************/
int main()
{
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //搶占式優先級與回應式優先級的分組
LED_Init();
USART1_Init(9600);
Ultrasonic_Init();
while(1)
{
printf("distance = %f mm\r\n",Get_distance()); //輸出距離
}
}
ultrasonic.c
#include "ultrasonic.h"
#include "System.c"
#include "Delay.h"
/*************************************************
*函式名: Ultrasonic_Init
*函式功能: 超聲波初始化函式
*輸入: 無
*回傳值: 無
**************************************************/
void Ultrasonic_Init()
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
// NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(Trig_RCC|Echo_RCC, ENABLE); //打開對應引腳時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //打開定時器時鐘
GPIO_InitStruct.GPIO_Pin = Trig_Pin; //Trig引腳
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //輸出速度
GPIO_Init(Trig_Port, &GPIO_InitStruct); //引腳初始化
GPIO_ResetBits(Trig_Port,Trig_Pin); //引腳置低
GPIO_InitStruct.GPIO_Pin = Echo_Pin; //Echo引腳
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; //下拉輸入
GPIO_Init(Echo_Port, &GPIO_InitStruct); //引腳初始化
TIM_TimeBaseInitStruct.TIM_Prescaler = 71; //分頻系數
TIM_TimeBaseInitStruct.TIM_Period = 50000; //重裝載值
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //定時器時鐘不分頻
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //向上計數模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct); //定時器初始化
}
/*************************************************
*函式名: Get_distance
*函式功能: 獲得距離
*輸入: 無
*回傳值: 距離,型別浮點型,單位mm
**************************************************/
float Get_distance()
{
float TIME_distance;
Trig = 1; Delay_us(15); Trig = 0; //給Trig引腳15us的高電平
TIM_Cmd(TIM3, ENABLE); //定時器3使能
while(!Echo) //等待高電平出現
{
if(TIM_GetCounter(TIM3)>40000) //200ms內未接收到回傳信號
{
TIM_Cmd(TIM3, DISABLE); //定時器3失能
TIM_SetCounter(TIM3, 0); //計時器清零
return ERROR;
}
}
TIM_SetCounter(TIM3, 0); //接收到高電平,開始計時
while(Echo); //等待低電平出現
TIM_Cmd(TIM3, DISABLE); //定時器3失能
TIME_distance = ((float)TIM_GetCounter(TIM3)/1000.0)*340/2.0; //計算距離
TIM_SetCounter(TIM3, 0); //計時器清零
return TIME_distance; //回傳距離,單位mm
}
ultrasonic.h
#ifndef ULTRASONIC_H_
#define ULTRASONIC_H_
#include "stm32f10x.h"
/************重定義引腳便于移植************/
#define Trig_RCC RCC_APB2Periph_GPIOB
#define Trig_Pin GPIO_Pin_1
#define Trig_Port GPIOB
#define Echo_RCC RCC_APB2Periph_GPIOB
#define Echo_Pin GPIO_Pin_2
#define Echo_Port GPIOB
/************位帶操作************/
#define Trig PBout(1)
#define Echo PBin(2)
/************函式說明************/
void Ultrasonic_Init(void);
float Get_distance(void);
#endif
2、實驗效果

五、HAL庫使用傳感器
1、cubemx主要配置
①

②

③

④串口配置

⑤定時器配置

⑥引腳配置

⑦工程配置


⑧在工程內添加檔案(記得添加檔案路徑)

2、實驗程式
ultrasonic.c
#include "Ultrasonic.h"
#include "tim.h"
#include "Delay.h"
#include "System.h"
/*************************************************
*函式名: Ultrasonic_Get_Distance
*函式功能: 獲取超聲波距離函式
*輸入: 無
*回傳值: 無
**************************************************/
float Ultrasonic_Get_Distance()
{
float Distance;
Trig = 1; Delay_ms(15); Trig = 0; //給Trig引腳15us的高電平
HAL_TIM_Base_Start(&htim3); //打開定時器
while(!Echo) //等待回聲出現
{
if(__HAL_TIM_GET_COUNTER(&htim3)>40000) //時間超時
{
HAL_TIM_Base_Stop(&htim3); //關閉定時器
__HAL_TIM_SET_COUNTER(&htim3, 0); //計數器清零
return ERROR;
}
}
__HAL_TIM_SET_COUNTER(&htim3, 0); //計數器清零
while(Echo); //等待低電平結束
HAL_TIM_Base_Stop(&htim3); //關閉定時器
Distance = ((float)__HAL_TIM_GET_COUNTER(&htim3)/1000.0)*340/2.0; //計算距離
__HAL_TIM_SET_COUNTER(&htim3, 0); //計數器清零
return Distance;
}
ultrasonic.h
#ifndef UITRASONIC_H_
#define UITRASONIC_H_
#include "stm32f1xx_hal.h"
/************位帶操作************/
#define Trig PBout(1)
#define Echo PBin(2)
/************函式定義************/
float Ultrasonic_Get_Distance(void);
#endif
main.c

#include<stdio.h>
#include "Ultrasonic.h"
/**
* 函式功能: 重定向c庫函式printf到DEBUG_USARTx
* 輸入引數: 無
* 返 回 值: 無
* 說 明:無
*/
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}

printf("distance = %f mm \r\n",Ultrasonic_Get_Distance());
HAL_Delay(500);
3、實驗效果

到這里就結束啦!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/376022.html
標籤:其他
