STM32串口接收正点原子MS53L1M激光测距模块数据

目录

1.前言

2.配置VL53L0X激光测距模块

1.接线部分

2.上位机配置 

3.分析接收数据

3.STM32接收激光测距模块数据并打印到电脑和在OLED屏上显示

1.接线部分

2.STM32F103代码

        1.主函数代码

        2.串口1代码

4.实验现象和完整源码


 

1.前言

        因为一个项目需要用到测距模块,所以接触到正点原子的MS53L1M激光测距模块,刚好最近有在调试串口接收数据包,于是我就尝试写一个标准库接收的代码。

2.配置VL53L0X激光测距模块

        在与STM32通信之前先使用正点原子自带的上位机对激光测距模块进行配置

        上位机下载地址: https://pan.baidu.com/s/10eQFh6TeAuCfJO3vPgCJew 提取码:fcak

1.接线部分

         如上图所示正点原子的这个激光测距模块,有2种通信方式串口通信和IIC通信,我使用的是串口通信方式,用USB转TTL模块将激光测距模块连接上电脑

USB转TTL模块激光测距模块
3.3V红线
GND黑线
RXD黄线
TXD白线

2.上位机配置 

         首先选择对应串口,配置对应波特率,再打开串口选择TOF_4M后,点击搜索模块,找到模块后就可以进行配置了。

        设备ID:更改不同的ID,可以通过串口读取所有的模块的测距距离,本文未涉及。

        工作模式:工作模式有三种,正常串口模式,IIC模式,MODBUS模式。我就使用了正常模式。

3.分析接收数据

        对激光测距模块配置好后,随便使用一个串口助手接收一下数据,先使用ASCII码接收,显示数据为:

 真正需要的数据为d:462 MM 此时我们在将数据接收模式换成HEX的模式,显示数据为:

 可以发现每组距离数据前后都会有d:     (空格)MM,对应的HEX为64 4A          20 6D 6D(空格的ASCII为0x20),那我们只需要写一个数据包格式为帧头1 64,帧头2 4A帧尾为20的数据包,就可以接收激光测距模块的数据了。

3.STM32接收激光测距模块数据并打印到电脑和在OLED屏上显示

1.接线部分

激光测距模块STM32F103
3.3V3.3V
GNDGND
黄线PA10
STM32F103USB转TTL模块
3.3V3.3V
GNDGND
PA2RXD

2.STM32F103代码

        1.主函数代码

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Serial.h"
#include "Serial2.h"
int main (void)
{
	OLED_Init();
	Serial_Init();
	Serial2_Init();
	OLED_ShowString(1,1,"d:    mm");
	while(1)
	{
		int D = Cx*1000+Cy*100+Cz*10+Cw;
		OLED_ShowNum(1,4,D,4);
		SendData(Cx,Cy,Cz,Cw);//将数据发送到电脑
	}

}

        2.串口1代码

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>

uint8_t Cx,Cy,Cz,Cw;
        
                           
void Serial_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	//USART1_RX	  PA10
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode =USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART1, &USART_InitStructure);
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	USART_Cmd(USART1, ENABLE);
}

