激光测距传感器学习(STM32和MSP432P401R)

目录

模块相关介绍:

原理介绍:

功能描述: ​

 技术参数:​

实物图 :

代码介绍:

STM32版:

串口初始化:

读取数据

讲解

 设置功能参数

MSP432P401R版

串口初始化:

读取数据:


模块相关介绍:

原理介绍:

基于光的时间飞行(Time of Flight)原理。它利用激光器发射一束非常短暂、高能量的激光脉冲,并通过接收器接收反射回来的光脉冲。通过测量激光脉冲从发射到接收的时间差,可以计算出被测物体与测距仪之间的距离。

具体的工作原理如下:

  1. 发射激光脉冲:激光测距仪中的激光器发射一束非常短暂、高能量的激光脉冲。

  2. 光脉冲传播:激光脉冲沿直线路径传播,朝向被测物体。

  3. 光脉冲反射:当激光脉冲遇到被测物体时,部分光能会被物体表面反射回来。这是因为激光脉冲遇到物体时会发生反射、散射或吸收。

  4. 光脉冲接收:激光测距仪中的接收器接收到反射回来的光脉冲。

  5. 时间测量:接收器测量从激光脉冲发射到接收的时间差,也就是激光脉冲的飞行时间。

  6. 距离计算:根据光在真空中的传播速度和测得的时间差,可以使用简单的公式(距离 = 速度 x 时间)计算出被测物体与激光测距仪之间的距离。

本次我所使用的是未来世界机器人的激光测距模块,你可以看成一个升级版的超声波

功能描述: 

 技术参数:

实物图 :

本次讲解:通过串口发送,该模块有好几种测距输出方式,本次只介绍最基本的输出方式:主动输出

主动输出数据意义对照表:

代码介绍:

STM32版:

串口初始化:

void Usart3_Init(void)
{
	GPIO_InitTypeDef   GPIO_InitStructure;
	USART_InitTypeDef  USART_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
	GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);
	
	//USART3_TX		PB.10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;					//复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	//USART3_RX		PB.11
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;			//浮空输入
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	//对串口3通信协议进行初始化设置
	USART_InitStructure.USART_BaudRate = 115200;						//设置波特率
	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_Tx | USART_Mode_Rx;	//双向通信
	USART_Init(USART3, &USART_InitStructure);
	
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);					//开启接收中断	
	USART_Cmd(USART3, ENABLE);

	//对串口3收发中断设置
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);					//中断组选第二组
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;  				
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  		//先占优先级2级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  			//从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 				//IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);
}

读取数据

u8 USART_RX_STA[8] = { 0 };       //接收状态标记	  
u8 Num = 0;              //接收数据的当前位置

	
/*********************************************************************
 *  函数名称:Read_LaserDis
 *  函数功能:读取数据
 *  形    参:ID: 模块编号,*Data: 读取到的数据
 *  输    出:无
 *  备    注:无
 ********************************************************************/   
void Read_LaserDis(unsigned char ID, unsigned int *Data)       
{	
	unsigned char y=0;
	unsigned int Receive_data [3] = { 0 };       //数据缓存区

	Num = 0; 
///读取距离、环境质量、环境光强数值///
	while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
	USART_SendData(USART3, 0x57);																//命令起始信号
	while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);	

	while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
	USART_SendData(USART3, ID);																  //ID模块编号
	while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
	Delay_ms(2);

  while(1)
  {
		if(USART_RX_STA[0] != 0x75) { Num = 0; }  //判断帧头0x75,否者重新接收
		if(Num == 8)
		{
			Num = 0;
			if(USART_RX_STA[7] == 0x07)  //判断帧尾0x07,否者不赋值
			{
				Receive_data[0] = USART_RX_STA[1];
				Receive_data[0] <<= 8;
				Receive_data[0] |= USART_RX_STA[2];        
				*Data = Receive_data[0];          //距离
				
				Receive_data[1] = USART_RX_STA[3];
				Receive_data[1] <<= 8;
				Receive_data[1] |= USART_RX_STA[4];
				*(Data+1) = Receive_data[1];          //环境质量
				
				Receive_data[2] = USART_RX_STA[5];
				Receive_data[2] <<= 8;
				Receive_data[2] |= USART_RX_STA[6];
				*(Data+2) = Receive_data[2];         //环境光强        
				
				break;
			}        
			break;
		}
    else
    {
      Delay_ms(1);y++;
      if(y==10) { Num = 0;break; }
    }
  }
///读取距离、环境质量、环境光强数值///
}
讲解

内部实现逻辑如下:

  1. 定义了一个缓存区 Receive_data[3],用来存储读取到的数据。

  2. Num = 0; 将变量 Num 初始化为 0,用于计数接收到的数据字节数。

  3. 发送命令起始信号 0x57 到激光测距模块,表示开始读取数据。

  4. 发送激光测距模块的 ID 号码。

  5. 延时 2 毫秒。

  6. 进入一个循环,判断接收到的数据是否满足要求。

  7. 判断帧头是否为 0x75,如果不是,则重新接收。

  8. 如果接收到的数据字节数为 8,则表示接收完成。

  9. 判断帧尾是否为 0x07,如果是,则将接收到的数据赋值给相应的变量。

  10. 跳出循环。

  11. 返回读取到的距离、环境质量和环境光强的值。

 设置功能参数

