STM32F103RCT6使用HY-SRF05 五针超声波测距模块进行测距实现

18 篇文章 2 订阅
13 篇文章 0 订阅

功能简述:STM32F103RCT6使用HY-SRF05五针超声波测距模块进行测距,再将测距好的值通过串口2DMA方式发送到PC的串口调试助手上。

HY-SRF05五针超声波测距模块描述:

软件实现思路:

1、精准的延时工具

2、超声波模块TRIG引脚连接到STM32的某个引脚,推挽输出,通常情况是低电平。触发超声波信号时,将STM32的这个引脚拉高,制造一个上升沿,并延时>10us,再将该引脚拉低,如此超声波就可以发送测距脉冲信号了。

3、超声波模块的ECHO引脚连接到STM32的某个引脚上,下拉输入,通常情况下是低电平,当检测到上升沿时开始计时,直到下降沿停止计时。计时单位为us(微秒),考虑到超声波测距有效性为2cm-450cm,因此,需要有一个测距超时的机制。根据声波的速度为340m/s,检测1cm的距离需要的时间为0.01/340=0.0000294s=0.0294ms=29.4us,即每29.4us的时间换算成距离约等于1cm。超声波最大测量距离为450cm,换算成等效时间为450*29.4=13230。

4、测量距离=高电平时间/29.4,结果即为计算的厘米数。

硬件电路接线:

具体实现代码:

1、精准延时

#ifndef __Z_UTIL_TIME_H
#define __Z_UTIL_TIME_H
#include "z_util_time.h"
#endif

void delay_us(uint32_t time_us)
{
	SysTick->LOAD = AHB_INPUT * time_us;
	SysTick->VAL = 0x00;
	SysTick->CTRL = 0x00000005;
	for(;!(SysTick->CTRL & 0x00010000););
	SysTick->CTRL = 0x00000004;
}

void delay_ms(uint32_t time_ms)
{
	for(;time_ms-- > 0;)
	{
		delay_us(1000);
	}
}

2、超声波测距功能代码

#ifndef __Z_OUTER_HARDWARE_SUPERSONIC_H
#define __Z_OUTER_HARDWARE_SUPERSONIC_H
#include "z_outer_hardware_supersonic.h"
#endif

void init_hardware_supersonic()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_ResetBits(GPIOB, GPIO_Pin_7);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void func_trig_supersonic()
{
	GPIO_SetBits(GPIOB, GPIO_Pin_7);
	delay_us(12);
	GPIO_ResetBits(GPIOB, GPIO_Pin_7);
}

u8 func_get_supersonic_echo_signal(u16 *distance_cm)
{
	u16 counter_high;
	u16 timeout;
	
	func_trig_supersonic();
	for(;;)
	{
		delay_us(1);
		if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8) == Bit_SET)
		{
			counter_high ++;
			if(counter_high > 13235)
			{
				return 2;
			}
		}
		else
		{
			if(counter_high > 1)
			{
				*distance_cm = ((counter_high)*10)/294;
				return 0;
			}
			timeout++;
		}
		if(timeout > 13235)
		{
			return 2;
		}
	}
}

3、USART2串口DMA通讯代码

#ifndef __Z_HARDWARE_USART2_DMA_H
#define __Z_HARDWARE_USART2_DMA_H
#include "z_hardware_usart2_dma.h"
#endif

u8 dma_recv_buf[LEN_DMA_RECV_BUF];
u8 dma_send_buf[LEN_DMA_RECV_BUF];
u8 usart2_cache[LEN_DMA_RECV_BUF];

void init_hardware_usart2_dma(u32 bound)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_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(USART2, &USART_InitStructure);
	
	DMA_DeInit(DMA1_Channel6);
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DR;
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)dma_recv_buf;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = LEN_DMA_RECV_BUF;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel6, &DMA_InitStructure);
	DMA_Cmd(DMA1_Channel6, ENABLE);
	
	DMA_DeInit(DMA1_Channel7);
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DR;
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)dma_send_buf;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
	DMA_InitStructure.DMA_BufferSize = 0;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel7, &DMA_InitStructure);
	DMA_Cmd(DMA1_Channel7, DISABLE);
	DMA_ClearFlag(DMA1_FLAG_GL7);
		
	USART_Cmd(USART2, ENABLE);
	USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
	USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
}

