00_YDLIDAR_SDM15

1.1 工作模式

YDLIDAR SDM15 单点激光雷达(以下简称 SDM15)的系统设置了 3 种工作模式:空闲模
式、测距模式、停机模式。
空闲模式: SDM15 上电时,默认为空闲模式;空闲模式时,SDM15 的测距单元不工作,激
光器不亮。
测距模式: 当 SDM15 进入测距模式时,点亮激光器,实时输出测距数据。
停机模式: 当 SDM15 运行有错时,如测距异常,自检不过等状况,SDM15 会自动关闭测距
单元,并反馈错误代码。

1.2 系统通信

通信机制如下:
SDM15 是通过串口来和外部设备进行命令和数据的交互。当外部设备发送一个系统命令
至 SDM15,SDM15 解析系统命令,会返回相应的应答报文,并根据命令内容,来切换相应的工
作状态,外部系统根据报文内容,解析报文,便可获取应答数据。

1.3 系统命令如下图:

1.4 系统报文

1.5 数据协议

开启测距:

 

 

 停止测距:

获取版本信息

 设置波特率

 恢复出厂设置

 使用注意

2.STM32单片机实现数据的读取

传感器的接口头文件内容如下:

/**
  ******************************************************************************
  * @file    Project/Bsp/sensor/Sensor.h 
  * @author  Mr_Chen
  * @version V1.0.0
  * @date    2022-12-07
  * @brief   Header for Sensor.c module
  ******************************************************************************
  */

/* Define to prevent recursive inclusion c-------------------------------------*/
#ifndef __SENSOR_H
#define __SENSOR_H			 

/* Includes ------------------------------------------------------------------*/

/* Exported macro ------------------------------------------------------------*/ 		  	
#define RS485_TX_EN		PAout(1)	//485模式控制.0,接收;1,发送.			


/* Exported functions ---------------------------------------------------------*/
typedef  struct{
	void (* init )(void);
	void (* start_sdm15_sensor_scan)(void);
	void (* read_sdm15_sensor_value)(void);
}F_Sensor_Typedef;

extern F_Sensor_Typedef fSensor;

#endif	   

传感器模块的代码如下:

/**
  ******************************************************************************
  * @file    Bsp/sensor/Sensor.c 
  * @author  Mr_Chen
  * @version V1.1.0
  * @date    2022-12-07
  * @brief   Sensor.c module
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/	
#include <string.h>	    
#include "sensor.h"	 

/* Private function prototypes -----------------------------------------------*/
static void RS485_Init(void);		

static u8 send_buf[18]={'\0'};
static u8 Rx_buffer_temp[18];
static u8 Rx_buffer_ok[18];
static u8 Sensor_Data[18];

u8 countsum(u8 *buf)
{
	u8 len = 0;
	u8 checksum =0;
	len = sizeof(buf)+1;
	while(len --)
	{
		checksum += *buf;
		buf++;
	}	
	//保留最后2位
	checksum &=0xFF;
	return checksum;
} 

void START_SDM15_SCAN(void)
{
	u8 i=0; 
	send_buf[0] = 0xAA;    // 包头
	send_buf[1] = 0x55;    // 包头
	send_buf[2] = 0x60;    // 命令:开启测距
	send_buf[3] = 0x00;
	send_buf[4] = 0x5F;    // 校验码
	
	RS485_TX_EN=1;	
	for(i=0; i<=4; i++)
	{
		while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
		USART_SendData(USART2,send_buf[i]); 
	}	
	while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
	RS485_TX_EN = 0;
	delay_ms(100);
}

