基于STM32和超声波测距传感器的测距功能设计

Posted 跋扈洋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于STM32和超声波测距传感器的测距功能设计相关的知识,希望对你有一定的参考价值。

基于STM32和超声波测距传感器的测距功能设计(使用陌生传感器的流程介绍)

引言

最近和很多单片机和嵌入式的初学者交流,发现大家对使用一个没接触过的传感器往往感到无从下手。正好我最近使用一款我以前没使用过的超声波测距传感器开发新的功能,这里就来逐步详细的介绍如何使用一款陌生的传感器。大家在项目开发中,如果使用陌生传感器没有思路,可以仔细看一下本文。可以说,几乎使用所有的传感器,往往开发流程大同小异,所以阅读本文其实就可以对开发有一个清晰的认识。

项目设计

项目简介

本项目选用STM32为MCU,使用485接口的超声波测距传感器,实现测量距离的功能。

开发工具

  1. keil 5:STM32程序开发平台
  2. SSCOM:串口调试助手

硬件设计

  1. 使用目前主流的STM32F103C8T6充当MCU(编写程序使用标准库)。
  2. 使用KS114超声波测距传感器,其中数据传输接口为485(具体使用何种型号和厂商的传感器其实不重要,只要选用好是何种接口,比如是485还是IIC,另外配有手册就可以完成开发,本文也会详细介绍如何接触一个陌生的传感器模块进行开发的流程)。
  3. USB转TTL模块,主要为了调试用,没有也可以。

软件设计

  1. 需要在STM32单片机和超声波测距传感器之间建立通信,因为是485,所以主要是编写USART的数据收发。
  2. 查询手册获取控制超声波传感器的控制指令,每250ms向超声波测距传感器发送一次控制超声波测距传感器测距的命令。
  3. 将接收到的距离值进行校验,保证数据安全。
  4. 将接收到的距离值进行解析,转换成米和厘米的组合。

注:现在常规使用的传感器往往集成化很高,我们其实就是使用传感器提供的接口进行数据收发并对数据进行处理,无非就是使用什么通信方式而已。

开发流程

阅读手册

  1. 我们使用一个陌生的传感器,首先需要看一下他的功能摘要。

  1. 然后需要查看传感器的电性能参数,比如我们使用超声波测距传感器,我们就可以看一下他的供电电压、波束脚和工作状态的功率。

  1. 使用一个传感器,我们必须知道传感器每个引脚具体是什么作用的。比如正、负极和485通信引脚。

可以看到,图中说明了485-A、485-B、正极和负极具体是那个颜色的线,我们使用的时候也就可以接上相应的线。

  1. 对于使用陌生的传感器最关键的就是要看一下此传感器的工作流程。


我们从上述手册中知道了,使用此超声波测距传感器的主要流程是:先配置相关波特率、串口地址等基本信息 ->向超声波测距传感器发送测距命令 -> 接收超声波测距的命令。

  1. 从手册的工作流程我们知道,我们需要知道超声波的地址有哪些,然后开始查手册。

  1. 我们还需要知道探测指令都有哪些,之后仍然是查手册。

  1. 我们如果想使用多个超声波传感器,那么一般需要传感器给我们回传的信息中有相应的标识,此传感器中的串口地址就有此效果,那么如何让他回传呢,我们还是要查手册获得。

我们看到如何配置此通信协议了。

  1. 在手册的最下面我们看到他的使用建议里有如何快速上手,这往往可以让我们的开发更加快捷。

配置并测试传感器相关设置

注:每个传感器的配置流程和测试流程都不同,这里只是以本次使用的超声波测距传感器为例进行介绍平时的流程。读者进行开发的时候,还是要你自己使用的传感器手册为准,本节大家大致看一下即可,不用细看。

  1. 首先我们使用USB转TTL模块,将其中的485-A和485-B和超声波传感器的A和B相连,并将超声波测距传感器的正负极连接上电源并通电。
  2. 使用传感器手册中给的调试软件,根据手册给的串口信息进行设置。

连接成功后,我们可以向传感器发送控制指令,测试一下是否能正常使用。

  1. 我们需要修改波特率,这里设置为9600。

当修改完波特率后,我们以刚设置的波特率重新连接一下。

  1. 我们修改一下地址,这里设置为ea。

  1. 最后我们修改一下通信协议,选择手册里我们查询到的对应通信格式的指令,然后设置。

  1. 最后就是发送指令,测试是否符合我们的要求。

我们看到,测试的效果完全符合我们的预期,那么我们就可以进行MCU的软件开发了。

软件开发

  1. 为了增强可读性,我们往往需要将一些数据使用宏定义增加代码的可读性。我们将传感器手册中,我们使用到的指令都可以宏定义一下。
/****定义指令****/
#define Left_Address_cmd		0xe8
#define Right_Address_cmd 		0xea
#define Register_02_cmd  		0x02
#define Probe1_cmd 	 		    0x14//探测范围1cm-2m
#define Probe2_cmd         		0x1e//探测范围1cm-3m
#define Probe3_cmd         		0xb0//探测范围1cm-5m
  1. 我们要开发MCU和超声波测距传感器的通信,硬件上只需要将485的A与B连接上即可,下面主要说一下软件的编写。首先我们需要初始化串口,相关的程序我相信大家都看过很多次了。
