维特智能激光测距仪VL53-400S_stm32f1驱动代码解析

开发板(原子的mini stm32)主控stm32F103RCT6

模块:维特智能VL53-400S激光测距仪(以下简称VL53)

模块与主控之间串口通信

目录

将VL53设置为Modbus模式

代码验证

结果


将VL53设置为Modbus模式

需要一个USB转TTL的串口模块,某宝上大概5块一个,CH340的

用串口模块连接VL53和电脑

5V接VCC,GND接GND

串口模块的RX接VL53的TX

串口模块的TX接VL53的RX

登录维特智能官网下载维特智能上位机

 按照上面产品说明书中给出的步骤用维特的上位机连接VL53并设置为Modbus模式

设置为Modbus后VL53不再自动返回测量数据,用XCOM验证一下

具体步骤也在产品说明书里,确定成功设定

代码验证

用开发板连接VL53和电脑,原子的mini可以用串口1和电脑通信,在XCOM上显示,如果你的板不能直连的话可以考虑用0.96那个OLED显示或者用前面的串口模块连接开发板和电脑,有点麻烦

主要使用了两个串口和一个按键中断,串口1给电脑发数据,串口2和VL53通信,按键中断里发起一次读取测量数据的请求

main.c

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "uart2.h"
#include "key.h"

extern u8 rx_buffer[100];    //串口2接收的数据
extern u8 counter;           //串口2数据接收计数
extern u8 flag;              //串口2接收到7个数据标志
extern u8 printf_flag;       //按键中断后打印测量数据标志

int main(void)
{	
	u8 i;

	delay_init();	    	 //延时函数初始化	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
	uart_init(115200);	  //串口1初始化为115200
	Initial_UART2(115200);//串口2初始化
	LED_Init();		  	 //初始化与LED连接的硬件接口 
	EXTIX_Init();   //按键中断初始化
	
	printf("usart1_on\r\n");//初始化结束后示意串口1已开启
	
	for(i=0;i<50;i++)//保险起见前50个先置零,其实用不了这么多
		rx_buffer[i] = 0;
	
	while(1)
	{
		
		if(printf_flag == 1){      //只有每发起一次读数据请求后才打印测量值避免不断输出
		
			if(flag == 1){         //串口2收到7个数据
				if(rx_buffer[0] == 0x50)    //验证数据头是否为0x50
					printf("head_right\r\n");    //数据头正确则提示
					
				for(i=0;i<=counter;i++){
					printf("%x__",rx_buffer[i]);    
                    //打印测量数据,建议格式化输出,我用的下划线

					rx_buffer[i] = 0;               //输出后清零,其实也可以不清
					if(i == 6)                      //输出7个数据后换行方便观察
						printf("\r\n");
					}
				counter = 0;    //重置计数位,下一次接收数据从零开始
				flag = 0;       //标志位清零
			}
			else
				printf("head_wrong\r\n");  //数据错误
			
			printf_flag = 0;  //打印标志清零,避免反复打印
		}		
	}

}

 uart_init(115200);      //串口1初始化为115200

前面还有重定向的部分没粘

void uart_init(u32 bound){
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	
    //使能USART1,GPIOA时钟
  
	//USART1_TX   GPIOA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
    //USART1_RX	  GPIOA.10初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

    //USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	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(USART1, &USART_InitStructure); //初始化串口1
    USART_Cmd(USART1, ENABLE);                    //使能串口1 

}

Initial_UART2(115200);//串口2初始化

#include "uart2.h"
#include "usart.h"

//串口2初始化
void Initial_UART2(unsigned long baudrate)
{
	
 	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure; 
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;    //USART2_TX
	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;    USART2_RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	USART_InitStructure.USART_BaudRate = baudrate;
	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_TXE, DISABLE);    
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
	
	USART_ClearFlag(USART2,USART_FLAG_TC);	
	USART_Cmd(USART2, ENABLE);

}


void USART2_IRQHandler(void)
{
	u8 Res;
	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){
	  
		Res =USART_ReceiveData(USART2);    //读串口接收到的数据
		rec_data_handle(Res);              //处理数据,写的有点啰嗦  
		USART_ClearITPendingBit(USART2, USART_IT_RXNE);
  }
	USART_ClearITPendingBit(USART2,USART_IT_RXNE);
}


