完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1. 准备工作
硬件准备 首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi): 超声波模块使用HC-SR04,如图: 该模块的四个引脚说明如下表: 超声波模块测距原理 如图,超声波模块发出超声波信号,如果前方碰到障碍物,则被障碍物反射回来,模块收到回来的超声波后,即可计算出与障碍物的距离: HR-SC04模块工作原理 HR-SC04模块的时序图如下: 根据该时序图,可以看出一次测距的流程如下: 触发信号由Trig引脚输入,10us的高电平即可触发一次测距; 触发后,距离信息由Echo引脚输出,该输出信号的高电平时间与检测距离成比例; 在整个测距过程中,最重要的是Echo引脚输出信号高电平的时间,可以使用STM32硬件定时器得到时长,这个时间为超声波从发射到接收的时长,由声速计算出传播距离,再取1/2,计算出当前距离障碍物的距离。 软件准备 需要安装好Keil - MDK及芯片对应的包,以便编译和下载生成的代码。 2.生成MDK工程 选择芯片型号 打开STM32CubeMX,打开MCU选择器: 搜索并选中芯片STM32L431RCT6: 配置时钟源 如果选择使用外部高速时钟(HSE),则需要在System Core中配置RCC; 如果使用默认内部时钟(HSI),这一步可以略过; 这里我都使用外部时钟: 配置GPIO 配置两个普通的GPIO,一个配置为输出模式,用于连接模块的Trig引脚,触发一次测距,这里我配置为PB8,另一个配置为输入模式(浮空),用于连接模块的Echo引脚,接收echo信号,这里我配置为PB9。 配置通用定时器TIM2 知识小卡片——STM32L431的定时器 STM32L431xx 系列有 1 个高级定时器(TIM1), 3 个通用定时器(TIM2、TIM15、TIM16),两个基本定时器(TIM6、TIM7),还有两个低功耗定时器(LPTIM1、LPTIM2)。 STM32L431 的通用 TIMx (TIM2、TIM15、TIM16)定时器功能包括: 16 位(TIM15,TIM16)/32 位(TIM2)向上、向下、向上/向下自动装载计数器,注意: TIM15、TIM16 只支持向上(递增)计数方式; 16 位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为 1~65535 之间的任 意数值。 4 个独立通道(TIMx_CH1~4, 其中 TIM15 最多 2 个通道, TIM16 最多 1 个 通道),这些通道可以用来作为: 输入捕获 输出比较 PWM 生成(边缘或中间对齐模式) 单脉冲模式输出 可使用外部信号控制定时器和定时器互连的同步电路。 如下事件发生时产生中断/DMA: 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) 输入捕获 输出比较 知识小卡片结束啦~ 接下来开始配置TIM2,首先选择TIM2,我们的目的是每1us计数一次 ,所以定时器的频率需要在1Mhz, 时钟源选择内部时钟: 接下来是对TIM2的参数设置,参照数据手册中的RCC时钟树,TIM2内部时钟来源是PCLK1 = 80Mhz,,所以预分频系数设置为80,即可得到1Mhz的计数频率。 计数周期设为60000,实际测试情况下,大约60000us对应的实际距离是10m(实际中也用不到这么大): 配置串口 开发板板载了一个CH340换串口,连接到USART1。 接下来开始配置USART1: 配置时钟树 STM32L4的最高主频到80M,所以配置PLL,最后使HCLK = 80Mhz即可: 生成工程设置 代码生成设置 最后设置生成独立的初始化文件: 生成代码 点击GENERATE CODE即可生成MDK-V5工程: 3. 在MDK中编写、编译、下载用户代码 1. printf重定向 2. 添加us级延时函数 使用时注意根据自己的处理器主频修改: 3. 编写驱动 因为超声波模块往往需要多个,所以采用面向对象的思想设计,将每个模块封装为一个设备对象。 HC_SR04.h /** * @Copyright (c) 2021,mculover666 All rights reserved * @filename HC_SR04.c * @breif Drive HC_SR04 based on stm32 tim peripheral * @changelog v1.0 mculover666 2021/5/9 * v1.1 mculover666 2021/5/12 add object design */ #ifndef _HC_SR04_H_ #define _HC_SR04_H_ #include “stm32f1xx.h” #include “core_delay.h” typedef struct hc_sr04_device_st { GPIO_TypeDef *trig_port; uint16_t trig_pin; GPIO_TypeDef *echo_port; uint16_t echo_pin; TIM_HandleTypeDef *tim; //us级硬件定时器 double distance; //测算距离 } hc_sr04_device_t; /* us级延时函数 */ #define HC_SR04_Delay_Us(n) CPU_TS_Tmr_Delay_US(n) void HC_SR04_Init(hc_sr04_device_t *hc_sr04_device); int HC_SR04_Measure(hc_sr04_device_t *hc_sr04_device); #endif /* _HC_SR04_H_ */ HC_SR04.c /** * @Copyright (c) 2021,mculover666 All rights reserved * @filename HC_SR04.c * @breif Drive HC_SR04 based on stm32 tim peripheral * @changelog v1.0 mculover666 2021/5/9 * v1.1 mculover666 2021/5/12 add object design */ #include “HC_SR04.h” #include 《stdio.h》 /** * @brief pend the mutex to protect tim. * @param none * @return none * @note it will be need if you use rtos */ static void HC_SRO4_Mutex_Pend() { //add your code here } /** * @brief post the mutex to protect tim. * @param none * @return none * @note it will be need if you use rtos */ static void HC_SRO4_Mutex_Post() { //add your code here } /** * @brief hc_sr04_device object initialization. * @param hc_sr04_device the pointer of the hc_sr04_device_t object * @return none */ void HC_SR04_Init(hc_sr04_device_t *hc_sr04_device) { // the gpio and tim is initialized in main } /** * @brief Send trig signal. * @param hc_sr04_device the pointer of the hc_sr04_device_t object * @return none */ static void HC_SR04_Start(hc_sr04_device_t *hc_sr04_device) { /* output high level */ HAL_GPIO_WritePin(hc_sr04_device-》trig_port, hc_sr04_device-》trig_pin, GPIO_PIN_SET); /* maintain high level at least 10us */ CPU_TS_Tmr_Delay_US(10); /* resume low level */ HAL_GPIO_WritePin(hc_sr04_device-》trig_port, hc_sr04_device-》trig_pin, GPIO_PIN_RESET); } /** * @brief Measure the high level time of the echo signal. * @param hc_sr04_device the pointer of the hc_sr04_device_t object * @return errcode * @retval 0 success * @retval -1 fail */ int HC_SR04_Measure(hc_sr04_device_t *hc_sr04_device) { uint32_t tick_us; HC_SRO4_Mutex_Pend(); HC_SR04_Start(hc_sr04_device); __HAL_TIM_SetCounter(hc_sr04_device-》tim, 0); /* waitting for start of the high level through echo pin */ while (HAL_GPIO_ReadPin(hc_sr04_device-》echo_port, hc_sr04_device-》echo_pin) == GPIO_PIN_RESET); /* start the tim and enable the interrupt */ HAL_TIM_Base_Start(hc_sr04_device-》tim); /* waitting for end of the high level through echo pin */ while (HAL_GPIO_ReadPin(hc_sr04_device-》echo_port, hc_sr04_device-》echo_pin) == GPIO_PIN_SET); /* stop the tim */ HAL_TIM_Base_Stop(hc_sr04_device-》tim); /* get the time of high level */ tick_us = __HAL_TIM_GetCounter(hc_sr04_device-》tim); /* calc distance in unit cm */ hc_sr04_device-》distance = (double)(tick_us/1000000.0) * 340.0 / 2.0 *100.0; HC_SRO4_Mutex_Post(); return 0; } 测试结果 在main.c中包含驱动头文件: #include 《stdio.h》 #include “HC_SR04.h” 在main函数中创建设备对象: /* USER CODE BEGIN 1 */ int ret; hc_sr04_device_t hc_sr04_device1; /* USER CODE END 1 */ 编写测试代码: /* USER CODE BEGIN 2 */ printf(“HC-SR04 Module Test By Mculover666rn”); hc_sr04_device1.trig_port = GPIOB; hc_sr04_device1.trig_pin = GPIO_PIN_8; hc_sr04_device1.echo_port = GPIOB; hc_sr04_device1.echo_pin = GPIO_PIN_9; hc_sr04_device1.tim = &htim2; HC_SR04_Init(&hc_sr04_device1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ ret = HC_SR04_Measure(&hc_sr04_device1); if (ret 《 0) { printf(“measure failrn”); } printf(“distance:%.2f cmrn”, hc_sr04_device1.distance); HAL_Delay(1000); } /* USER CODE END 3 */ 测试结果为: |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1602 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1536 浏览 1 评论
967 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
680 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1579 浏览 2 评论
1860浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
640浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
513浏览 3评论
525浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
500浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-19 04:23 , Processed in 0.838296 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号