CubeMX配置STM32以驅(qū)動(dòng)超聲波模塊(HC-SR04)
一、CubeMX配置STM32 |
1、選擇定時(shí)器
選擇輸入捕獲模式
預(yù)分頻設(shè)置為71,向上計(jì)數(shù),自動(dòng)重裝值65535
然后將名字改為ECHO
2、配置TRIG口
這里的端口使用其它空閑的IO口是可以的,設(shè)置為輸出模式,其它配置不需要改變,最主要的是User Label那兒,需要設(shè)置為TRIG,因?yàn)轵?qū)動(dòng)函數(shù)里面使用的是這個(gè)的宏定義,所以必須要改成這個(gè)名字才能直接使用驅(qū)動(dòng)函數(shù)。
3、配置串口
因?yàn)橐@示超聲波測(cè)出的距離,我這里就直接使用串口助手顯示了,有需要的話(huà)使用OLED、TFT之類(lèi)的模塊顯示也可以。
在這里如果需要使用printf函數(shù)的話(huà),還需要在生成的usart.c里面添加fputc函數(shù)
:
/*********************************************************
*
*重定義 fputc 函數(shù)
*
*********************************************************/
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit (&huart1 ,(uint8_t *)&ch,1,HAL_MAX_DELAY );
return ch;
}
在這之前記得引入頭文件stdio.h
、勾選Use MicroLIB
二、使用keil5進(jìn)行進(jìn)一步開(kāi)發(fā) |
1、引入HC-SR04的驅(qū)動(dòng)文件
hc-sr04.c
/*
* @Author : yzy
* @Date : 2021-05-31 17:03:23
* @LastEditors : yzy
* @LastEditTime : 2021-06-21 22:16:28
* @Description :
* @FilePath : \CSDN_HC-SR04_GPIO\BSP_HARDWARE\HC-SR04\hc-sr04.c
*/
#include "hc-sr04.h"
Hcsr04InfoTypeDef Hcsr04Info;
/**
* @description: 超聲波模塊的輸入捕獲定時(shí)器通道初始化
* @param {TIM_HandleTypeDef} *htim
* @param {uint32_t} Channel
* @return {*}
*/
void Hcsr04Init(TIM_HandleTypeDef *htim, uint32_t Channel)
{
/*--------[ Configure The HCSR04 IC Timer Channel ] */
// MX_TIM2_Init(); // cubemx中配置
Hcsr04Info.prescaler = htim->Init.Prescaler; // 72-1
Hcsr04Info.period = htim->Init.Period; // 65535
Hcsr04Info.instance = htim->Instance;
if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_1)
{
Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_1; // TIM_CHANNEL_1
}
else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_2)
{
Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_2; // TIM_CHANNEL_2
}
else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_3)
{
Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_3; // TIM_CHANNEL_3
}
else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_4)
{
Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_4; // TIM_CHANNEL_4
}
/*--------[ Start The ICU Channel ]-------*/
HAL_TIM_Base_Start_IT(htim);
HAL_TIM_IC_Start_IT(htim, Channel);//開(kāi)啟中斷
}
/**
* @description: HC-SR04觸發(fā)
* @param {*}
* @return {*}
*/
void Hcsr04Start(void)
{
HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET);
HAL_Delay(1); // 10us以上
HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET);
}
/**
* @description: 定時(shí)器計(jì)數(shù)溢出中斷處理函數(shù)
* @param {*} main.c中重定義void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
* @return {*}
*/
void Hcsr04TimOverflowIsr(TIM_HandleTypeDef *htim)
{
if(htim->Instance == Hcsr04Info.instance) //
{
Hcsr04Info.tim_overflow_counter++;
}
}
/**
* @description: 輸入捕獲計(jì)算高電平時(shí)間->距離
* @param {*} main.c中重定義void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
* @return {*}
*/
void Hcsr04TimIcIsr(TIM_HandleTypeDef* htim)
{
if((htim->Instance == Hcsr04Info.instance) && (htim->Channel == Hcsr04Info.active_channel))
{
if(Hcsr04Info.edge_state == 0) // 捕獲上升沿
{
// 得到上升沿開(kāi)始時(shí)間T1,并更改輸入捕獲為下降沿
Hcsr04Info.t1 = HAL_TIM_ReadCapturedValue(htim, Hcsr04Info.ic_tim_ch);
__HAL_TIM_SET_CAPTUREPOLARITY(htim, Hcsr04Info.ic_tim_ch, TIM_INPUTCHANNELPOLARITY_FALLING);
Hcsr04Info.tim_overflow_counter = 0; // 定時(shí)器溢出計(jì)數(shù)器清零
Hcsr04Info.edge_state = 1; // 上升沿、下降沿捕獲標(biāo)志位
}
else if(Hcsr04Info.edge_state == 1) // 捕獲下降沿
{
// 捕獲下降沿時(shí)間T2,并計(jì)算高電平時(shí)間
Hcsr04Info.t2 = HAL_TIM_ReadCapturedValue(htim, Hcsr04Info.ic_tim_ch);
Hcsr04Info.t2 += Hcsr04Info.tim_overflow_counter * Hcsr04Info.period; // 需要考慮定時(shí)器溢出中斷
Hcsr04Info.high_level_us = Hcsr04Info.t2 - Hcsr04Info.t1; // 高電平持續(xù)時(shí)間 = 下降沿時(shí)間點(diǎn) - 上升沿時(shí)間點(diǎn)
// 計(jì)算距離
Hcsr04Info.distance = (Hcsr04Info.high_level_us / 1000000.0) * 340.0 / 2.0 * 100.0;
// 重新開(kāi)啟上升沿捕獲
Hcsr04Info.edge_state = 0; // 一次采集完畢,清零
__HAL_TIM_SET_CAPTUREPOLARITY(htim, Hcsr04Info.ic_tim_ch, TIM_INPUTCHANNELPOLARITY_RISING);
}
}
}
/**
* @description: 讀取距離
* @param {*}
* @return {*}
*/
float Hcsr04Read(void)
{
// 測(cè)距結(jié)果限幅
if(Hcsr04Info.distance >= 450)
{
Hcsr04Info.distance = 450;
}
return Hcsr04Info.distance;
}
hc-sr04.h
/*
* @Author : yzy
* @Date : 2021-05-31 17:03:27
* @LastEditors : yzy
* @LastEditTime : 2021-05-31 19:02:54
* @Description :
* @FilePath : \F103_Test\BSP_HARDWARE\hc-sr04.h
*/
#ifndef HCSR04_H_
#define HCSR04_H_
#include "main.h"
typedef struct
{
uint8_t edge_state;
uint16_t tim_overflow_counter;
uint32_t prescaler;
uint32_t period;
uint32_t t1; // 上升沿時(shí)間
uint32_t t2; // 下降沿時(shí)間
uint32_t high_level_us; // 高電平持續(xù)時(shí)間
float distance;
TIM_TypeDef* instance;
uint32_t ic_tim_ch;
HAL_TIM_ActiveChannel active_channel;
}Hcsr04InfoTypeDef;
extern Hcsr04InfoTypeDef Hcsr04Info;
/**
* @description: 超聲波模塊的輸入捕獲定時(shí)器通道初始化
* @param {TIM_HandleTypeDef} *htim
* @param {uint32_t} Channel
* @return {*}
*/
void Hcsr04Init(TIM_HandleTypeDef *htim, uint32_t Channel);
/**
* @description: HC-SR04觸發(fā)
* @param {*}
* @return {*}
*/
void Hcsr04Start(void);
/**
* @description: 定時(shí)器計(jì)數(shù)溢出中斷處理函數(shù)
* @param {*} main.c中重定義void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
* @return {*}
*/
void Hcsr04TimOverflowIsr(TIM_HandleTypeDef *htim);
/**
* @description: 輸入捕獲計(jì)算高電平時(shí)間->距離
* @param {*} main.c中重定義void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
* @return {*}
*/
void Hcsr04TimIcIsr(TIM_HandleTypeDef* htim);
/**
* @description: 讀取距離
* @param {*}
* @return {*}
*/
float Hcsr04Read(void);
#endif /* HCSR04_H_ */
驅(qū)動(dòng)文件里面函數(shù)的具體使用都有介紹,我就不做過(guò)多解釋了。
2、添加中斷回調(diào)函數(shù)
如果有了解過(guò)超聲波的工作原理的話(huà)就可以知道使用到了定時(shí)器,我們還配置了TIM4一通道為輸入捕獲,所以我們需要輸出捕獲中斷和定時(shí)器溢出中斷的回調(diào)函數(shù)。
/* USER CODE BEGIN 4 */
/**
* @description: 定時(shí)器輸入捕獲中斷
* @param {TIM_HandleTypeDef} *htim
* @return {*}
*/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
Hcsr04TimIcIsr(htim);
}
/**
* @description: 定時(shí)器溢出中斷
* @param {*}
* @return {*}
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
Hcsr04TimOverflowIsr(htim);
}
/* USER CODE END 4 */
示例:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-433102.html
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_TIM4_Init();
/* USER CODE BEGIN 2 */
Hcsr04Init(&htim4, TIM_CHANNEL_1); // 超聲波模塊初始化
Hcsr04Start(); // 開(kāi)啟超聲波模塊測(cè)距
printf("hc-sr04 start!\r\n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// 打印測(cè)距結(jié)果
Hcsr04Start();
printf("distance:%.1f cm\r\n", Hcsr04Read());
HAL_Delay(300); // 測(cè)距周期300ms
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
效果圖如下:
發(fā)送端發(fā)送一個(gè)大于10us的高電平,發(fā)送結(jié)束后接收端立即置高,當(dāng)接收到返回的聲波信號(hào)時(shí)置低,所以在輸入捕獲的接收函數(shù)中有將上升沿捕獲改為下降沿捕獲的做法,也可以直接將輸入捕獲設(shè)置兩個(gè)通道,一個(gè)上升沿一個(gè)下降沿。
如果有什么錯(cuò)誤歡迎大家指正。謝謝啦文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-433102.html
到了這里,關(guān)于【CubeMX配置STM32驅(qū)動(dòng)超聲波模塊(HC-SR04)】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!