这段时间算是比较系统的学习了一点stm32相关的东西,驱动超声波测距模块这个简单的小任务综合了定时器,中断,串口三个知识点,拿来练手还是挺不错的
以上是该模块原理的简介,就我个人体验而言,实际使用中,HC-SR04的稳定性可以说是很不错的, 测距的精度与范围基本上可以满足大部分小型项目的需求,最关键的一点,它的驱动非常的简单(虽然这并不影响菜鸡的我搞了3天才弄成)
那么简单说一下驱动的注意事项,由于模块所需要的供电是5V,而板子能直接供的电压只有3V3,因此我拿了个充电宝来当电源,当然,如果有锂电池啥的就更好了
其次,引脚设置时不要弄反,TRIG引脚作为输出,而ECHO引脚作为输入
我所实现的功能是超声波模块用来读取距离数据,用串口将数据打印到屏幕上
那么废话完毕,开始上图上代码:
cubemx内部的设置如图所示
这是引脚的设置,我启用了定时器TIM2用来记时,以及它的2通道用来做输入捕获,顺便启用了一下串口
中断的设置如图所示,使能了定时器中断和串口中断(其实串口中断不需要使能,我只是随手点了而已)
定时器2的设置如图所示,分频设为80,重载值设为10000 ,捕获触发设为下降沿
然后就可以愉快的生成工程文件了
关于具体的测距程序,只能说一切都要跟着原理走,我就很想不开的脱离原理写了一天程序,然后发现自己写得东西一点鬼用没有,于是重新上网去各种借鉴,终于搞清楚自己是哪里出了问题,希望大家以后驱动别的模块时
一 定 要 先 看 懂 原 理!
不然会出各种各样神奇的bug还不知道怎么搞,超声波测距的程序如下,我放在了一个自己创建的soner.c文件里面:
#include "main.h"
#include "stm32f1xx_hal.h"
#include "stm32f1xx_it.h"
static float distance_temp=0;
static float distance_last=0;
static float distance_result;
/*
*********************************************************
函数原型:void Delay_us(uint16_t time)
函数输入:无符号整形
函数输出:无
函数功能:延时,与HAL_Delay类似,但是使用了定时器,Delay_us的单位是1*e-5s
*********************************************************
*/
void Delay_us(uint16_t time)
{
uint16_t a1=TIM2->CNT;
while(TIM2->CNT-a1
然后是头文件soner.h
#ifndef _SONER_H_
#define _SONER_H_
void Delay_us(uint16_t time);
void soner_startrange(void);
float soner_getdistance(void);
uint16_t soner_gettime(void);
#endif
最后在main.c里面调用以上函数就行了,简简单单轻轻松松
#include "main.h"
#include "stm32f1xx_hal.h"
/* USER CODE BEGIN Includes */
#include
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim2;
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
static float distance=0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM2_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
#undef __GNUC__
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int _io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch,FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);
return ch;
}
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
*
* @retval None
*/
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_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
distance=soner_getdistance();
printf("%.2f\n",distance);
HAL_Delay(50);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
另外专门需要提一句的是,我在main.h内定义了引脚SONER_PORT,SONER_ECHO_PIN和SONER_TRIG_PIN,代码如下:
#ifndef __MAIN_H__
#define __MAIN_H__
/* Includes ------------------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private define ------------------------------------------------------------*/
#define SONER_PORT GPIOA
#define SONER_ECHO_PIN GPIO_PIN_1
#define SONER_TRIG_PIN GPIO_PIN_0
初次搞这个东西会是一个漫长的写bug,debug的过程,希望大家一切顺利,我在上一篇文章里提到了一些我自己遇到的比较坑的error,大家有兴趣可以看一下
以上
p.s以上代码的具体原理,大家可以自己去搜索stm32的定时器,中断,输入捕获,串口等关键词去找教程,当然,说不定某一天我这只鸽子会开个视频详细一点讲讲这边的东西
咕咕咕,咕咕咕