STM32 HAL库 HC - SR04 超声波测距模块驱动实现

news2025/4/17 7:35:23

一、引言

在现代嵌入式系统开发中,传感器技术起着至关重要的作用。超声波测距模块作为一种常用的距离测量传感器,因其成本低、精度较高、使用方便等优点,被广泛应用于机器人避障、液位检测、工业自动化等领域。HC - SR04 超声波测距模块是一款常见的超声波测距传感器,它可以方便地与微控制器进行连接,实现距离的测量。本文将详细介绍如何基于 STM32F407 的 HAL 库来驱动 HC - SR04 超声波测距模块。

二、HC - SR04 超声波测距模块概述

2.1 工作原理

HC - SR04 超声波测距模块的工作原理基于超声波在空气中的传播速度是已知的(在常温下约为 340m/s),通过测量超声波从发射到接收的时间差,就可以计算出模块与目标物体之间的距离。具体工作过程如下:

  1. 微控制器向 HC - SR04 的 Trig 引脚发送一个至少 10μs 的高电平脉冲,触发模块发射超声波。
  2. HC - SR04 接收到触发信号后,会自动发射 8 个 40kHz 的超声波脉冲,并将 Echo 引脚置为高电平,开始计时。
  3. 当超声波遇到目标物体后反射回来,HC - SR04 接收到反射波,将 Echo 引脚置为低电平,停止计时。
  4. 微控制器通过测量 Echo 引脚高电平的持续时间 t,根据公式d=v×t/2(其中v为超声波在空气中的传播速度,d为模块与目标物体之间的距离)计算出距离。

2.2 引脚说明

HC - SR04 超声波测距模块有 4 个引脚,分别是:

  • VCC:电源正极,一般接 5V。
  • GND:电源负极,接地。
  • Trig:触发引脚,用于接收微控制器的触发信号。
  • Echo:回响引脚,用于输出超声波从发射到接收的时间信号。

2.3 性能参数

  • 工作电压:5V
  • 工作电流:15mA
  • 探测距离:2cm - 400cm
  • 测量精度:±3mm
  • 探测角度:<15°
  • 超声波频率:40kHz

三、STM32F407 简介

3.1 主要特性

  • 高性能:采用 ARM Cortex - M4 内核,最高主频可达 168MHz,具有丰富的外设资源。
  • 低功耗:支持多种低功耗模式,适用于对功耗要求较高的应用场景。
  • 丰富的外设:包含多个串口、SPI、I2C 等通信接口,以及定时器、ADC、DAC 等功能模块。

3.2 HAL 库

HAL(Hardware Abstraction Layer)库是 ST 公司为 STM32 系列微控制器提供的硬件抽象层库,它简化了开发人员对硬件外设的操作,提高了代码的可移植性和开发效率。

四、硬件连接

将 HC - SR04 超声波测距模块与 STM32F407 开发板进行连接,连接方式如下:

HC - SR04 引脚STM32F407 引脚
VCC5V
GNDGND
Trig任意 GPIO 输出引脚(例如 PA0)
Echo任意 GPIO 输入引脚(例如 PA1)

需要注意的是,由于 HC - SR04 的 VCC 为 5V,而 STM32F407 的 GPIO 引脚一般为 3.3V,为了避免损坏 STM32F407 的 GPIO 引脚,需要在 Echo 引脚与 STM32F407 的 GPIO 输入引脚之间添加一个电平转换电路,将 5V 信号转换为 3.3V 信号。可以使用一个简单的分压电路来实现电平转换,例如使用两个电阻R1​和R2​,将R1​连接到 Echo 引脚,R2​接地,R1​和R2​的中间节点连接到 STM32F407 的 GPIO 输入引脚,选择合适的电阻值使得中间节点的电压为 3.3V。

五、开发环境搭建

5.1 安装开发工具

  • Keil MDK:用于编写、编译和调试 STM32 的代码。
  • STM32CubeMX:用于配置 STM32 的外设和生成初始化代码。

