STM32_超声波测距

2023-11-02

超声波测距原理

利用声音测距,声音在空气中的速度是340m/s(15℃)
当声音传播时,若遇到障碍物时,就会被反弹回来,通过计时反弹回来的时间就可以计算出从发射端到障碍物的距离

S=v*(t/2)

超声波模块说明书

在单片机中借助超声波模块实现测距功能,通过串口调试助手或者显示屏进行显示反馈

在这里插入图片描述
HC-SR04超声波模块测量范围为2cm-400cm,精度可达3mm。

引脚功能:
VCC引脚:5V电源。
TRIG引脚:触发信号引脚,单片机给超声波模块一个信号,超声波模块就会工作。
ECHO引脚:回响信号引脚,当超声波模块已经测量距离成功后,通过该引脚告诉单片机当前超声波传输的时间。
GND:信号地。

模块工作原理:
在这里插入图片描述
1、起初Trig和Echo两个引脚都处于低电平状态;
2、然后将TRIG引脚拉高至少10微秒以上再拉低,让超声波模块开始工作;
3、此时模块内部会自动发送8个40KHz的方波作为起始信号;
4、在起始信号发射的同时ECHO引脚就会被拉高,如果有信号返回,ECHO引脚会自动检测到反射回来的信号,并被拉低,那么ECHO引脚的高电平持续时间就是波从发射到返回的时间。
测出的距离即为:
S=(ECHO引脚高电平持续的时间*340m/s)/2
S=t x 170
因为单片机的定时器一般使用us进行计时,所以公式可以转换为
S= t x 170 x 10-6=t/58 (cm)

超声波注意事项

1、不同的温度,声音的传播速度是不一样的,有以下公式:
在这里插入图片描述
一般取15℃时,v=340m/s,可以在测量距离时加入温湿度传感器测量环境温度,带入公式,动态计算声速值,使测量更加精确;
2、测距时,要求被测物体尽量平整,且面积不小于0.5平方米,否则会影响测量结果;
2、超声波的测量误差为3mm,可根据3mm的测距求出测量时间,求算如下:

在这里插入图片描述
这里使用这个公式测量距离,当延时9us,即ECHO持续高电平9us,测得的距离为3mm,这里只是近似值。

在这里插入图片描述

HMI串口屏

本实验使用的串口屏来自淘晶驰商家
型号为 :TJC3224K024_011R
320x240分辨率
_011:硬件版本号
K0系列
2.4寸屏幕(斜对角线的距离)
触摸屏说明:N=无触摸 R=电阻触摸屏 C=电容触摸屏
在这里插入图片描述
相对LCD(液晶屏)和OLED(有机发光显示器),串口屏幕更加简单,只有4根线,利用串口通信,而且屏幕丰富多彩,可以彩屏显示。

LCD:32根引脚,使用IIC或者SPI通信
OLED:显示颜色有限,最多两种颜色
在这里插入图片描述
相对其他商家,陶晶驰的串口屏使用起来比较简单,只需遵守它的串口屏协议就可以。
在这里插入图片描述
这是它的语法规则,只需要在控件后面加三个0xff字节作为结束符,没有其他规则的要求。

本实验设计的串口屏界面:
在这里插入图片描述
由于这款软件是中文的,所以不进行过多的介绍,直接点击帮助文档进行学习,官网关于这款软件的使用介绍的佷详细,只是与单片机的通信介绍的很少,不过官方文档给出了明确的说明,这属于高级应用,不过多介绍。
在这里插入图片描述

HMI串口屏注意事项:
1、当往屏幕添加了字库,字库才会有文字或者数字显示,字而库的添加最好以指定字库的形式添加,不要添加所有字库,否则下载到屏幕中会很慢。
2、串口屏数据传输支持两种方式下载:①串口号搜索下载②;SD内存卡下载。
3、关于屏幕中图片上传的格式要求是:png图片,且根据屏幕的尺寸大小它会对图片大小有限制,小一点的图片才可以加载进去。

