目录
第一部分、前言
1、TOF10120激光测距模块的基本知识
2、TOF的引脚
3、与单片机的接线
第二部分、工程代码
1、代码功能描述
2、tof.h文件
3、tof.c文件
4、main.c文件
第三部分、总结
1、TOF10120的数据参考手册
2、完整的工程代码
第一部分、前言
1、TOF10120激光测距模块的基本知识
模块最佳距离测量范围:10cm~180cm。这里的范围是指这个模块在这个距离范围内测到的数据都非常准确,而不是指我只能测量这个范围的距离,其它距离测量不了,超过这个距离范围,误差会大一点而已。
工作电压:3.3V~5V都可以,不容易烧。
通讯协议:这个模块支持串口协议和IIC协议,串口协议默认波特率9600,但是我这个工程是利用IIC协议调试的,因为单片机的串口毕竟有限。
2、TOF的引脚
下图是我模块的样子,从左到右的引脚对应如下表格
绿线SCL蓝线SDA白线TXD黄线RXD红线VCC黑线GND
![](https://img-blog.csdnimg.cn/1fe007e30c534c3a9c5c9a65d24ac3a6.png)
3、与单片机的接线
本次调试利用的是IIC协议,没有用到串口,因此白线和黄线就可以不要了,后来我直接把这根线直接给剪掉了😂。
IIC协议是模拟出来,绿线SCL —— PB12;蓝线SDA —— PB13,注意:单片机用的核心板C8T6。
第二部分、工程代码
1、代码功能描述
串口一不断将距离数据打印在电脑的串口助手,每隔1s打印一次,LED闪烁。注意:这里得到的距离数据已经是模块内部滤波后的数据,这种得到的数值比较平滑。如果想要得到实时距离,需要更改寄存器的值,这里请自行参考TOF10120的技术手册。
![](https://img-blog.csdnimg.cn/a8a2a27cabfa425a9700d64c2cd908db.png)
2、tof.h文件
#ifndef __TOF_H
#define __TOF_H
#include "sys.h"
// 绿线SCL —— PB12
// 蓝线SDA —— PB13
//管脚宏定义
#define I2C_SCL_PIN GPIO_Pin_12
#define I2C_SCL_PORT GPIOB
#define I2C_SCL_CLK RCC_APB2Periph_GPIOB
#define I2C_SDA_PIN GPIO_Pin_13
#define I2C_SDA_PORT GPIOB
#define I2C_SDA_CLK RCC_APB2Periph_GPIOB
//IO操作函数
#define USERI2C_SCL_1 GPIO_SetBits(I2C_SCL_PORT, I2C_SCL_PIN)
#define USERI2C_SCL_0 GPIO_ResetBits(I2C_SCL_PORT, I2C_SCL_PIN)
#define USERI2C_SDA_1 GPIO_SetBits(I2C_SDA_PORT, I2C_SDA_PIN)
#define USERI2C_SDA_0 GPIO_ResetBits(I2C_SDA_PORT, I2C_SDA_PIN)
#define USERI2C_READ_SDA (GPIO_ReadInputDataBit(I2C_SDA_PORT, I2C_SDA_PIN))
#define I2C_DEVID 164//0XA4
//函数声明
void UserI2c_Start(void);
void UserI2c_Init(void);
unsigned char SensorWritenByte(unsigned char Devid, unsigned char *TXBuff, unsigned char SubAdd, unsigned char Size);
unsigned char SensorReadnByte(unsigned char Devid, unsigned char *RXBuff, unsigned char SubAdd, unsigned char Size);
#endif
3、tof.c文件
#include "tof.h"
#include "delay.h"
#include "usart.h"
//变量定义
unsigned char devid;
unsigned int i2cread_interval;
unsigned char dirt_send_flag;
unsigned char dirt_detection_flag;
unsigned short int length_val;
unsigned short int length_aveval;
/*******************************************************************************
* Function Name : UserI2c_Start
* Description : sck stable in H,sda falling edge
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void UserI2c_Start(void)
{
USERI2C_SDA_1;
delay_us(5);
USERI2C_SCL_1;
delay_us(5);
USERI2C_SDA_0; //START:when CLK is high,DATA change form high to low
delay_us(5);
USERI2C_SCL_0; //钳住I2C总线,准备发送或接收数据
delay_us(30); //加30uS延时
}
/*******************************************************************************
* Function Name : UserI2c_Stop
* Description : sck stable in H,sda rising edge
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void UserI2c_Stop(void)
{
USERI2C_SCL_0;
USERI2C_SDA_0;//STOP:when CLK is high DATA change form low to high
delay_us(5);
USERI2C_SCL_1;
delay_us(5);
USERI2C_SDA_1; //发送I2C总线结束信号
delay_us(5);
delay_us(30); //加30uS延时
}
/*******************************************************************************
* Function Name : UserI2c_Wait_Ack
* Description : the 9th clock pulse period wait ack
* Input : None
* Output : None
* Return : =0有ack
* : =1无ack
*******************************************************************************/
unsigned char UserI2c_Wait_Ack(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
unsigned short int ucErrTime = 0;
unsigned char RetValue;
//SDA设置为输入
GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //上拉输入
GPIO_Init(I2C_SDA_PORT, &GPIO_InitStructure);
USERI2C_SCL_0;
delay_us(5);
USERI2C_SCL_1;
ucErrTime = 10000;
while( ucErrTime-- > 0 )
{
if(USERI2C_READ_SDA )
{
RetValue = 0;
}
else
{
RetValue = 1;
break;
}
}
delay_us(1);
USERI2C_SCL_0;//时钟输出0
//SDA线输出
GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置IO的输出速度为50MHz,高低电平状态最高切换频率
GPIO_Init(I2C_SDA_PORT, &GPIO_InitStructure);
USERI2C_SDA_0;
delay_us(30); //加30uS延时
return RetValue;
}
/*******************************************************************************
* Function Name : useri2c_ack
* Description : the 9th clock pulse period, the receiver pulls sda low to
* : acknowledge the receipt of the eight data bits.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void useri2c_ack(void)
{
USERI2C_SCL_0;
USERI2C_SDA_0;
delay_us(5);
USERI2C_SCL_1;
delay_us(5);
USERI2C_SCL_0;
delay_us(30); //加30uS延时
}
/*******************************************************************************
* Function Name : useri2c_nack
* Description : no acknowledge the receipt of the eight data bits.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void useri2c_nack(void)
{
USERI2C_SCL_0;
USERI2C_SDA_1;
delay_us(5);
USERI2C_SCL_1;
delay_us(5);
USERI2C_SCL_0;
delay_us(30); //加30uS延时
}
/*******************************************************************************
* Function Name : UserI2c_Send_Byte
* Description : write one data to i2c bus
* Input : txd-data
* Output : None
* Return : None
*******************************************************************************/
void UserI2c_Send_Byte(unsigned char txd)
{
unsigned char t;
USERI2C_SCL_0;//拉低时钟开始数据传输
delay_us(5);
for(t = 0; t < 8; t++)
{
if((txd & 0x80) >> 0)
USERI2C_SDA_1;
else
USERI2C_SDA_0;
txd |