激光测距传感器学习(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.10GPIO_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.11GPIO_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 比特率 115200const eUSCI_UART_ConfigV1 uartConfig ={EUSCI_A_UART_CLOCKSOURCE_SMCLK,                // SMCLK Clock Source26,                                            // BRDIV = 260,                                             // UCxBRF = 0111,                                           // UCxBRS = 111EUSCI_A_UART_NO_PARITY,                        // No ParityEUSCI_A_UART_LSB_FIRST,                        // MSB FirstEUSCI_A_UART_ONE_STOP_BIT,                     // One stop bitEUSCI_A_UART_MODE,                             // UART modeEUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // OversamplingEUSCI_A_UART_8_BIT_LEN                         // 8 bit data length};eusci_calcBaudDividers((eUSCI_UART_ConfigV1 *)&uartConfig, baudRate); //配置波特率
#else//固件库v3_21_00_05//默认SMCLK 48MHz 比特率 115200const eUSCI_UART_Config uartConfig ={EUSCI_A_UART_CLOCKSOURCE_SMCLK,                // SMCLK Clock Source26,                                            // BRDIV = 260,                                             // UCxBRF = 0111,                                           // UCxBRS = 111EUSCI_A_UART_NO_PARITY,                        // No ParityEUSCI_A_UART_LSB_FIRST,                        // MSB FirstEUSCI_A_UART_ONE_STOP_BIT,                     // One stop bitEUSCI_A_UART_MODE,                             // UART modeEUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling};eusci_calcBaudDividers((eUSCI_UART_Config *)&uartConfig, baudRate); //配置波特率
#endifMAP_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; }}}
///读取距离、环境质量、环境光强数值///
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部