5.2 配置 STM32CubeMX

  1. 打开 STM32CubeMX,选择 STM32F407 芯片。
  2. 配置系统时钟,将主频设置为 168MHz。
  3. 配置 GPIO 引脚:
    • 将 Trig 引脚配置为推挽输出模式。
    • 将 Echo 引脚配置为浮空输入模式。
  4. 配置定时器:为了精确测量 Echo 引脚高电平的持续时间,需要使用定时器。选择一个合适的定时器(例如 TIM2),配置定时器的时钟源、预分频器和自动重载值,使得定时器的计数周期为 1μs。
  5. 生成代码,选择 Keil MDK 作为开发工具,点击 “Generate Code” 生成初始化代码。

六、代码实现

6.1 初始化 GPIO 和定时器

在生成的初始化代码中,已经包含了 GPIO 和定时器的初始化函数。以下是一个简单的示例代码,用于初始化 GPIO 和定时器:

#include "stm32f4xx_hal.h"

TIM_HandleTypeDef htim2;
GPIO_InitTypeDef GPIO_InitStruct = {0};

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM2_Init();

  while (1)
  {
    // 主循环
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** 初始化RCC振荡器 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** 初始化RCC时钟 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_TIM2_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 168 - 1; // 定时器时钟频率为1MHz,计数周期为1μs
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 0xFFFF;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_GPIO_Init(void)
{
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PA1 */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void Error_Handler(void)
{
  while(1)
  {
  }
}

6.2 触发 HC - SR04 发射超声波

为了触发 HC - SR04 发射超声波,需要向 Trig 引脚发送一个至少 10μs 的高电平脉冲。以下是一个触发 HC - SR04 发射超声波的函数:

void Trigger_HC_SR04(void)
{
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // 将Trig引脚置为高电平
  HAL_Delay(1); // 延时1ms,确保高电平持续时间足够长
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // 将Trig引脚置为低电平
}

6.3 测量 Echo 引脚高电平的持续时间

使用定时器来测量 Echo 引脚高电平的持续时间。以下是一个测量 Echo 引脚高电平持续时间的函数:

uint32_t Measure_Echo_Time(void)
{
  uint32_t start_time, end_time;

  // 等待Echo引脚变为高电平
  while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET);

  // 启动定时器
  HAL_TIM_Base_Start(&htim2);
  start_time = __HAL_TIM_GET_COUNTER(&htim2);

  // 等待Echo引脚变为低电平
  while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_SET);

  // 停止定时器
  HAL_TIM_Base_Stop(&htim2);
  end_time = __HAL_TIM_GET_COUNTER(&htim2);

  return end_time - start_time; // 返回高电平持续时间(单位:μs)
}

6.4 计算距离

根据测量得到的 Echo 引脚高电平持续时间,使用公式d=v×t/2计算出距离。以下是一个计算距离的函数:

float Calculate_Distance(uint32_t time)
{
  float distance;
  distance = (float)time * 0.034 / 2; // 超声波传播速度为340m/s,转换为cm/μs为0.034cm/μs
  return distance; // 返回距离(单位:cm)
}

6.5 主函数

在主函数中,调用上述函数完成超声波测距的操作。以下是一个完整的主函数示例:

#include "stm32f4xx_hal.h"

TIM_HandleTypeDef htim2;
GPIO_InitTypeDef GPIO_InitStruct = {0};

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
void Trigger_HC_SR04(void);
uint32_t Measure_Echo_Time(void);
float Calculate_Distance(uint32_t time);

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM2_Init();

  float distance;
  uint32_t echo_time;

  while (1)
  {
    Trigger_HC_SR04(); // 触发HC - SR04发射超声波
    echo_time = Measure_Echo_Time(); // 测量Echo引脚高电平的持续时间
    distance = Calculate_Distance(echo_time); // 计算距离

    // 可以在这里将距离值通过串口等方式输出
    HAL_Delay(1000); // 延时1s,避免频繁测量
  }
}

// 其他函数定义保持不变

七、调试与测试

7.1 硬件连接检查

在进行调试之前,需要检查硬件连接是否正确,确保 HC - SR04 超声波测距模块的电源、Trig 引脚和 Echo 引脚连接无误,同时检查电平转换电路是否正常工作。

