前段时间在做一个项目时,用到了一块TFMINI激光测距的传感器,在编写程序时,自己也遇到了一些问题,跟大家分享一下。
首先,简要介绍一下这个传感器的基本情况。
TFmini 是一款小型激光雷达模组。主要实现实时、无接触式的距离测量功能,具有测量准确、稳定、高速的特点。TFmini 产品经过光路与算法优化,已最大程度减小外界环境对测距性能的影响。但限于工作原理,测距范围仍会受到环境光照强度和被测目标反射率不同程度的影响。
①:TFmini 的测距盲区,为 0-30cm,该范围内的数据不可信。
②:TFmini 在极限环境下的测距范围,一般为 0.3-3m,极限条件是指室外强光(夏天正午室外的光照强度约 100klux 左右)下对黑 {MOD}目标物(10%反射率)探测。
③:代表 TFmini 在一般日照条件下(70klux 左右)测量白 {MOD}目标物的测距范围,包含②的范围,为 0.3-7m。
④:代表 TFmini 在室内或环境光很弱的情况下,测距范围为 0.3-12m。
简而言之,这个传感器能够实现元距离较为精确的距离测量。
TFmini 采用串口数据通信协议。通信接口 UART默认波特率 115200,数据位 8,停止位 1,奇偶校验 None。TFmini 有两种数据输出格式,标准数据输出格式(默认)和 pixhawk 数据格式。
标准数据输出格式(默认):数据结构:每个数据包为 9Byte。包含距离信息(Dist)、信号强度信息(Strength)、测距档位(Mode)、数据校验字节(CheckSum)等。数据格式为 16 进制(HEX)。具体数据编码详见表 。
在我的项目中,我用的就是这个默认数据格式。我将这传感器与串口2相连。用串口2接收传感器发送的数据包,并将数据帧解析出来。在这个地方我停滞了很久,原因就是我在串口接收数据时,处理的不到位,导致解析的数据异常。同时,我也查了相当多的资料、论坛,CSDN啥的逛了好久,也借鉴了其他人的方法,包括利用空闲中断啥的,依旧没有解决。没办法,自己就用仿真器仿真调试,一步一步运行,终于解决了这个问题。说来丢人,还是怪自己C语言掌握不牢,在编写解析程序时犯了几个错误。
下面是我调试成功的程序。主要的就是在串口接收中断里的处理。
首先,还是常规的串口2配置: [mw_shl_code=c,true]#include "tfmini.h"#include "delay.h"
#define USART2_REC_LEN 200
#define EN_USART2 1
#define Data_Head 0X59
#define Data_Length 9
u16 USART2_RX_BUF[USART2_REC_LEN];
u16 TFMINI_Distance;
void USART2_Init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
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);
//USART2相关初始化
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_Cmd(USART2, ENABLE);
//Usart2 NVIC配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
[/mw_shl_code]
接下来就是串口接收数据帧的处理了: [mw_shl_code=c,true]void USART2_IRQHandler(void)
{
static u8 seri_count=0;
u16 check_sum=0; //D£Ñéoí
u8 i;
static u8 flag;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
if(USART_ReceiveData(USART2) == Data_Head)
{
flag = 1;
}
if(flag)
{
USART2_RX_BUF[seri_count++] =USART_ReceiveData(USART2);
if(seri_count == Data_Length)
{
if(USART2_RX_BUF[0]==Data_Head && USART2_RX_BUF[1]== Data_Head)
{
for( i = 0; i < Data_Length-1; i++)
{
check_sum += USART2_RX_BUF
; //¼ÆËãD£Ñéoí
}
if((check_sum & 0x00ff)== USART2_RX_BUF[8]) TFMINI_Distance = USART2_RX_BUF[2] + USART2_RX_BUF[3]* 256;
// printf("dis= %d
",data);
seri_count = 0;
flag=0;
}
}
}
}
}[/mw_shl_code] 在此,给大家提供一个解决思路。如果有更好的方法,欢迎大家跟我讨论。
一周热门 更多>