void USART1_IRQHandler(void)			 
{
		u8 com_data; 
		u8 i;
		static u8 RxCounter1=0;
		static u16 RxBuffer1[7]={0};
		static u8 RxState = 0;	

		if( USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)  	   //接收中断  
		{
			
				USART_ClearITPendingBit(USART1,USART_IT_RXNE);   //清除中断标志
				com_data = USART_ReceiveData(USART1);
				if(RxState==0&&com_data==0x64)  //0x2c帧头
				{
					
					RxState=1;
					RxBuffer1[RxCounter1++]=com_data;
				}
		
				else if(RxState==1&&com_data==0x3A)  //0x12帧头
				{
					RxState=2;
					RxBuffer1[RxCounter1++]=com_data;
				}
		
				else if(RxState==2)
				{
					RxBuffer1[RxCounter1++]=com_data;

					if(RxCounter1==7 && com_data == 0x20)       //RxBuffer1接受满了,接收数据结束
					{
						
						Cx=RxBuffer1[RxCounter1-5];
						Cy=RxBuffer1[RxCounter1-4];
						Cz=RxBuffer1[RxCounter1-3];
						Cw=RxBuffer1[RxCounter1-2];
						if(Cx<48)
						{
							Cx=0;
						}
						else
						{
							Cx-=48;
						}	
						if(Cy<48)
						{
							Cy=0;
						}
						else
						{
							Cy-=48;
						}
							if(Cz<48)
						{
							Cz=0;
						}
						else
						{
							Cz-=48;
						}
							if(Cw<48)
						{
							Cw=0;
						}
						else
						{
							Cw-=48;
						}
						RxCounter1 = 0;
						RxState = 0;	
					}
					else if(RxCounter1 > 7)
					{
						RxState = 0;
						RxCounter1=0;
						for(i=0;i<7;i++)
						{
								RxBuffer1[i]=0x00;      //将存放数据数组清零
						}
					
					}
				}
				else   //接收异常
				{
						RxState = 0;
						RxCounter1=0;
						for(i=0;i<7;i++)
						{
								RxBuffer1[i]=0x00;      //将存放数据数组清零
						}
				}

		}
		
}

        此接收代码接收数据包的逻辑在我的上一篇文章STM32与K210串口通信已经讲过了,这里就不重复在说了,感兴趣的话可以去那篇文章看一看。

        唯一不同的就是对接收到的数据进行了一点处理,因为我们接收到的数据为ASCII对应的数字,所以要进行一定的转化。

 

                        if(Cx<48)
                        {
                            Cx=0;
                        }
                        else
                        {
                            Cx-=48;
                        }    
                        if(Cy<48)
                        {
                            Cy=0;
                        }
                        else
                        {
                            Cy-=48;
                        }
                            if(Cz<48)
                        {
                            Cz=0;
                        }
                        else
                        {
                            Cz-=48;
                        }
                            if(Cw<48)
                        {
                            Cw=0;
                        }
                        else
                        {
                            Cw-=48;
                        }

         因为ASCII数据与我们所需要数据差48,所以需要将每个数据减掉48,但因为激光测距模块的首位数据为零的话,它会发送0x20也就是空格,所以我们需要使用判断将其置零。

3.串口2代码

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>
#include "Delay.h"
char sendBuf2[10];

void Serial2_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	//USART2_TX 
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//USART2_RX	 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART2, &USART_InitStructure);
	
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =5;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
	NVIC_Init(&NVIC_InitStructure);
	
	USART_Cmd(USART2, ENABLE);
}
void Serial2_SendByte(uint8_t Byte)
{
	USART_SendData(USART2, Byte);
	while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
}
void Serial2_SendString(char *String)
{
	uint16_t i;
	for (i = 0; String[i] != '\0'; i ++)
	{
		Serial2_SendByte(String[i]);
	}
}

void Serial2_Printf(char *format, ...)
{
	char String[100];
	va_list arg;
	va_start(arg, format);
	vsprintf(String, format, arg);
	va_end(arg);
	Serial2_SendString(String);
}


void SendData(u8 a1,u8 a2,u8 a3,u8 a4)
{			
			sprintf((char *)sendBuf2, "d:%d%d%d%dmm\r\n",a1,a2,a3,a4);    
			Serial2_SendString(sendBuf2);
			Delay_ms(100);
}

        此代码是将从激光测距模块获得的数据发送给电脑。

4.实验现象和完整源码

                                                                      OLED显示距离 

                                                                     串口打印显示 

 完整源码:主控/C8T6/stm32接收激光测距模块 · 亟待/electronic-game-code - 码云 - 开源中国 (gitee.com)icon-default.png?t=N3I4https://gitee.com/AD123zsg/electronic-game-code/tree/master/%E4%B8%BB%E6%8E%A7/C8T6/stm32%E6%8E%A5%E6%94%B6%E6%BF%80%E5%85%89%E6%B5%8B%E8%B7%9D%E6%A8%A1%E5%9D%97

 

  • 14
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值