实验三 您所在的位置:网站首页 测距抓拍 实验三

实验三

2024-07-07 11:11| 来源: 网络整理| 查看: 265

实验三—红外超声波雷达测距 实验内容与要求: 一. 采用stm32F103和HC-SR04超声波模块, 使用标准库或HAL库+ 定时器中断,完成1或2路的超声波障碍物测距功能。 1)测试数据包含噪声,程序需要进行滤波处理;将测距数值通过串口上传到上位机串口助手; 2)根据障碍物距离远近,控制一个蜂鸣器(可以用LED灯代替)发出频率不同的声音(或LED不同闪烁),即输出占空比变化的PWM波形; 3)在没有超声波模块硬件的场景下,先使用Keil中的仿真逻辑分析仪,观察分析对应管脚上的时序波形,判读是否符合协议规范。 HC-SR04基本工作原理: (1)采用IO口TRIG触发测距,给最少10us的高电平信呈。 (2)模块自动发送8个40khz的方波,自动检测是否有信号返回; (3)有信号返回, 通过IO口ECHO输出一个高电平, 高电平持续的时间就是超声波从发射到返回的时间。 引脚连接: VCC --> VCC GND --> GND Trig --> PA5 Echo --> PA0 CubeMX配置:

1、RCC配置外部高速晶振——HSE

2、SYS配置:Debug设置成Serial Wire

ADC1配置:配置ADC-IN1模数转换

TIM2配置:设置定时器TIM2每1us向上计数一次,通道1为上升沿捕获并连接到超声波模块的ECHO引脚

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GPIO配置:PA5接到了HC-SR04的TRIG触发引脚,默认输出低电平

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

TIM1配置:由上面可知HC-SR04的使用需要us级的延迟函数,HAL库自带只有ms的,所以需要自己设计一个定时器外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

超声波模块代码:

HC-SR04.h:

#ifndef HCSR04_H_ #define HCSR04_H_ #include "main.h" #include "delay.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(); /** * @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(); #endif /* HCSR04_H_ */

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-1 Hcsr04Info.period = htim->Init.Period; // 65535 Hcsr04Info.instance = htim->Instance; // TIM2 Hcsr04Info.ic_tim_ch = Channel; if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_1) { Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_1; // TIM_CHANNEL_4 } else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_2) { Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_2; // TIM_CHANNEL_4 } else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_3) { Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_3; // TIM_CHANNEL_4 } else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_4) { Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_4; // TIM_CHANNEL_4 } 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() { HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET); DelayUs(10); // 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) // TIM2 { 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() { // 测距结果限幅 if(Hcsr04Info.distance >= 500) { Hcsr04Info.distance = 500; //元器件资料说是600cm最高距离,这里保守一点 } return Hcsr04Info.distance; } /* 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 */

ranging.h:

#ifndef __SHARP2Y0A21_H #define __SHARP2Y0A21_H #include "main.h" #define Adc1IN1Distance_READ_TIMES 10 //定义红外传感器读取次数,以便取平均值 void DistanceSensor_Init(void); //初始化红外传感器 float DistanceSensor_Get_Val(void); //读取红外传感器的值 #endif

ranging.c:

#include "sharp.h" #include "adc.h" #include "main.h" #include "stdio.h" //初始化ADC,不用修改 //这里我们仅以规则通道为例 //初始化传感器,需要修改端口和引脚号,这里是c出口,c1引脚,ADC1的IN1 void DistanceSensor_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; __HAL_RCC_GPIOA_CLK_ENABLE();//使能GPIOA时钟 //先初始化ADC1通道11 IO口 GPIO_InitStructure.Pin = GPIO_PIN_1;//PA1 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;//模拟输入 GPIO_InitStructure.Pull = GPIO_NOPULL ;//不带上下拉 HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 MX_ADC1_Init();//初始化ADC1 } //PA1=IN1 float DistanceSensor_Get_Val(void) { uint32_t temp_val=0; float distemp=0.0; uint8_t t; for(t=0;t


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有