7.2 串口调试

可以通过串口将测量得到的距离值输出到串口调试助手中,方便观察和调试。在代码中添加串口初始化和数据发送的代码,例如使用 USART1 进行串口通信:

#include "stm32f4xx_hal.h"

UART_HandleTypeDef huart1;
TIM_HandleTypeDef htim2;
GPIO_InitTypeDef GPIO_InitStruct = {0};

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
static void MX_USART1_UART_Init(void);
void Trigger_HC_SR04(void);
uint32_t Measure_Echo_Time(void);
float Calculate_Distance(uint32_t time);

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_USART1_UART_Init();

  float distance;
  uint32_t echo_time;
  char buffer[50];

  while (1)
  {
    Trigger_HC_SR04(); // 触发HC - SR04发射超声波
    echo_time = Measure_Echo_Time(); // 测量Echo引脚高电平的持续时间
    distance = Calculate_Distance(echo_time); // 计算距离

    // 将距离值转换为字符串
    sprintf(buffer, "Distance: %.2f cm\r\n", distance);
    // 通过串口发送距离值
    HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);

    HAL_Delay(1000); // 延时1s,避免频繁测量
  }
}

void SystemClock_Config(void)
{
  // 系统时钟配置函数,保持不变
}

static void MX_TIM2_Init(void)
{
  // 定时器初始化函数,保持不变
}

static void MX_GPIO_Init(void)
{
  // GPIO初始化函数,保持不变
}

static void MX_USART1_UART_Init(void)
{
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
}

void Trigger_HC_SR04(void)
{
  // 触发HC - SR04发射超声波函数,保持不变
}

uint32_t Measure_Echo_Time(void)
{
  // 测量Echo引脚高电平持续时间函数,保持不变
}

float Calculate_Distance(uint32_t time)
{
  // 计算距离函数,保持不变
}

void Error_Handler(void)
{
  while(1)
  {
  }
}

7.3 实际测试

将 STM32F407 开发板和 HC - SR04 超声波测距模块放置在合适的位置,使用不同距离的目标物体进行测试,观察串口调试助手中输出的距离值是否准确。

八、常见问题及解决方法

8.1 测量结果不准确

  • 原因
    • 超声波传播过程中受到干扰,例如周围有其他超声波源或障碍物。
    • 定时器精度不够,导致测量的 Echo 引脚高电平持续时间不准确。
    • 电平转换电路存在问题,导致 Echo 引脚信号异常。
  • 解决方法
    • 尽量避免在有干扰的环境下使用 HC - SR04 超声波测距模块,或者采取屏蔽措施减少干扰。
    • 检查定时器的配置,确保定时器的计数周期准确,同时可以考虑使用更高精度的定时器。
    • 检查电平转换电路的连接和电阻值,确保电平转换正常。

8.2 无法触发 HC - SR04 发射超声波

  • 原因
    • Trig 引脚连接不正确,或者没有输出正确的触发信号。
    • HC - SR04 模块本身存在故障。
  • 解决方法
    • 检查 Trig 引脚的连接,确保其与 STM32F407 的 GPIO 输出引脚连接正确,同时检查触发信号的持续时间是否满足要求。
    • 更换 HC - SR04 模块,检查是否是模块本身的问题。

8.3 无法测量 Echo 引脚高电平的持续时间

  • 原因
    • Echo 引脚连接不正确,或者没有接收到正确的回响信号。
    • 定时器没有正常工作。
  • 解决方法
    • 检查 Echo 引脚的连接,确保其与 STM32F407 的 GPIO 输入引脚连接正确,同时检查电平转换电路是否正常工作。
    • 检查定时器的初始化和启动、停止操作,确保定时器能够正常工作。

九、总结

通过本文的介绍,你已经了解了如何基于 STM32F407 的 HAL 库来驱动 HC - SR04 超声波测距模块。从硬件连接、开发环境搭建到代码实现和调试,详细介绍了整个开发过程。希望本文能帮助你顺利完成基于 HC - SR04 超声波测距模块的嵌入式系统开发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2335495.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Boot 热部署详解,包含详细的配置项说明

