当前位置: 首页 > news >正文

超声波的应用

功能实现请看最顶端视频

配合舵机实现指定距离转动功能:

主函数代码:

主函数部分: 首先定义了一个用于调整电机 PWM 值的变量 pwmval 和用于存储超声波测量距离的变量 length。

调用 HC_SR04Config 函数配置超声波传感器,usart_init 函数初始化串口通信,motor_config 函数配置电机。

在无限循环中,不断调用 Getlength 函数获取超声波传感器测量的距离,并通过串口打印输出。然后根据距离判断条件,调整电机的 PWM 值。如果距离小于 5,则逐渐减小 PWM 值;如果距离大于 5,则将 PWM 值减去 20。

// 包含必要的头文件
#include "stm32f10x.h"
#include "systick.h"
#include "led.h"
#include "HC_SR04.h"
#include "usart.h"
#include "motor.h"// 定义延时函数
void delay(uint16_t time)
{uint16_t i = 0;while (time--){// 设置一个较大的循环次数进行延时i = 12000;while (i--);}
}int main()
{// 初始化 PWM 值int pwmval = 195;// 用于存储超声波测量的距离float length = 0;// 配置 HC-SR04 超声波传感器HC_SR04Config();// 初始化串口通信usart_init();// 配置电机motor_config();while (1){// 获取超声波传感器测量的距离,保留三位小数length = Getlength();printf("%.3f\r\n", length);// 延时 50 毫秒ms_delay(50);// 如果距离小于 5if (length < 5){// 逐渐减小 PWM 值for (pwmval = 195; pwmval >= 155; pwmval -= 15){// 设置 TIM3 的通道 2 比较值TIM_SetCompare2(TIM3, pwmval);// 延时 500 毫秒delay(500);}}// 如果距离大于 5else if (length > 5){// 调整 PWM 值TIM_SetCompare2(TIM3, pwmval - 20);}}
}

舵机代码:

电机配置函数部分(motor_config): 首先定义了一些结构体变量用于配置 GPIO 和 TIM 相关参数。 通过时钟使能函数使能了 GPIOB、TIM3 和复用功能时钟。

配置 GPIO 为部分重映射,并将 GPIOB 的引脚 5 配置为复用推挽输出模式,用于连接电机。

配置 TIM3 的时钟分割、计数模式、周期和预分频值,以及通道 2 的 PWM 模式、输出状态和极性。最后使能 TIM3。

#include "stm32f10x.h"
#include "motor.h"// 舵机配置函数
void motor_config(void)
{GPIO_InitTypeDef         GPIO_Motorinit;TIM_TimeBaseInitTypeDef  TIM_Motorinit;TIM_OCInitTypeDef        TIMPWM_Motorinit;// 使能 GPIOB 时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);// 使能 TIM3 时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);// 使能复用功能时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);// 配置 GPIO 为部分重映射GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);// 配置 GPIOB 的引脚 5 为复用推挽输出模式,速度为 50MHzGPIO_Motorinit.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Motorinit.GPIO_Pin = GPIO_Pin_5;GPIO_Motorinit.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_Motorinit);// 配置 TIM3 的时钟分割、计数模式、周期和预分频值TIM_Motorinit.TIM_ClockDivision = TIM_CKD_DIV1;       // 设置时钟分割TIM_Motorinit.TIM_CounterMode = TIM_CounterMode_Up;   // TIM 向上计数模式TIM_Motorinit.TIM_Period = 200 - 1;                   // 设置下一个更新事件的周期TIM_Motorinit.TIM_Prescaler = 7200 - 1;                // 设置预分频周期,用于 TIM 的时钟预分频TIM_TimeBaseInit(TIM3, &TIM_Motorinit);// 配置 TIM3 的通道 2 为 PWM1 模式,使能输出,低电平有效TIMPWM_Motorinit.TIM_OCMode = TIM_OCMode_PWM1;        // 选择定时器模式 1TIMPWM_Motorinit.TIM_OutputState = TIM_OutputState_Enable; // 使能比较输出TIMPWM_Motorinit.TIM_OCPolarity = TIM_OCPolarity_Low;  // 设置有效输出极性为低电平TIM_OC2Init(TIM3, &TIMPWM_Motorinit);  // 初始化 TIM3 通道 2TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);// 使能 TIM3TIM_Cmd(TIM3, ENABLE);
}

超声波传感器代码:

超声波传感器配置函数部分(HC_SR04Config): 定义了一些结构体变量用于配置 GPIO 和 TIM 以及 NVIC 相关参数。 使能了 GPIOB 和 TIM4 的时钟,并配置 NVIC 优先级分组为 1。 将 GPIOB 的引脚 11(Trig 引脚)配置为推挽输出模式,引脚 10(ECHO 引脚)配置为浮空输入模式。 配置 TIM4 的时钟分割、计数模式、周期和预分频值,并使能 TIM4 的更新中断。最后配置 TIM4 中断的优先级并初始化 NVIC。

#include "stm32f10x.h"
void HC_SR04Config(void);
void Open_tim4(void);
void Close_tim4(void);
int GetEcho_time(void);
float Getlength(void);
void TIM4_IRQHandler(void);// 宏定义,用于读取 ECHO 引脚的输入电平
#define ECHO_Reci  GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)
// 宏定义,用于设置 TRIG 引脚的输出电平
#define TRIG_Send(a) if(a) \GPIO_SetBits(GPIOB, GPIO_Pin_11); \else \GPIO_ResetBits(GPIOB, GPIO_Pin_11);\#include "HC_SR04.h"
#include "stm32f10x.h"
#include "systick.h"// 外部变量,用于存储毫秒计数
extern uint16_t mscount = 0;// HC-SR04 超声波传感器配置函数
void HC_SR04Config(void)
{GPIO_InitTypeDef GPIO_hcsr04init;TIM_TimeBaseInitTypeDef TIM_hcsr04init;NVIC_InitTypeDef NVIC_hcsr04init;// 使能 GPIOB 时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);// 使能 TIM4 时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);// 配置 NVIC 优先级分组为 1NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);// 配置 Trig 引脚(PB11)为推挽输出模式GPIO_hcsr04init.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_hcsr04init.GPIO_Pin = GPIO_Pin_11;GPIO_hcsr04init.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_hcsr04init);// 配置 ECHO 引脚(PB10)为浮空输入模式GPIO_hcsr04init.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_hcsr04init.GPIO_Pin = GPIO_Pin_10;GPIO_Init(GPIOB, &GPIO_hcsr04init);// 配置 TIM4 的时钟分割、计数模式、周期和预分频值TIM_hcsr04init.TIM_ClockDivision = TIM_CKD_DIV1;TIM_hcsr04init.TIM_CounterMode = TIM_CounterMode_Up;TIM_hcsr04init.TIM_Period = 1000 - 1;TIM_hcsr04init.TIM_Prescaler = 72 - 1;// 初始化 TIM4TIM_TimeBaseInit(TIM4, &TIM_hcsr04init);// 使能 TIM4 的更新中断TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);// 禁用 TIM4TIM_Cmd(TIM4, DISABLE);// 配置 TIM4 中断的优先级NVIC_hcsr04init.NVIC_IRQChannel = TIM4_IRQn;NVIC_hcsr04init.NVIC_IRQChannelPreemptionPriority = 0;NVIC_hcsr04init.NVIC_IRQChannelSubPriority = 0;NVIC_hcsr04init.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_hcsr04init);
}// 打开 TIM4
void Open_tim4(void)
{// 将 TIM4 的计数器清零TIM_SetCounter(TIM4, 0);// 重置毫秒计数mscount = 0;// 使能 TIM4TIM_Cmd(TIM4, ENABLE);
}// 关闭 TIM4
void Close_tim4(void)
{// 禁用 TIM4TIM_Cmd(TIM4, DISABLE);
}// TIM4 中断服务函数
void TIM4_IRQHandler(void)
{if (TIM_GetITStatus(TIM4, TIM_IT_Update)!= RESET){// 清除 TIM4 的更新中断标志TIM_ClearITPendingBit(TIM4, TIM_IT_Update);// 增加毫秒计数mscount++;}
}// 获取回声时间
int GetEcho_time(void)
{uint32_t t = 0;t = mscount * 1000;t += TIM_GetCounter(TIM4);// 将 TIM4 的计数器清零TIM4->CNT = 0;// 延时 50 毫秒ms_delay(50);return t;
}// 获取超声波距离
float Getlength(void)
{int i = 0;uint32_t t = 0;float length = 0;float sum = 0;while (i!= 5){// 设置 TRIG 引脚为高电平TRIG_Send(1);// 延时 20 微秒us_delay(20);// 设置 TRIG 引脚为低电平TRIG_Send(0);while (ECHO_Reci == 0);// 打开 TIM4Open_tim4();i = i + 1;while (ECHO_Reci == 1);// 关闭 TIM4Close_tim4();t = GetEcho_time();// 根据时间计算距离length = ((float)t / 58.0);sum = sum + length;}// 计算平均距离length = sum / 5.0;return length;
}

Open_tim4 函数用于打开 TIM4,将计数器清零,重置毫秒计数并使能 TIM4。

Close_tim4 函数用于关闭 TIM4。

TIM4_IRQHandler 是 TIM4 的中断服务函数,当 TIM4 发生更新中断时,清除中断标志并增加毫秒计数。

GetEcho_time 函数用于获取回声时间,通过读取毫秒计数和 TIM4 的计数器值计算得到。

Getlength 函数用于获取超声波距离,通过多次测量取平均值的方式提高测量精度。首先发送触发信号,然后等待回声信号,记录时间并计算距离,最后返回平均距离。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • AOP和注解的配合使用(封装通用日志处理类)
  • 2 html5 浏览器已经支持的新API
  • 腾讯云技术深度解析:AI代码助手与微服务架构的实践应用
  • 服务器数据恢复—如何应对双循环RAID5阵列的数据丢失问题?
  • 【初出江湖】分布式之什么是分布式存储?
  • P-Tuning v2:一种普遍有效的提示调整方法
  • 三分钟搭建线上RAG应用,实现定制化的知识库问答
  • 解锁企业微信营销新纪元:智驭未来,让每一次触达都精准高效!
  • Tensorflow实现深度学习8:猫狗识别
  • Qt Dialog退出事件
  • AIGC时代从新手到高手:B端竞品分析实战案例与技巧分享
  • 华为Huawei路由器交换机SSH配置
  • 设计模式-结构型模式-组合模式
  • 学习WebGl基础知识(二)
  • Docker原理及实例
  • 30秒的PHP代码片段(1)数组 - Array
  • Angular6错误 Service: No provider for Renderer2
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • css的样式优先级
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • laravel5.5 视图共享数据
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • 初识 beanstalkd
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 巧用 TypeScript (一)
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 限制Java线程池运行线程以及等待线程数量的策略
  • No resource identifier found for attribute,RxJava之zip操作符
  • puppet连载22:define用法
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ### RabbitMQ五种工作模式:
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (09)Hive——CTE 公共表达式
  • (2024)docker-compose实战 (9)部署多项目环境(LAMP+react+vue+redis+mysql+nginx)
  • (3)nginx 配置(nginx.conf)
  • (k8s)Kubernetes本地存储接入
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (翻译)terry crowley: 写给程序员
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • .JPG图片,各种压缩率下的文件尺寸
  • .net CHARTING图表控件下载地址
  • .net 简单实现MD5
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • @DependsOn:解析 Spring 中的依赖关系之艺术
  • @Slf4j idea标红Cannot resolve symbol ‘log‘
  • [240527] 谷歌 CEO 承认 AI 编造虚假信息问题难解(此文使用 @gemini 命令二次创作)| ICQ 停止运作
  • [AIGC] MySQL存储引擎详解
  • [Android学习笔记]ScrollView的使用
  • [ARC066F]Contest with Drinks Hard