关于控件的学习,可以直接下载USART HMI这款软件进行学习,点击软件里面的帮助就可以学习或者直接登入陶晶驰官网学习。

最后关于一些容易出错的地方做一些说明:
1、当串口屏和STM32开发板连接时,要把串口1的跳线帽拔掉,PA9和PA10分别接串口屏TX和RX引脚,野火指南针的串口1默认和CH340芯片连接。
拔掉跳线帽后,第一步可以让串口屏和CH340芯片的TX和RX引脚交叉连接,将USART HMI上位机中设计好的屏幕界面下载到串口屏中,下载好程序后,再拔掉连接PA9和PA10,与芯片通信。

2、CH340所起的作用就是一座桥梁,它可以将TTL电平转换为USB电平,一般单片机输出的都是TTL电平,那么如果想要单片机与电脑通信就需要USB接口,以前有使用DB9接口与电脑通信,但是现在用的很少,主要是USB更加小巧,方便通信。
CH340
3、串口屏的波特率一定要和所写程序的波特率设置成一样的,才可以进行通信,虽然上位机可以更改屏幕波特率,但是屏幕波特率可能出厂时已经固定好了,即使在上位机强制更改,通信的时候也无法正常通信,不知道屏幕的波特率,下载屏幕界面可以自动搜索,上面会有显示。

在这里插入图片描述

虽然有很多东西被淘汰了,主要是因为时代在进步,科技再不断更新迭代,但是新东西的诞生源于旧物件,旧物件涉及到的知识永远不会淘汰,除非一种知识被证明是错误的,那么错的东西肯定会被淘汰,这就像我们现在仍在学习几千年牛顿总结出的各种定律,如果这些定律被证明是错的,那么我们就不需要再学习了,今天需要学习的知识是太多了,学习途径也有很多,在知识的海洋中遨游,我们一定要站在巨人的肩膀上。

使用串口调试助手也可以显示数据,当拔下跳线帽时,串口调试助手就不可以使用了,或者使用其他串口来连接串口调试助手也可以,这里也要波特率设置成一样才可以通信

代码解析

hc-sr04.h
超声波模块的初始化是根据时序图进行编程

#ifndef  __HCSR04_H
#define  __HCSR04_H

#include "stm32f10x.h"

//超声波模块引脚
#define	TRIG_PORT      GPIOC		       
#define	ECHO_PORT      GPIOC		
#define	TRIG_PIN       GPIO_Pin_8   	//TRIG-发送引脚PC8       
#define	ECHO_PIN       GPIO_Pin_9		//ECHO-接收引脚PC9    

//超声波模块初始化
void sr04_init(void);

//超声波模块测距
int32_t sr04_get_distance(void);

#endif

hc-sr04.c

#include "hc-sr04.h"
#include "stm32f10x.h"
#include "delay.h"

uint32_t d;      //计算出的距离

//超声波初始化函数
void sr04_init(void)
{	
	GPIO_InitTypeDef GPIO_InitStructure;
		 	       
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//时钟使能
    
	GPIO_InitStructure.GPIO_Pin = TRIG_PIN;		//PC8接TRIG
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	      //速度
	GPIO_Init(TRIG_PORT, &GPIO_InitStructure);	         //初始化GPIO 

	GPIO_InitStructure.GPIO_Pin = ECHO_PIN;				 //PC9接ECH0
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
	GPIO_Init(ECHO_PORT,&GPIO_InitStructure);		//初始化GPIO 

	GPIO_ResetBits(GPIOC,GPIO_Pin_8);//PC8初始状态为低电平,看时序图	
}

