【CubeMX配置STM32驱动超声波模块(HC-SR04)】
CubeMX配置STM32以驱动超声波模块(HC-SR04)
一、CubeMX配置STM32 |
1、选择定时器
选择输入捕获模式
预分频设置为71,向上计数,自动重装值65535
然后将名字改为ECHO
2、配置TRIG口
这里的端口使用其它空闲的IO口是可以的,设置为输出模式,其它配置不需要改变,最主要的是User Label那儿,需要设置为TRIG,因为驱动函数里面使用的是这个的宏定义,所以必须要改成这个名字才能直接使用驱动函数。
3、配置串口
因为要显示超声波测出的距离,我这里就直接使用串口助手显示了,有需要的话使用OLED、TFT之类的模块显示也可以。
在这里如果需要使用printf函数的话,还需要在生成的usart.c里面添加fputc函数
:
/*********************************************************
*
*重定义 fputc 函数
*
*********************************************************/
int fputc(int ch,FILE *f)
{HAL_UART_Transmit (&huart1 ,(uint8_t *)&ch,1,HAL_MAX_DELAY );return ch;
}
在这之前记得引入头文件stdio.h
、勾选Use MicroLIB
二、使用keil5进行进一步开发 |
1、引入HC-SR04的驱动文件
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: 超声波模块的输入捕获定时器通道初始化* @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-1Hcsr04Info.period = htim->Init.Period; // 65535Hcsr04Info.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);
}/*** @description: HC-SR04触发* @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: 定时器计数溢出中断处理函数* @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: 输入捕获计算高电平时间->距离* @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) // 捕获上升沿{// 得到上升沿开始时间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; // 定时器溢出计数器清零Hcsr04Info.edge_state = 1; // 上升沿、下降沿捕获标志位}else if(Hcsr04Info.edge_state == 1) // 捕获下降沿{// 捕获下降沿时间T2,并计算高电平时间Hcsr04Info.t2 = HAL_TIM_ReadCapturedValue(htim, Hcsr04Info.ic_tim_ch);Hcsr04Info.t2 += Hcsr04Info.tim_overflow_counter * Hcsr04Info.period; // 需要考虑定时器溢出中断Hcsr04Info.high_level_us = Hcsr04Info.t2 - Hcsr04Info.t1; // 高电平持续时间 = 下降沿时间点 - 上升沿时间点// 计算距离Hcsr04Info.distance = (Hcsr04Info.high_level_us / 1000000.0) * 340.0 / 2.0 * 100.0;// 重新开启上升沿捕获Hcsr04Info.edge_state = 0; // 一次采集完毕,清零__HAL_TIM_SET_CAPTUREPOLARITY(htim, Hcsr04Info.ic_tim_ch, TIM_INPUTCHANNELPOLARITY_RISING);}}
}/*** @description: 读取距离 * @param {*}* @return {*}*/
float Hcsr04Read(void)
{// 测距结果限幅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; // 上升沿时间uint32_t t2; // 下降沿时间uint32_t high_level_us; // 高电平持续时间float distance;TIM_TypeDef* instance;uint32_t ic_tim_ch;HAL_TIM_ActiveChannel active_channel;
}Hcsr04InfoTypeDef;extern Hcsr04InfoTypeDef Hcsr04Info;/*** @description: 超声波模块的输入捕获定时器通道初始化* @param {TIM_HandleTypeDef} *htim* @param {uint32_t} Channel* @return {*}*/
void Hcsr04Init(TIM_HandleTypeDef *htim, uint32_t Channel);/*** @description: HC-SR04触发* @param {*}* @return {*}*/
void Hcsr04Start(void);/*** @description: 定时器计数溢出中断处理函数* @param {*} main.c中重定义void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)* @return {*}*/
void Hcsr04TimOverflowIsr(TIM_HandleTypeDef *htim);/*** @description: 输入捕获计算高电平时间->距离* @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_ */
驱动文件里面函数的具体使用都有介绍,我就不做过多解释了。
2、添加中断回调函数
如果有了解过超声波的工作原理的话就可以知道使用到了定时器,我们还配置了TIM4一通道为输入捕获,所以我们需要输出捕获中断和定时器溢出中断的回调函数。
/* USER CODE BEGIN 4 */
/*** @description: 定时器输入捕获中断* @param {TIM_HandleTypeDef} *htim* @return {*}*/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{Hcsr04TimIcIsr(htim);
}/*** @description: 定时器溢出中断* @param {*}* @return {*}*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{Hcsr04TimOverflowIsr(htim);
}
/* USER CODE END 4 */
示例:
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(); // 开启超声波模块测距printf("hc-sr04 start!\r\n");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){// 打印测距结果Hcsr04Start();printf("distance:%.1f cm\r\n", Hcsr04Read());HAL_Delay(300); // 测距周期300ms/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
效果图如下:
如果有什么错误欢迎大家指正。谢谢啦
【CubeMX配置STM32驱动超声波模块(HC-SR04)】相关推荐
- CubeMX配置STM32实现httpd服务器CGI功能并使用网页控制STM32单片机(四)
CubeMX配置STM32实现httpd服务器CGI功能并使用网页控制STM32单片机 引言 CubeMX配置HTTPD的CGI功能 实验过程 发现的问题 总结 引言 在前三篇文章中自己介绍了如何配置 ...
- 【CubeMX配置STM32的ADC】
CubeMX配置STM32的ADC 包含阻塞式和非阻塞式以及多通道ADC 一.CubeMX配置STM32 1.单通道ADC 单通道的配置比较简单,需要注意的是需要中断的使能,因为在使用非阻塞式的函数时 ...
- CUBEMX配置STM32实现FTP文件传输以及使用SNTP获取网络时间并写入RTC
CUBEMX配置STM32实现FTP文件传输以及使用SNTP获取网络时间并写入RTC 引言 FTP代码库的移植 Cubemx配置SNTP以及RTC RTC配置方法 SNTP配置方法 FATFS载入RT ...
- 【STM32训练—WiFi模块】第一篇、STM32驱动ESP8266WiFi模块获取网络时间
目录 第一部分.写在前面 1.硬件准备 2.相关的AT指令 3.参考博客 第二部分.电脑串口助手调试ESP8266模块获取网络时间 1.ESP8266获取时间的流程 2.具体实现步骤 第三部分.STM ...
- 【CubeMX配置stm32定时器中断】
CubeMX配置stm32定时器中断 一.使用CubeMX对STM32进行基础的配置 1.选择需要使用的定时器 选择TIM2和TIM3示例, 注意: TIM2和其它定时器选择时钟的方法不同,TIM3等 ...
- 【CubeMX配置STM32使用360°旋转编码器(KY-040)】
CubeMX配置STM32使用360°旋转编码器(KY-040) 一.使用CubeMX进行基本的配置 所使用编码器的图片为: 在编码电机上面的编码器与这个的使用方法类似. 选择编码器模式 另外还需要选 ...
- STM32F1驱动超声波模块实验
超声波模块测得的距离一直是固定值的同仁看过来: 如果你是用3.3v给开发板供电,但用到了开发板的5v给HC-SR04供电,那么你就和我掉进的同一个坑 出现这个问题的原因是STM32开发板一般没有升压芯 ...
- STM32驱动RC522-RFID模块
简介:STM32F103C8T6驱动RC522-RFID模块源码介绍. 开发平台:KEIL ARM MCU型号:STM32F103C8T6 传感器型号:RC522-RFID 特别提示:驱动内可能使用了 ...
- FPGA实例06——FPGA驱动超声波模块
目录 1.超声波模块原理 2.测试框架 3.FPGA驱动代码 3.1 超声波模块(ultrasonic) 3.2 串口发送模块 3.3 顶层模块 4.测试情况 1.超声波模块原理 此处的超声波模块为H ...
最新文章
- appium+python自动化测试教程_Python+Appium实现自动化测试
- html表格标签模板 实现跨行和跨列
- 【绝对干货】北京三年java开发多少工资
- 窗体DataGridView控件中按回车键时,单元格向下移动,如何能改成向右移动
- 【新星计划】MATLAB绘制图形
- matlab入门之旅,MATLAB 入门之旅学习笔记
- 三星智能家居系统频繁故障 大批用户受到影响
- 关于编写流程的一些经验
- centos smb配置与win7共享
- Windows10+Ubuntu 18.04.2+ROS 安装笔记(SSD单硬盘)上
- php 两个数组 交集_两个数组的交集
- 【java】高并发之限流 RateLimiter使用
- java面试 谈谈jvm内存结构
- SurfaceFlinger draw/render/display流程(fps)
- 分布式缓存的面试题2
- Android Studio couldn‘t generate bytecode view, no .class file found
- java weblogic 下载,weblogic 下载 weblogic 12.2.1 for windows 64位的下载地址
- kali虚拟机安装教程(超详细)
- 交换机常用配置命令(华为)
- css基础,HTML引入scc的三种方法