/*********************************************************************
 *  函数名称:Set_LaserDis
 *  函数功能:设置功能参数
 *  形    参:ID: 模块编号,Fun: 功能项,Par: 参数,
 *  输    出:无
 *  备    注:无
 ********************************************************************/
void Set_LaserDis(unsigned char ID, unsigned char Fun,unsigned char Par)	       
{	
 ///设置功能参数///	
	while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
	USART_SendData(USART3, 0x4C);																//命令起始信号
	while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);	
	
	while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
	USART_SendData(USART3, ID);																  //ID模块编号
	while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
	
	while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
	USART_SendData(USART3, Fun);																//功能项
	while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);	
	
	while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
	USART_SendData(USART3, Par);																//参数
	while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);

///设置功能参数///		
}

MSP432P401R版

不懂432串口的请参考:MSP432P401R第三讲:串口通信_三马分享家的博客-CSDN博客

串口初始化:

void uart_A1_init(uint32_t baudRate)
{
#ifdef EUSCI_A_UART_7_BIT_LEN
  //固件库v3_40_01_02
  //默认SMCLK 48MHz 比特率 115200
  const eUSCI_UART_ConfigV1 uartConfig =
      {
          EUSCI_A_UART_CLOCKSOURCE_SMCLK,                // SMCLK Clock Source
          26,                                            // BRDIV = 26
          0,                                             // UCxBRF = 0
          111,                                           // UCxBRS = 111
          EUSCI_A_UART_NO_PARITY,                        // No Parity
          EUSCI_A_UART_LSB_FIRST,                        // MSB First
          EUSCI_A_UART_ONE_STOP_BIT,                     // One stop bit
          EUSCI_A_UART_MODE,                             // UART mode
          EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
          EUSCI_A_UART_8_BIT_LEN                         // 8 bit data length
      };
  eusci_calcBaudDividers((eUSCI_UART_ConfigV1 *)&uartConfig, baudRate); //配置波特率
#else
  //固件库v3_21_00_05
  //默认SMCLK 48MHz 比特率 115200
  const eUSCI_UART_Config uartConfig =
      {
          EUSCI_A_UART_CLOCKSOURCE_SMCLK,                // SMCLK Clock Source
          26,                                            // BRDIV = 26
          0,                                             // UCxBRF = 0
          111,                                           // UCxBRS = 111
          EUSCI_A_UART_NO_PARITY,                        // No Parity
          EUSCI_A_UART_LSB_FIRST,                        // MSB First
          EUSCI_A_UART_ONE_STOP_BIT,                     // One stop bit
          EUSCI_A_UART_MODE,                             // UART mode
          EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
      };
  eusci_calcBaudDividers((eUSCI_UART_Config *)&uartConfig, baudRate); //配置波特率
#endif

	MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);//GPIO复用
  MAP_UART_initModule(EUSCI_A1_BASE, &uartConfig);//初始化串口函数
  MAP_UART_enableModule(EUSCI_A1_BASE);//使能串口模块
	UART_enableInterrupt(EUSCI_A1_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);//开启串口相关中断
	Interrupt_enableInterrupt(INT_EUSCIA1);//开启串口端口中断
}

读取数据:

uint8_t USART_A1_RX_STA[8] = { 0 };       //接收状态标记	  
uint8_t Num = 0;              //接收数据的当前位置

	
/*********************************************************************
 *  函数名称:Read_LaserDis
 *  函数功能:读取数据
 *  形    参:ID: 模块编号,*Data: 读取到的数据
 *  输    出:无
 *  备    注:无
 ********************************************************************/   
void Read_LaserDis(unsigned char ID, unsigned int *Data)       
{	
	unsigned char y=0;
	unsigned int Receive_data [3] = { 0 };       //数据缓存区

	Num = 0; 
///读取距离、环境质量、环境光强数值///
	//while (EUSCI_A1->IFG & EUSCI_A_IFG_TXIFG);
	UART_transmitData(EUSCI_A1_BASE,0x57);	//命令起始信号
	//while (EUSCI_A1->IFG & EUSCI_A_IFG_TXIFG);	

	//while (EUSCI_A1->IFG & EUSCI_A_IFG_TXIFG);
	UART_transmitData(EUSCI_A1_BASE,ID);//ID模块编号
	//while (EUSCI_A1->IFG & EUSCI_A_IFG_TXIFG);
	delay_ms(2);

  while(1)
  {
		if(USART_A1_RX_STA[0] != 0x75) { Num = 0; }  //判断帧头0x75,否者重新接收
		if(Num == 8)
		{
			Num = 0;
			if(USART_A1_RX_STA[7] == 0x07)  //判断帧尾0x07,否者不赋值
			{
				Receive_data[0] = USART_A1_RX_STA[1];
				Receive_data[0] <<= 8;
				Receive_data[0] |= USART_A1_RX_STA[2];        
				*Data = Receive_data[0];          //距离
				
				Receive_data[1] = USART_A1_RX_STA[3];
				Receive_data[1] <<= 8;
				Receive_data[1] |= USART_A1_RX_STA[4];
				*(Data+1) = Receive_data[1];          //环境质量
				
				Receive_data[2] = USART_A1_RX_STA[5];
				Receive_data[2] <<= 8;
				Receive_data[2] |= USART_A1_RX_STA[6];
				*(Data+2) = Receive_data[2];         //环境光强        
				
				break;
			}        
			break;
		}
    else
    {
      delay_ms(1);y++;
      if(y==10) { Num = 0;break; }
    }
  }
///读取距离、环境质量、环境光强数值///
}

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值