/*获取距离*/
int32_t sr04_get_distance(void)
{
	uint32_t t;	
		
	//PC8高电平
	GPIO_SetBits(TRIG_PORT,TRIG_PIN);
	delay_us(20);	//持续10us以上
	GPIO_ResetBits(TRIG_PORT,TRIG_PIN);//PC8低电平
	
	while(!GPIO_ReadInputDataBit(ECHO_PORT,ECHO_PIN));	//等待高电平
	
	//等待PC9出现高电平
	t=0;
	while(ECHO_PIN==0)
	{	
		//超时处理
		t++;
		delay_us(1);
		
		//如果超时,就返回一个错误码
		if(t >= 10000)
			return -1;
	
	}

	//测量高电平的时间
	t=0;
	while(GPIO_ReadInputDataBit(ECHO_PORT,ECHO_PIN))
	{	
		t++;
		delay_us(9);	//9us == 3mm
		
		//如果超时,就返回一个错误码
		if(t >= 10000)
			return -2;
	}
		
	//由于测量的时间,就是超声波从发射到返回的时间	
	d = t*0.3;
	
	return d;
	
}	





delay.h

#ifndef __DELAY_H
#define __DELAY_H

#include "stm32f10x.h"

void delay_us(uint32_t n);
void delay_ms(uint32_t n);

#endif

delay.c

#include "delay.h"

void delay_us(uint32_t n)
{
	SysTick->CTRL = 0; 			// Disable SysTick,关闭系统定时器
	SysTick->LOAD = (168*n)-1; // 配置计数值(168*n)-1 ~ 0
	SysTick->VAL  = 0; 		// Clear current value as well as count flag
	SysTick->CTRL = 5; 		// Enable SysTick timer with processor clock
	while ((SysTick->CTRL & 0x10000)==0);// Wait until count flag is set
	SysTick->CTRL = 0; 		// Disable SysTick	
}

void delay_ms(uint32_t n)
{
	while(n--)
	{
		SysTick->CTRL = 0; 		// Disable SysTick,关闭系统定时器
		SysTick->LOAD = (168000)-1; 	// 配置计数值(168000)-1 ~ 0
		SysTick->VAL  = 0; // Clear current value as well as count flag
		SysTick->CTRL = 5; 	// Enable SysTick timer with processor clock
		while ((SysTick->CTRL & 0x10000)==0);// Wait until count flag is set
	}
	
	SysTick->CTRL = 0; 		// Disable SysTick	

}



usart.h

#ifndef   __USART_H
#define	  __USART_H

#include "stm32f10x.h"
#include "stdio.h"

/*串口1参数宏定义*/
#define USART1_CLK			RCC_APB2Periph_USART1//串口时钟
#define USART1_BAUDRATE		9600//波特率

//串口1 GPIO引脚宏定义
#define USART1_GPIO_CLK		RCC_APB2Periph_GPIOA
#define USART1_GPIO_TX_PORT	GPIOA
#define USART1_GPIO_TX_PIN	GPIO_Pin_9
#define USART1_GPIO_RX_PORT	GPIOA
#define USART1_GPIO_RX_PIN	GPIO_Pin_10

//中断
#define  USART1_IRQ                USART1_IRQn
#define  USART1_IRQHandler         USART1_IRQHandler

//串口函数
void USART1_Config(void);
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t data);
void USART_SendString(USART_TypeDef* USARTx, char *DataString);


#endif /* __USART1_H */

usart.c

//串口
void USART1_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef  NVIC_InitStructure;
	
	/* config USART1 clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
	
	/* USART1 GPIO config */
	/* Configure USART1 Tx (PA.09) as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);    
	/* Configure USART1 Rx (PA.10) as input floating */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/* USART1 mode config */
	USART_InitStructure.USART_BaudRate = USART1_BAUDRATE;//波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//1个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No ;//无校验
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件控制流
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART1, &USART_InitStructure);//串口初始化完成
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//使能串口
	
	//配置串口1的中断触发方法:接收一个字节触发中断
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

	//配置串口1的中断优先级
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
		
	USART_Cmd(USART1, ENABLE);
}