static void SDM15_Decode(u8 RxData)
{
	static u8 RecCmd_Step=0,Checksum=0,RecCmd_Data_len=0,Data_cnt=0;
	switch(RecCmd_Step){
		case 0:
		if(RxData == 0xAA){
			Rx_buffer_temp[0]=RxData;
			RecCmd_Step++;
		}
		Checksum = 0xAA;
		break;
		
		case 1:
		if(RxData == 0x55){
			Rx_buffer_temp[1]=RxData;
			RecCmd_Step++;
			Data_cnt = 0;
			Checksum+=RxData;
			RecCmd_Data_len = 0;
		}
		else{
			RecCmd_Step = 0;
		}
		break;
		
		case 2:
			Rx_buffer_temp[2]=RxData;
			Checksum+=RxData;
			RecCmd_Step++;
		break;
		
		case 3:
			Rx_buffer_temp[3]=RxData;
			Checksum+=RxData;
			RecCmd_Data_len = Rx_buffer_temp[3];
			RecCmd_Step = RecCmd_Data_len==0 ? 5 : RecCmd_Step+1; 
		break;
		
		case 4:
		if(Data_cnt<RecCmd_Data_len){
			Rx_buffer_temp[4+Data_cnt++]=RxData;
			Checksum+=RxData;
			if(Data_cnt>=RecCmd_Data_len){
			RecCmd_Step++;
			}
		}
		break;
		
		case 5:
		if(Checksum==RxData){
			memcpy(Sensor_Data,&Rx_buffer_temp[0],18); 
			memset(Rx_buffer_temp,0,18);// 清一下数据
			RecCmd_Step=0;
			Data_cnt = 0;
			Checksum = 0;
		}
		else{
			RecCmd_Step = 0;
			Data_cnt = 0;
			Checksum = 0;
			memset(Rx_buffer_temp,0,18);// 清一下数据
		}
		break;
		
		default: break;
	}
}

// 输出距离、强度、干扰 2023-07-10
void print_message(void)
{
	u16 dis;
	u8	engy;
	u8	noise;
	if(Sensor_Data[0] == '\0') return;// 没有信息返回
		
	if(Sensor_Data[3]==0x00)// 没数据长度也返回
	{
		memset(Sensor_Data,0,18);// 清一下数据
		return; 
	}
	dis = Sensor_Data[5]<<8 | Sensor_Data[4];
	engy = Sensor_Data[6];
	noise = Sensor_Data[7];
	
	printf("dis = %d, engy = %d, noise = %d\r\n",dis,engy,noise);
	
	memset(Sensor_Data,0,18);// 清一下数据
	//LED = ~LED;
	//return 1;
}

void USART2_IRQHandler(void)
{
#if SYSTEM_SUPPORT_UCOS 	
		OSIntEnter();	 
#endif
	if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
	{	
		u8 Rx2_Temp = USART_ReceiveData(USART2);
		USART_ClearITPendingBit(USART2, USART_IT_RXNE);
		SDM15_Decode(Rx2_Temp);// 接收一个数据就解析一个数据
	}
#if SYSTEM_SUPPORT_UCOS 	
		OSIntExit();											 
#endif
}

/* Private variables for functions -------------------------------------------*/
F_Sensor_Typedef fSensor = 
{
	.init = RS485_Init, 
	.start_sdm15_sensor_scan = START_SDM15_SCAN,
	.read_sdm15_sensor_value = print_message
};

/* Private functions ---------------------------------------------------------*/
/**
  * @brief  This function to initialise comm usart.
  * @param  None
  * @retval None
  */
static void RS485_Init()
{  	 	
	 GPIO_InitTypeDef GPIO_InitStructure;
	 USART_InitTypeDef USART_InitStructure;
	 NVIC_InitTypeDef NVIC_InitStructure;
		 
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 
	 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);	 
	 
	 //USART2	 
	 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); 
	 
	 //PA1推挽输出,485模式控制  
	 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; 
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 
	 GPIO_Init(GPIOA,&GPIO_InitStructure); 
	 
	// CFG usart
	 USART_InitStructure.USART_BaudRate = 460800;
	 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_Cmd(USART2, ENABLE);
	
	 USART_ClearFlag(USART2, USART_FLAG_TC);
	
	 USART_ITConfig(USART2,USART_IT_RXNE, ENABLE); 
	
	 //Usart2 NVIC 配置
	 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	 // 2022-10-25 修改优先级的配置
	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; 
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;		 
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 NVIC_Init(&NVIC_InitStructure); 
	 RS485_TX_EN=0;

}

RTOS下的任务函数中,获得传感器的数据:

void sensor_test_task(void *pdata)
{
	pdata = pdata;
	u16 cnt = 0;
	delay_ms(5000);// 等待传感器初始化完毕
	do{ fSensor.start_sdm15_sensor_scan(); } while (0);
	for(;;)
	{
        cnt++;
		if(cnt%5==0)
		{
			fSensor.read_sdm15_sensor_value();
		}
        delay_ms(20);// 100ms
     }
}
		

备注:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值