void func_usart2_dma_send_bytes(u8 *bytes, u8 bytes_len)
{
	DMA_Cmd(DMA1_Channel7, DISABLE);
	memcpy(dma_send_buf, bytes, bytes_len);
	DMA_SetCurrDataCounter(DMA1_Channel7, bytes_len);
	DMA_Cmd(DMA1_Channel7, ENABLE);
	while(DMA_GetCurrDataCounter(DMA1_Channel7));
	while(USART_GetFlagStatus(USART2, USART_FLAG_TC) != SET);
}

u8 func_usart2_dma_recv_bytes(u8 *buf_recv, u8 *len_recv)
{
	u8 len_dma_recv;
	if(USART_GetFlagStatus(USART2, USART_FLAG_IDLE) != RESET)
	{
		USART_ReceiveData(USART2);
		DMA_Cmd(DMA1_Channel6, DISABLE);
		len_dma_recv = LEN_DMA_RECV_BUF - DMA_GetCurrDataCounter(DMA1_Channel6);
		memcpy(buf_recv, dma_recv_buf, len_dma_recv);
		memset(dma_recv_buf, 0, len_dma_recv);
		DMA_SetCurrDataCounter(DMA1_Channel6, LEN_DMA_RECV_BUF);
		USART_ClearFlag(USART2, USART_FLAG_IDLE);
		DMA_Cmd(DMA1_Channel6, ENABLE);
		*len_recv = len_dma_recv;
		return 0;
	}
	return 1;
}

4、主功能函数实现:

#include "stm32f10x.h"

#ifndef __Z_HARDWARE_USART2_DMA_H
#define __Z_HARDWARE_USART2_DMA_H
#include "z_hardware_usart2_dma.h"
#endif

#ifndef __Z_OUTER_HARDWARE_SUPERSONIC_H
#define __Z_OUTER_HARDWARE_SUPERSONIC_H
#include "z_outer_hardware_supersonic.h"
#endif

void init_led0(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
}

int main()
{
	u8 buf_tmp[LEN_DMA_RECV_BUF];
	
	u16 distance_cm;
	
	init_hardware_usart2_dma(9600);
	init_led0();
	init_hardware_supersonic();
	
	while(1)
	{
		if(func_get_supersonic_echo_signal(&distance_cm) == 0)
		{
			buf_tmp[1] = (u8)distance_cm;
			buf_tmp[0] = (u8)(distance_cm >> 8);
			func_usart2_dma_send_bytes(buf_tmp, 2);
			
			distance_cm = 0;
		}
		GPIO_SetBits(GPIOA, GPIO_Pin_8);
		delay_ms(1000);
		GPIO_ResetBits(GPIOA, GPIO_Pin_8);
		delay_ms(200);
		
	}
}


最终的效果如下:

以上,仅供参考。

  • 11
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
### 回答1: 要实现利用stm32f103rct6和hc-05蓝牙模块来控制LED的功能,需进行以下步骤: 1. 硬件连接:将hc-05模块的TXD引脚连接到stm32f103rct6的RX引脚,将hc-05模块的RXD引脚连接到stm32f103rct6的TX引脚。此外,还需要将hc-05模块的VCC引脚连接到stm32f103rct6的3.3V电源引脚,将hc-05模块的GND引脚连接到stm32f103rct6的地引脚。 2. 软件编程:使用适用的集成开发环境(IDE)如Keil等,进行stm32f103rct6的软件编程。首先,需要配置串口通信的参数,包括波特率、数据位、停止位和校验位等。然后,编写程序以接收从hc-05蓝牙模块发送的控制指令,并解析该指令来确定需要对LED进行的操作。例如,可以使用if语句判断接收到的指令,如果是打开LED的指令,就将stm32f103rct6的GPIO引脚配置为输出模式,并将其输出高电平以点亮LED;如果是关闭LED的指令,就将输出低电平以熄灭LED。 3. 设置hc-05蓝牙模块:使用适用的串口工具连接到hc-05蓝牙模块,设置其波特率和其他参数以确保与stm32f103rct6相匹配。然后,使用蓝牙终端应用程序(如手机上的蓝牙终端应用)连接到hc-05模块,并发送相应的控制指令来控制LED的开关状态。 总结:通过正确的硬件连接和软件编程,可以实现利用stm32f103rct6和hc-05蓝牙模块来控制LED的功能。 ### 回答2: 要实现使用STM32F103RCT6和HC-05蓝牙模块来控制LED功能,可以按照以下步骤进行: 1. 连接硬件:将STM32F103RCT6单片机与HC-05蓝牙模块进行连接。通常,将STM32F103RCT6的UART引脚连接到HC-05蓝牙模块的RX和TX引脚,以便通过串口通信进行数据传输。 2. 配置STM32的UART:使用STM32的开发环境(如Keil或STM32CubeIDE)来配置UART串口通信。设置适当的波特率、数据位、停止位和奇偶校验位,以与HC-05蓝牙模块进行通信。 3. 编写STM32的程序:使用C语言编写STM32的程序,实现蓝牙控制LED功能。首先,初始化串口通信并设置GPIO用于控制LED引脚。然后,通过UART接收来自HC-05蓝牙模块的数据。当接收到特定的指令时,例如“ON”或“OFF”,控制LED引脚的状态,从而实现相应的LED开关。 4. 配置HC-05蓝牙模块:使用蓝牙手机APP或其他蓝牙串口终端软件,连接到HC-05蓝牙模块。确保与STM32的串口通信配置相匹配,以便正确发送控制指令。 5. 测试和调试:将STM32单片机烧录程序并连接到电源。打开蓝牙手机APP或蓝牙串口终端软件,通过蓝牙与HC-05蓝牙模块进行通信,并发送相应的指令来控制LED的开关。观察LED的状态是否与指令一致,如果不一致,可以通过调试程序、检查硬件连接等方式进行故障排除。 总之,利用STM32F103RCT6、HC-05蓝牙模块实现蓝牙控制LED的功能,需要进行硬件连接、配置UART通信、编写STM32程序、配置HC-05蓝牙模块等步骤。正确设置和配置后,通过与蓝牙设备进行通信,即可实现控制LED引脚的开关。 ### 回答3: 要利用STM32F103RCT6和HC-05蓝牙模块实现蓝牙控制LED的功能, 需要进行以下步骤: 1. 首先,连接STM32F103RCT6开发板和HC-05蓝牙模块。将HC-05的TX引脚连接至STM32F103RCT6的Rx引脚,将HC-05的RX引脚连接至STM32F103RCT6的Tx引脚。此外,还需要将LED的一个引脚连接至STM32F103RCT6的一个GPIO引脚,以便控制LED的开关。 2. 在STM32F103RCT6开发板上编写程序。首先,需要设置STM32F103RCT6的GPIO引脚为输出模式,用于控制LED的开关。然后,使用UART串口通信协议,与HC-05蓝牙模块进行通信。通过接收到的蓝牙指令,判断是否是控制LED的指令,若是,则改变LED引脚的电平状态。 3. 配置HC-05蓝牙模块。可通过AT指令,设置蓝牙模块的名称、波特率等参数,以及设定接收和发送数据的格式。确保蓝牙模块与STM32F103RCT6开发板之间能够成功建立蓝牙连接。 4. 编写一个蓝牙控制APP。在移动设备上,编写一个能够与HC-05蓝牙模块通信的APP。通过该APP,可以发送控制LED的指令,例如打开LED、关闭LED等。 5. 在移动设备上运行蓝牙控制APP,并与HC-05蓝牙模块建立连接。在APP上点击相关按钮,即可发送控制LED的指令至HC-05蓝牙模块。 6. STM32F103RCT6开发板通过UART接收到蓝牙指令后,判断指令类型,并相应改变LED引脚的电平状态,从而实现蓝牙控制LED的功能。 通过以上步骤,即可利用STM32F103RCT6和HC-05蓝牙模块实现蓝牙控制LED的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值