/*****************  发送一个字节 **********************/

void Usart_SendByte(USART_TypeDef * pUSARTx, uint8_t data)
{
	/* 发送一个字节数据到USART */
	USART_SendData(pUSARTx,data);
		
	/* 等待发送数据寄存器为空 */
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}

/*****************  发送字符串 **********************/

void USART_SendString(USART_TypeDef* USARTx, char *DataString)
{
	int i = 0;
	USART_ClearFlag(USARTx,USART_FLAG_TC);										//发送字符前清空标志位(否则缺失字符串的第一个字符)
	while(DataString[i] != '\0')												//字符串结束符
	{
		USART_SendData(USARTx,DataString[i]);									//每次发送字符串的一个字符
		while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == 0);					//等待数据发送成功
		USART_ClearFlag(USARTx,USART_FLAG_TC);									//发送字符后清空标志位
		i++;
	}
}

//重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
		/* 发送一个字节数据到串口 */
		USART_SendData(USART1, (uint8_t) ch);
		
		/* 等待发送完毕 */
		while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);		
	
		return (ch);
}

int fgetc(FILE *f)
{
		/* 等待串口输入数据 */
		while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

		return (int)USART_ReceiveData(USART1);
}

stm32f10x_it.c中断服务函数

#include "stm32f10x_it.h"
#include "usart.h"
#include "stdio.h"

void USART1_IRQHandler(void)
{
	u8 d;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
	{ 	
	    d=USART1->DR;
	  	printf("%c",d);    //将接受到的数据直接返回打印
	} 
	 
}

main.c

/**********************************************
 * 文件名  :main.c
 * 描述    :GPIOC8接超声波模块的TRIG
		   GPIOC9接超声波模块的ECHO
		   VCC接5V
		   GND接GND

             打开串口助手,配置波特率115200,8位,一个停止位,
		   无校验位。定时向PC发送测得的距离     

*******************************************************/

#include "stm32f10x.h"
#include "systick.h"
#include "stdio.h"
#include "usart.h"
#include "hc-sr04.h"
#include "delay.h"

/**********************************************
 * 文件名  :main.c
 * 描述    :GPIOC8接超声波模块的TRIG
		   GPIOC9接超声波模块的ECHO
		   VCC接5V
		   GND接GND

             打开串口助手,配置波特率115200,8位,一个停止位,
		   无校验位。定时向PC发送测得的距离     

*******************************************************/

#include "stm32f10x.h"
#include "systick.h"
#include "stdio.h"
#include "usart.h"
#include "hc-sr04.h"
#include "delay.h"

/*HMI串口屏函数定义,也可以直接使用串口字符串或者字节函数*/
void HMISends(char *buf1);
void HMISendb(u8 buf);

void HMISendstart(void)
	{
	 	delay_ms(200);
		HMISendb(0xff);
		delay_ms(200);
	}


int main(void)
{	
	uint32_t d;//距离
	USART1_Config();	//调用串口函数,配置模式为 115200 8-N-1
	NVIC_Configuration();//中断	
	sr04_init();//超声波模块初始化
	
	while(1)
	{		
		d=sr04_get_distance();
		printf("distance=%dcm\r\n",d);
		
		HMISendstart();  //串口HMI显示
		{ 
			printf("n0.val=%d",d);
			HMISendb(0xff);
		}			
	}
}

void HMISends(char *buf1)		 //字符串发送函数
{
	u8 i=0;
	while(1)
	{
	 if(buf1[i]!=0)
	 	{
			USART_SendData(USART1,buf1[i]);  //发送一个字节
			while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET){};//等待发送结束
		 	i++;
		}
	 else 
	 return ;

		}
}