void USART2_485_Init(u32 bound)

    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    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);
    // 使能串口接收中断
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
    USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
    USART_Cmd(USART2, ENABLE);
    // 清除发送完成标志
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0X08;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0X00;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

然后编写串口发送。

void USART_Send(USART_TypeDef* USARTx,u8 *data, u8 len)

    for(int i = 0; i < len; i++)
    
        USART_SendData(USARTx, data[i]); //向串口发送数据

        while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); //等待发送结束
    

最后编写串口接收函数,这里使用中断接收。

void USART2_IRQHandler(void)                

    u8 Res;
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断
    
        Res = USART_ReceiveData(USART2);	//读取接收到的数据
        if(rbWrite(&pRb_dis, &Res, 1) != 1)//此处使用到了环形队列,每次接收一个字节放进环形队列中,环形队列的编写不是此项目的重点,大家可以用别的方式实现,主要是存下来字节的数据。
        
            printf("DIS_溢出");				
        
    
		else if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)  //接收中断
    
        USART2->SR;//先读SR寄存器
        USART2->DR; //再读DR寄存器
    


  1. 我们编写函数实现给超声波发送相关指令,控制超声波执行对应工作的任务。
void control_ultrasonic(uint8_t address,uint8_t instruction)

	uint8_t tmp[5];
	switch(instruction)
	
		case  Probe1_cmd:
			tmp[0]=address;
			tmp[1]=Register_02_cmd;
			tmp[2]=Probe1_cmd;
			USART_Send(USART2,tmp,3);
			break;
		case  Probe2_cmd:
			tmp[0]=address;
			tmp[1]=Register_02_cmd;
			tmp[2]=Probe2_cmd;
			USART_Send(USART2,tmp,3);
			break;
		case  Probe3_cmd:
			tmp[0]=address;
			tmp[1]=Register_02_cmd;
			tmp[2]=Probe3_cmd;
			USART_Send(USART2,tmp,3);
			break;	
    default:
        break; 
	

此函数的编写主要就是将我们需要发送的指令放在一个数组中,然后调用串口发送函数进行发送。

在这里我们也可以很明显的发现宏定义的好处,让这里可读性增强了非常多。

  1. 我们使用传感器,最重要的当然是想要传感器的数据。我们一般需要编写一个函数用以处理我们接受到的传感器的数据,也就执行数据处理的角色。
void distance_data(void)

	uint8_t  dis_Temp_Buff[4] = 0;
	rbRead(&pRb_dis, dis_Temp_Buff, 4);	
	if(((dis_Temp_Buff[0]==Left_Address_cmd)&&(dis_Temp_Buff[3]==((uint8_t)(Summation(dis_Temp_Buff,3)&0xFF)))))
	
		Ultrasonic_distance[0]=dis_Temp_Buff[1];
		Ultrasonic_distance[0]=(Ultrasonic_distance[0]<<8)|(dis_Temp_Buff[2]);
	
	else if( (dis_Temp_Buff[0]==Right_Address_cmd)&&( dis_Temp_Buff[3]==((uint8_t)(Summation(dis_Temp_Buff,3)&0xFF))) )
	
		Ultrasonic_distance[1]=dis_Temp_Buff[1];
		Ultrasonic_distance[1]=(Ultrasonic_distance[1]<<8)|(dis_Temp_Buff[2]);
	 
	else
	
		Dis_Error_Cnt++;
        if(Dis_Error_Cnt > 5)
        
                Dis_Error_Cnt = 0;
                printf("超声波距离数据错误");
        
	

我们首先将环形队列中的数据取出来四个字节放在一个数组中,然后我们进行数据校验,校验方式可以在手册中得到。数据校验正确时,我们将超声波发来的数据中代表距离的数据,放在一个全局变量中,这样的好处是,方便我们在任何一个函数中使用。此时其实我们的主要需求已经都能满足,项目主体已经完成。

  1. 最后就是使用我们编写的这些程序,因为每个人的需求都不同,这里也就不具体放代码了。但编写流程就是:循环发送control_ultrasonic(Left_Address_cmd ,Probe2_cmd);和control_ultrasonic(Right_Address_cmd,Probe2_cmd);,使超声波传感器一直将测量的距离发送给MCU -> 调用processing_distance_data函数将接受到的数据进行数据处理 ->我们想要使用这个数据的时候,直接读取这个Ultrasonic_distance全局变量数组即可使用距离数据。

总结

嵌入式软件工程师和单片机工程师使用一个陌生的传感器的流程上面已经详细介绍完毕。具体流程就是先仔细阅读一遍技术手册或者说明书,然后使用配套软件或者其他第三方软件进行需要的配置信息设置和大致通信测试,再后进行程序的编写,最后是进行总体测试。可以说,使用所有传感器几乎都是这几个步骤,大家可以试一下。

后续

更多嵌入式开发知识可以关注公众号:物联网知识。欢迎大家和我进行交流,一同进步。

以上是关于基于STM32和超声波测距传感器的测距功能设计的主要内容,如果未能解决你的问题,请参考以下文章

基于STM32和超声波测距传感器的测距功能设计(如何使用陌生传感器的流程介绍)

基于STM32温湿度传感器采集报警系统设计(含超声波测距)

stm32与HC-SR04超声波传感器测距

(STM32CubeMX)超声波模块测距传感器学习笔记

基于STM32的超声波测距proteus仿真 HC-SR04(仿真+源码)

STM32超声波模块测距控制舵机