Spring Boot 热部署详解 1. 热部署简介 热部署&#xff08;Hot Deployment&#xff09;允许在应用运行时修改代码或配置文件&#xff0c;无需重启应用即可使更改生效。Spring Boot 通过 spring-boot-devtools 模块实现这一功能&#xff0c;其核心依赖于 LiveReload 技术和自动…

剑指Offer(数据结构与算法面试题精讲)C++版——day12

剑指Offer&#xff08;数据结构与算法面试题精讲&#xff09;C版——day12 题目一&#xff1a;小行星碰撞题目二&#xff1a;每日温度题目三&#xff1a;直方图最大矩形面积附录&#xff1a;源码gitee仓库 题目一&#xff1a;小行星碰撞 题目&#xff1a;输入一个表示小行星的数…

Docker学习笔记-docker安装、删除

一、在centOS 7中docker的默认安装目录 # Docker 主配置文件目录 ls /etc/docker# Docker 数据目录&#xff08;镜像、容器、卷等&#xff09; ls /var/lib/docker# Docker 可执行文件路径 which docker # 输出类似 /usr/bin/docker 二、docker文件目录说明 目录/文件用途/…

【Python 开源】你的 Windows 关机助手——PyQt5 版定时关机工具

&#x1f5a5;️ 你的 Windows 关机助手——PyQt5 版定时关机工具 相关资源文件已经打包成EXE文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Python相关程序案例&#xff0c;秉着开源精神的…

【Python爬虫】简单介绍

目录 一、基本概念 1.1 什么是爬虫 1.2 Python为什么适合爬虫 1.3 Python爬虫应用领域 &#xff08;1&#xff09;数据采集与分析 市场调研 学术研究 &#xff08;2&#xff09;内容聚合与推荐 新闻聚合 视频内容聚合 &#xff08;3&#xff09;金融领域 股票数据获…

使用MCP服务通过自然语言操作数据库(vscode+cline版本)

使用MCP服务操纵数据库(vscodecline版本) 本文主要介绍&#xff0c;在vscode中使用cline插件调用deepseek模型&#xff0c;通过MCP服务器 使用自然语言去操作指定数据库。本文使用的是以己经创建号的珠海航展数据库。 理解MCP服务&#xff1a; MCP&#xff08;Model Context…

Vue 3 + TypeScript 实现一个多语言国际化组件(支持语言切换与内容加载)

文章目录 一、项目背景与功能概览二、项目技术架构与依赖安装2.1 技术栈2.2 安装依赖 三、国际化组件实现3.1 创建 i18n 实例3.2 配置 i18n 到 Vue 应用3.3 在组件中使用国际化内容3.4 支持语言切换 四、支持类型安全4.1 添加类型支持4.2 自动加载语言文件 一、项目背景与功能概…

PhalApi 2.x:让PHP接口开发从“简单”到“极简”的开源框架

—— 专为高效开发而生&#xff0c;助你轻松构建高可用API接口 一、为什么选择PhalApi 2.x&#xff1f; 1.轻量高效&#xff0c;性能卓越 PhalApi 2.x 是一款专为接口开发设计的轻量级PHP框架&#xff0c;其核心代码精简但功能强大。根据开发者实测&#xff0c;在2核2G服务器…

Java 企业级应用:SOA 与微服务的对比与选择

企业级应用开发中&#xff0c;架构设计是决定系统可扩展性、可维护性和性能的关键因素。SOA&#xff08;面向服务的架构&#xff09;和微服务架构是两种主流的架构模式&#xff0c;它们各自有着独特的和设计理念适用场景。本文将深入探讨 SOA 和微服务架构的对比&#xff0c;并…

Zookeeper的典型应用场景?

大家好&#xff0c;我是锋哥。今天分享关于【Zookeeper的典型应用场景?】面试题。希望对大家有帮助&#xff1b; Zookeeper的典型应用场景? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 ZooKeeper 是一个开源的分布式协调服务&#xff0c;主要用于管理和协调大…

数据分析不只是跑个SQL!