void HMISendb(u8 k)		  //字节发送函数
{		 
	u8 i;
	 for(i=0;i<3;i++)
	 {
	 if(k!=0)
	 	{
			USART_SendData(USART1,k);  //发送一个字节
			while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET){};//等待发送结束
		}
	 else 
	 return ;

	 } 
} 


测距结果

测试距离
在这里插入图片描述

串口调试助手
在这里插入图片描述
串口屏
在这里插入图片描述

由于我没有使用定时器进行计时以及环境的影响,会存在一定的误差。

这篇文章所涉及的串口知识没有过多的文字介绍,只在代码中写了注释,其实串口通信很简单,只需要启动时钟,使用两根引脚的输入和输出模式,配置好相关参数即可,由于这篇文章的内容比较多,在这里就不进行过多的介绍,如果有机会,会在后面的文章会有所涉及。

在孤独中,一个人要像一支队伍。

作者能力水平有限,文章难免存在错误和纰漏,请大佬不吝赐教,非常欢迎大家与小白杨进行技术交流,一起学习技术。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32_超声波测距 的相关文章

  • 牛客网刷题笔记

    本来想在牛客网上刷完一道在线编程题后就写以下体会笔记 可是找了半天都没找到在哪里写东西 无奈 我就只好来CSDN上写了 只是想写而已 刚开始写 肯定会很不理想 但是没关系 慢慢写吧 总会有提高的 今天在牛客网刷了一道求最长字串是回文数的长度
  • android中出现javax.net.ssl.SSLPeerUnverifiedException的解决方案

    javax net ssl SSLPeerUnverifiedException No peer certificate的错误 根据有关资料解决如下 1 编写SSLSocketFactoryEx 以代替原有的SSLSocketFactory