void UART2_Put_Char(unsigned char DataToSend){
	
	USART_SendData(USART2,DataToSend); 
	while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
	
}

u8 rx_buffer[100];    //接收的数据先放在这里面,在while(1)里面处理
u8 counter;
u8 flag = 1;

void rec_data_handle(u8 rec_data){
	
	rx_buffer[counter++] = rec_data;
	if(counter == 7)    //接到7个数据就表明有一个完整的数据包
		flag = 1;

}


//用串口2给VL53发送指令
void sendcmd_usart2(char cmd[])
{
	
	char i;
	for(i=0;i<8;i++){
	    UART2_Put_Char(cmd[i]);
	}
	
}

EXTIX_Init();//按键中断初始化,在中断里发起一次读数据请求

#include "key.h"
#include "delay.h"
#include "uart2.h"
   
//按键初始化函数 
//PC5 设置成输入
void KEY_Init(void){

	GPIO_InitTypeDef GPIO_InitStructure;

 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能PORTC时钟

	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_5;//PC5
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
 	GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC5
} 


void EXTIX_Init(void){
	
 	EXTI_InitTypeDef EXTI_InitStructure;
 	NVIC_InitTypeDef NVIC_InitStructure;

  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    //外部中断,需要使能AFIO时钟

	KEY_Init();//初始化按键对应io模式

    //GPIOC.5 中断线以及中断初始化配置
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);

  	EXTI_InitStructure.EXTI_Line=EXTI_Line5;
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);	 	
    //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
		
	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;			
    //使能按键所在的外部中断通道

  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2, 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;		    //子优先级1
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			    	//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure); 
 

}

char read_data[8] = {0x50,0x03,0x00,0x34,0x00,0x01,0xc8,0x45};//在维特官网上有
u8 printf_flag;    //每进入一次中断在XCOM上输出一次数据

void EXTI9_5_IRQHandler(void){	
	
	delay_ms(10);   //消抖			 
	if(KEY0==0)	{
        sendcmd_usart2(read_data);//发送读数据请求
		printf_flag = 1;
	}
 	 EXTI_ClearITPendingBit(EXTI_Line5);    //清除LINE5上的中断标志位  
}

结果

没搞明白这几个零哪来的,而且每次得按两次,比较勉强,数据处理的有点糙

有需要完整工程的评论留邮箱

 小白一个,有错还请指正

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
若您想刷新sa400s37240固件,以下是一些步骤供参考: 1. 首先,您需要前往Kingston官方网站,找到适用于sa400s37240型号的最新固件版本。下载该固件文件并确保保存在易于访问的位置。 2. 在您的电脑上打开一个文件管理器窗口,并连接sa400s37240固态硬盘到计算机的可用SATA端口。同时,确保您拥有管理员权限。 3. 在开始菜单中搜索并打开“磁盘管理”工具。您可以通过右键点击“此电脑/我的电脑”,选择“管理”,然后在左侧找到“磁盘管理”选项。 4. 在磁盘管理窗口中,找到您的sa400s37240固态硬盘。检查该硬盘上是否有分区,如果有,请备份重要数据,因为刷新固件可能会导致数据丢失。 5. 关闭磁盘管理工具,然后打开下载的固件文件。通常,固件文件会以可执行文件 (exe) 的形式提供。双击运行该文件。 6. 在固件刷新程序中,您可能需要选择要刷新的设备。请确保选择正确的设备,即sa400s37240固态硬盘。 7. 根据刷新程序的指示,完成固件刷新过程。整个过程可能需要几分钟时间,具体取决于您的系统性能和固件文件的大小。 8. 一旦固件刷新完成,您可以重新启动计算机,并再次使用磁盘管理工具检查刷新后的固态硬盘。 请注意,刷新固件是一个敏感的操作,因此在执行之前,请确保已经备份了重要的数据。同时,仅使用制造商官方提供的固件进行刷新,避免使用非官方或未经验证的固件文件,以免对您的设备造成损害。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值