数据分析不只是跑个SQL&#xff01; 数据分析五大闭环&#xff0c;你做到哪一步了&#xff1f;闭环一&#xff1a;认识现状闭环二&#xff1a;原因分析闭环三&#xff1a;优化表现闭环四&#xff1a;预测走势闭环五&#xff1a;主动解读数据 数据思维&#xff1a;WHY-WHAT-HOW模…

Dify智能体平台源码二次开发笔记(4) - 多租户的SAAS版实现

前言 Dify 的多租户功能是其商业版的标准功能&#xff0c;我们应当尊重其盈利模式。只有保持良性的商业运作&#xff0c;Dify 才能持续发展&#xff0c;并为用户提供更优质的功能。因此&#xff0c;此功能仅限学习使用。 我们的需求是&#xff1a;实现类似 SaaS 版的账号隔离&a…

layui中transfer两个table展示不同的数据列

在项目的任务开发中需要达到transfer右侧table需要有下拉框可选择状态&#xff0c;左侧table不变 使用的layui版本为2.4.5&#xff0c;该版本没有对transfer可自定义数据列的配置&#xff0c;所以改动transfer.js中的源码 以下为transfer.js部分源码 也是transfer.js去render的…

【机器学习】机器学习笔记

1 机器学习定义 计算机程序从经验E中学习&#xff0c;解决某一任务T&#xff0c;进行某一性能P&#xff0c;通过P测定在T上的表现因经验E而提高。 eg&#xff1a;跳棋程序 E&#xff1a; 程序自身下的上万盘棋局 T&#xff1a; 下跳棋 P&#xff1a; 与新对手下跳棋时赢的概率…

STM32 BOOT设置,bootloader,死锁使用方法

目录 BOOT0 BOOT1的配置含义 bootloader使用方法 芯片死锁解决方法开发调试过程中&#xff0c;由于某种原因导致内部Flash锁死&#xff0c;无法连接SWD以及JTAG调试&#xff0c;无法读到设备&#xff0c;可以通过修改BOOT模式重新刷写代码。修改为BOOT01&#xff0c;BOOT10…

【Redis】string类型

目录 1、介绍2、底层实现【1】SDS【2】int编码【3】embstr编码【4】raw编码【5】embstr和raw的区别 3、常用指令【1】字符串基本操作&#xff1a;【2】批量操作【3】计数器【4】过期时间【5】不存在就插入 4、使用场景 1、介绍 string是redis中最简单的键值对形式&#xff0c;…

PostgreSQL全平台安装指南:从入门到生产环境部署

一、PostgreSQL核心特性全景解析 1.1 技术架构深度剖析 graph TDA[客户端] --> B(连接池)B --> C{查询解析器}C --> D[优化器]D --> E[执行引擎]E --> F[存储引擎]F --> G[物理存储]G --> H[WAL日志]H --> I[备份恢复] 1.2 特性优势对比矩阵 特性维度…

UE5 物理模拟 与 触发检测

文章目录 碰撞条件开启模拟关闭模拟 多层级的MeshUE的BUG 触发触发条件 碰撞 条件 1必须有网格体组件 2网格体组件必须有网格&#xff0c;没有网格虽然可以开启物理模拟&#xff0c;但是不会有任何效果 注意开启的模拟的网格体组件会计算自己和所有子网格的mesh范围 3只有网格…

做仪器UI用到的颜色工具网站

https://color.adobe.com/zh/create/color-wheel 1. 图片取颜色工具 2. 对比度工具&#xff0c;煤矿井下设备&#xff0c;光线暗&#xff0c;要求背景与文字有合适的对比度&#xff0c;可以用这个软件 3. 颜色生成ARGB的值工具&#xff0c;这三个工具&#xff0c;都在上面这…

网络安全·第三天·ICMP协议安全分析

一、ICMP功能介绍 ICMP&#xff08;Internet Control Message Protocal&#xff09;是一种差错和控制报文协议&#xff0c;不仅用于传输差错报文&#xff0c; 还传输控制报文&#xff0c;但是ICMP只是尽可能交付&#xff0c;提供的服务是无连接、不可靠的&#xff0c;并不能保…