随机推荐

  • activiti7-4-流程激活和挂起

    我是一个目录 1 分析 2 全部流程实例的挂起和激活 3 单个流程实例挂起 1 分析 如果公司制度发生变化 1 原本没有批完的流程怎么办 例如 30人没有处理完 怎么办 看公司制度了 有可能 按原来的走 也有可能全部打回 重新发起 全部按照
  • windows创建软连接

    可用于地址映射 方便统一配置管理 打开cmd执行 创建命令 指令 软连接地址 实际地址 mklink J D bwopt booway bwss D Java Project main insenattendance bwopt boowa
  • Java http请求工具类

    近期使用json请求很多 数据交互格式统一 方便数据转化 但是过时的工具类在后台之间请求时 发现接收到并不是标准的JSON 请求头也有问题 造成很大的困扰 所以整理了一个标准的工具类 import org apache http NameV
  • c语言中八进制输出的格式说明符,C 的输入&输出格式说明符讲解

    C的输入 输出格式说明符讲解 方便你了解C的输入与输出格式的写法 d整型输出 ld长整型输出 o以八进制数形式输出整数 x以十六进制数形式输出整数 或输出字符串的地址 u以十进制数输出unsigned型数据 无符号数 注意 d与 u有无符号
  • win服务器上的虚拟机反应慢,高手解读Win10系统打开vmware特别慢的具体方法

    大家在用win10系统的过程中 各位难免会遇到Win10系统打开vmware特别慢的问题 Win10系统打开vmware特别慢这样的情况还真的把很多电脑高手都为难住了 别着急 我们自己就可以处理掉Win10系统打开vmware特别慢的问题
  • 【毕业季·进击的技术er】 我 能

    你陪我步入蝉夏 越过城市喧嚣 歌声还在游走 你榴花般的双眸 不见你的温柔 丢失花间欢笑 岁月无法停留流云 的等候 在纸短情长里 我们迎来了毕业季 这是告别 也是迈向新起点的开始 本文我从一个大三在校生的角度来讲讲我和编程的那些事 希望技术社
  • Android 系统865虚拟化集成无源码apk示例

    一 环境 高通865虚拟化Android 10 版本 二 具体修改的文件 以集成OppoAnonymousId apk为例 1 新建OppoAnonymousId目录 将apk放到该目录 vendor qcom proprietary pr
  • g2o编译错误

    ORBSLAM2 with pointcloud map g2o with orbslam2 g2o types slam2d edge se2 pointxy bearing cpp 51 39 error cannot convert
  • uniapp uni.setClipboardData成功默认提示

    uni setClipboardData data hello uniapp success function 重点 做笔记 在success中加入uni hideToast 可以解决 uni hideToast 以下就可自定义操作了 fa
  • SpringBoot(八)拦截器Interceptor

    上篇介绍了Filter过滤器的使用 提起过滤器 就不得不再提起另外一个叫做拦截器的东西 两者的作用类似 都可以实现拦截请求的作用 但其实两者有着非常大的区别 本篇 我们就来学习下拦截器的使用 如果你是新手 且没看过我之前的一系列Spring
  • Ubuntu系统使用光盘作为apt-get源

    1 将系统光盘插入光驱 接入系统 并挂载 mount dev sr0 mnt 2 修改apt get源 将光驱挂着的目录加入源 vim etc apt sources list 在首行加入 deb file mnt trusty main
  • 【Linux服务器】 .bashrc设置永久环境变量后不起作用的问题

    在使用vi打开 bashrc文件以后设置环境变量 vim bashrc export PATH PATH home uusama mysql bin 然而发现设置了以后不起作用 这时候可以在终端界面使用export命令查看当前所有的PATH
  • 基于Aidlux的自动驾驶智能预警方案

    forewarning py为智能预警代码 运行后视频结果如下所示 基于Aidlux的自动驾驶智能预警方案 YOLOP导出onnx模型 执行命令 python3 export onxx py height 640 width 640 执行完
  • 问题 E: 括号的最大嵌套深度

    题目描述 如果字符串满足以下条件之一 则可以称之为 有效括号字符串 valid parentheses string 可以简写为 VPS 字符串是一个空字符串 或者是一个不为 或 的单字符 字符串可以写为 AB A 与 B 字符串连接 其中
  • 机器学习课后习题 --- 逻辑回归

    一 单选题 1 一监狱人脸识别准入系统用来识别待进入人员的身份 此系统一共包括识别4种不同的人员 狱警 小偷 送餐员 其他 下面哪种学习方法最适合此种应用需求 A 二分类问题 B 多分类问题 C 回归问题 D 聚类问题 2 以下关于分类问题
  • webpack5基本教程-1

    基本使用 Webpack 是一个静态资源打包工具 它会以一个或多个文件作为打包的入口 将我们整个项目所有文件编译组合成一个或多个文件输出出去 输出的文件就是编译好的文件 就可以在浏览器段运行了 我们将 Webpack 输出的文件叫做 bun
  • nginx 超时配置说明

    keepalive timeout 默认75s 通常keepalive timeout应该比client body timeout大 如果值为0 则响应头Connection close Syntax keepalive timeout t
  • android log缓冲区大小,科普:开发者模式日志记录缓冲区到底怎样设置

    概念 志缓冲区是小型的 用于短期存储将写入到磁盘上的重做日志的变更向量的临时区域 变更向量 是应用于某些对象的修改 执行DML语句会生成应用于数据的变更向量 有了重做日志 数据库就可以确保数据永不丢失 每当数据块发生更改时 都会将应用于块的
  • 微信开发时, 如何进行服务器验证及接收回复信息呢? 分享原生PHP代码如下:

    if isset GET echostr signature GET signature timestamp GET timestamp nonce GET nonce 验证时会传递这个信息 echostr GET echostr toke
  • STM32_超声波测距

    超声波测距 超声波测距原理 超声波模块说明书 超声波注意事项 HMI串口屏 代码解析 测距结果 超声波测距原理 利用声音测距 声音在空气中的速度是340m s 15 当声音传播时 若遇到障碍物时 就会被反弹回来 通过计时反弹回来的时间就可以