打印
[STM32F1]

大佬们我用TOFVL500红外测距一直有问题求大佬们看看

[复制链接]
1781|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
开开one|  楼主 | 2024-6-19 11:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 开开one 于 2024-6-19 11:35 编辑

大佬们我用TOFVL500红外测距一直有问题求大佬们看看
/* 定义I2C总线连接的GPIO端口, 用户只需要修改下面4行代码即可任意改变SCL和SDA的引脚 */
/* 定义I2C总线连接的GPIO端口, 用户只需要修改下面4行代码即可任意改变SCL和SDA的引脚 */

#define RCC_I2C_PORT         RCC_APB2Periph_GPIOB                /* GPIO端口时钟 */

#define PORT_I2C_SCL        GPIOB                        /* GPIO端口 */
#define PIN_I2C_SCL                GPIO_Pin_6                /* GPIO引脚 */

#define PORT_I2C_SDA        GPIOB                        /* GPIO端口 */
#define PIN_I2C_SDA                GPIO_Pin_7                /* GPIO引脚 */

#define I2C_SCL_PIN                GPIO_Pin_6                        /* 连接到SCL时钟线的GPIO */
#define I2C_SDA_PIN                GPIO_Pin_7                        /* 连接到SDA数据线的GPIO */

/* 定义读写SCL和SDA的宏 */
#define I2C_SCL_1()  PORT_I2C_SCL->BSRR = I2C_SCL_PIN                                /* SCL = 1 */
#define I2C_SCL_0()  PORT_I2C_SCL->BRR = I2C_SCL_PIN                                /* SCL = 0 */

#define I2C_SDA_1()  PORT_I2C_SDA->BSRR = I2C_SDA_PIN                                /* SDA = 1 */
#define I2C_SDA_0()  PORT_I2C_SDA->BRR = I2C_SDA_PIN                                /* SDA = 0 */

#define I2C_SDA_READ()  ((PORT_I2C_SDA->IDR & I2C_SDA_PIN) != 0)        /* 读SDA口线状态 */
#define I2C_SCL_READ()  ((PORT_I2C_SCL->IDR & I2C_SCL_PIN) != 0)        /* 读SCL口线状态 */

/*
*********************************************************************************************************
*        函 数 名: bsp_InitI2C
*        功能说明: 配置I2C总线的GPIO,采用模拟IO的方式实现
*        形    参:  无
*        返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitI2C(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_I2C_PORT, ENABLE);        /* 打开GPIO时钟 */

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;;        /* 推挽模式 */
       
        GPIO_InitStructure.GPIO_Pin = PIN_I2C_SCL;
        GPIO_Init(PORT_I2C_SCL, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = PIN_I2C_SDA;
        GPIO_Init(PORT_I2C_SDA, &GPIO_InitStructure);

        /* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */
        i2c_Stop();
}
/*
*********************************************************************************************************
*        函 数 名: i2c_Start
*        功能说明: CPU发起I2C总线启动信号
*        形    参:  无
*        返 回 值: 无
*********************************************************************************************************
*/
void i2c_Start(void)
{
        /* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */
        I2C_SDA_1();
        I2C_SCL_1();
        delay_us(VL2_SPEED*2);
        I2C_SDA_0();
        delay_us(VL2_SPEED*2);

        I2C_SCL_0();
delay_us(VL2_SPEED*2);
}

/*
*********************************************************************************************************
*        函 数 名: i2c_Start
*        功能说明: CPU发起I2C总线停止信号
*        形    参:  无
*        返 回 值: 无
*********************************************************************************************************
*/
void i2c_Stop(void)
{
        /* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */
        I2C_SDA_0();
        I2C_SCL_1();
        delay_us(VL2_SPEED*2);
        I2C_SDA_1();
        delay_us(VL2_SPEED*2);
}

/*
*********************************************************************************************************
*        函 数 名: i2c_SendByte
*        功能说明: CPU向I2C总线设备发送8bit数据
*        形    参:  _ucByte : 等待发送的字节
*        返 回 值: 无
*********************************************************************************************************
*/
void i2c_SendByte(uint8_t _ucByte)
{
        uint8_t i;

        /* 先发送字节的高位bit7 */
        for (i = 0; i < 8; i++)
        {
                if (_ucByte & 0x80)
                {
                        I2C_SDA_1();
                }
                else
                {
                        I2C_SDA_0();
                }
        delay_us(VL2_SPEED*2);
                I2C_SCL_1();
                delay_us(VL2_SPEED*2);
                I2C_SCL_0();
                if (i == 7)
                {
                         I2C_SDA_1(); // 释放总线
                }
                _ucByte <<= 1;        /* 左移一个bit */
                delay_us(VL2_SPEED*2);
        }
}

/*
*********************************************************************************************************
*        函 数 名: i2c_ReadByte
*        功能说明: CPU从I2C总线设备读取8bit数据
*        形    参:  无
*        返 回 值: 读到的数据
*********************************************************************************************************
*/
uint8_t i2c_ReadByte(void)
{
        uint8_t i;
        uint8_t value;

        /* 读到第1个bit为数据的bit7 */
        value = 0;
        for (i = 0; i < 8; i++)
        {
                value <<= 1;
                I2C_SCL_1();
                delay_us(VL2_SPEED*2);
                if (I2C_SDA_READ())
                {
                        value++;
                }
                I2C_SCL_0();
                delay_us(VL2_SPEED*2);
        }
        return value;

}

/*
*********************************************************************************************************
*        函 数 名: i2c_WaitAck
*        功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
*        形    参:  无
*        返 回 值: 返回0表示正确应答,1表示无器件响应
*********************************************************************************************************
*/
uint8_t i2c_WaitAck(void)
{
        uint8_t re;

        I2C_SDA_1();        /* CPU释放SDA总线 */
        delay_us(VL2_SPEED*2);
        I2C_SCL_1();        /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
        delay_us(VL2_SPEED*2);
        if (I2C_SDA_READ())        /* CPU读取SDA口线状态 */
        {
                re = 1;
        }
        else
        {
                re = 0;
        }
        I2C_SCL_0();
delay_us(VL2_SPEED*2);
        return re;
}

/*
*********************************************************************************************************
*        函 数 名: i2c_Ack
*        功能说明: CPU产生一个ACK信号
*        形    参:  无
*        返 回 值: 无
*********************************************************************************************************
*/
void i2c_Ack(void)
{
        I2C_SDA_0();        /* CPU驱动SDA = 0 */
delay_us(VL2_SPEED*2);
        I2C_SCL_1();        /* CPU产生1个时钟 */
delay_us(VL2_SPEED*2);
        I2C_SCL_0();
        delay_us(VL2_SPEED*2);
        I2C_SDA_1();        /* CPU释放SDA总线 */
}

/*
*********************************************************************************************************
*        函 数 名: i2c_NAck
*        功能说明: CPU产生1个NACK信号
*        形    参:  无
*        返 回 值: 无
*********************************************************************************************************
*/
void i2c_NAck(void)
{
        I2C_SDA_1();        /* CPU驱动SDA = 1 */
        delay_us(VL2_SPEED*2);
        I2C_SCL_1();        /* CPU产生1个时钟 */
delay_us(VL2_SPEED*2);
        I2C_SCL_0();
        delay_us(VL2_SPEED*2);
}

/*
*********************************************************************************************************
*        函 数 名: i2c_CheckDevice
*        功能说明: 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
*        形    参:  _Address:设备的I2C总线地址
*        返 回 值: 返回值 0 表示正确, 返回1表示未探测到
*********************************************************************************************************
*/
uint8_t i2c_CheckDevice(uint8_t _Address)
{
        uint8_t ucAck;

        if (I2C_SDA_READ() && I2C_SCL_READ())
        {
                i2c_Start();                /* 发送启动信号 */

                /* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */
                i2c_SendByte(_Address | I2C_WR);
                ucAck = i2c_WaitAck();        /* 检测设备的ACK应答 */

                i2c_Stop();                        /* 发送停止信号 */

                return ucAck;
        }
        return 1;        /* I2C总线异常 */
}




//IIC连续写
//addr:器件地址
//reg:寄存器地址
//len:写入长度
//buf:数据区
//返回值:0,正常
//    其他,错误代码
u8 VL53L0X_Write_Len(u8 addr,u8 reg,u8 *buf,u8 len )
{
        u8 i;
    i2c_Start();
        i2c_SendByte((addr<<1)|0);//发送器件地址+写命令       
        if(i2c_WaitAck())        //等待应答
        {
                i2c_Stop();                 
                return 1;               
        }
    i2c_SendByte(reg);        //写寄存器地址
    i2c_WaitAck();                //等待应答
        for(i=0;i<len;i++)
        {
                i2c_SendByte(buf);        //发送数据
                if(i2c_WaitAck())                //等待ACK
                {
                        i2c_Stop();         
                        return 1;                 
                }               
        }   
    i2c_Stop();         
        return 0;       
}
//IIC连续读
//addr:器件地址
//reg:要读取的寄存器地址
//len:要读取的长度
//buf:读取到的数据存储区
//返回值:0,正常
//    其他,错误代码
u8 VL53L0X_Read_Len(u8 addr,u8 reg,u8 *buf,u8 len)
{
        i2c_Start();
        i2c_SendByte((addr<<1)|0);//发送器件地址+写命令       
        if(i2c_WaitAck())        //等待应答
        {
                i2c_Stop();                 
                return 1;               
        }
    i2c_SendByte(reg);        //写寄存器地址
    i2c_WaitAck();                //等待应答
    i2c_Start();
        i2c_SendByte((addr<<1)|1);//发送器件地址+读命令       
    i2c_WaitAck();                //等待应答
               
while(len)
        {
                if(len==1)
                {
                        *buf=i2c_ReadByte();//读数据,发送nACK
                        i2c_NAck();
                }
                else
                {
                        *buf=i2c_ReadByte();                //读数据,发送ACK  
                        i2c_Ack();
                }
                len--;
                buf++;
        }   
    i2c_Stop();        //产生一个停止条件
        return 0;       
}

/***********************************************************
* 此文档需要客户移植完成
* 1、IIC读写函数
* 2、实现延时函数:void VI530x_Delay_Ms(uint16_t nMs)
* 3、如果使用硬件中断,则在触发下降沿中断中调用:void VI530x_GPIO_Interrupt_Handle(void)
* 4、XSHUT高低电位的控制:void VI530x_XSHUT_Pin_Status(uint8_t state)
* ********************************************************/

//Xshut引脚配置
/* Start user code for adding. */
void XSHUT_Init(void){
        GPIO_InitTypeDef  GPIO_InitStructure;        
    RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );        //使能GPIOA时钟(RCC_APB2Periph_GPIOB);      
    GPIO_InitStructure.GPIO_Pin = XSHUT_PIN; //选择端口号(0~15或all)                        
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式      
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)   
        GPIO_Init(XSHUT_PORT, &GPIO_InitStructure);                       
}


void AVDD_EN_Init(void)
{
                GPIO_InitTypeDef  GPIO_InitStructure;        
    RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );        //使能GPIOA时钟(RCC_APB2Periph_GPIOB);      
    GPIO_InitStructure.GPIO_Pin = AVDD_EN_PIN; //选择端口号(0~15或all)                        
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式      
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)   
        GPIO_Init(AVDD_EN_PORT, &GPIO_InitStructure);                       
}
/* End user code.  */

/**
* @brief         VI530X I2C 1Byte 读
* @param         [uint8_t] addr:读地址
* @param         [uint8_t] *value:读到的值
* @return         [uint8_t]        ret:0-操作成功(I2C读写无异常);other-异常(I2C读写有异常)
*/
uint8_t VI530x_IIC_Read_One_Byte(uint8_t addr, uint8_t *value)
{               
       
        uint8_t ret = 0;
       
        ret = VL53L0X_Read_Len(VI530x_IIC_Dev_Addr_Now,addr,value,1);

        if(ret != 0)
                ret =  VI530x_IIC_ERROR;
        return ret;

}
/**
* @brief         VI530X I2C x Byte 读
* @param         [uint8_t] addr:读地址
* @param         [uint8_t] *value:读到的值
* @param         [uint16_t] tlen:读取的长度
* @return         [uint8_t]        ret:0-操作成功(I2C读写无异常);other-异常(I2C读写有异常)
*/
uint8_t VI530x_IIC_Read_X_Bytes(uint8_t addr, uint8_t *value, uint16_t tlen)
{
        uint8_t ret = 0;
       
                ret = VL53L0X_Read_Len(VI530x_IIC_Dev_Addr_Now,addr,value,tlen);
       
        if(ret != 0)
                ret =  VI530x_IIC_ERROR;
        return ret;

}

/**
* @brief         VI530X I2C 1 Byte 写
* @param         [uint8_t] addr:写的地址
* @param         [uint8_t] value:写入的值
* @return         [uint8_t]        ret:0-操作成功(I2C读写无异常);other-异常(I2C读写有异常)
*/
uint8_t VI530x_IIC_Write_One_Byte(uint8_t addr, uint8_t value)
{       
        uint8_t ret = 0;

        //ret = IIC_Write_X_Bytes(addr,&value,1);
        ret=         VL53L0X_Write_Len(VI530x_IIC_Dev_Addr_Now,addr,&value,1);
       
        if(ret != 0)
                ret =  VI530x_IIC_ERROR;
        return ret;

}

/**
* @brief         VI530X I2C 1 Byte 写
* @param         [uint8_t] addr:写的地址
* @param         [uint8_t] *pValue:写入的值
* @param         [uint16_t] tlen:写入的长度
* @return         [uint8_t]        ret:0-操作成功(I2C读写无异常);other-异常(I2C读写有异常)
*/
uint8_t VI530x_IIC_Write_X_Bytes(uint8_t addr, uint8_t *pValue, uint16_t tlen)
{       
        uint8_t ret = 0;
       
        ret=         VL53L0X_Write_Len(VI530x_IIC_Dev_Addr_Now,addr, pValue,tlen);


        if(ret != 0)
                ret =  VI530x_IIC_ERROR;
        return ret;

}

/**
* @brief         VI530X 延时 单位:ms
* @param         [none]
* @return         [none]
*/
void VI530x_Delay_Ms(uint16_t nMs)
{
        /* Start user code for adding. */

        /* End user code.  */
}

//添加于输入中断函数内调用
/**
* @brief         VI530X 延时 硬件中断处理
* @param         [none]
* @return         [none]
*/
void VI530x_GPIO_Interrupt_Handle(void)
{
        if(VI530x_Cali_Data.VI530x_Interrupt_Mode_Status)
        {
                VI530x_GPIO_Interrupt_status = 1;
        }
}

/**
* @brief         VI530X XSHUS引脚控制
* @param         [uint8_t] state:0-拉低,1-拉高
* @return         [none]
*/
void VI530x_XSHUT_Enable(uint8_t state)
{
        if(state)
        {
                GPIO_SetBits(XSHUT_PORT,XSHUT_PIN);
        }
        else
        {
                GPIO_ResetBits(XSHUT_PORT,XSHUT_PIN);
        }
}

int main (void){//主程序
        uint8_t ret = 0;
         uint8_t status = 0;
        RCC_Configuration();
        LED_Init();//LED初始化
        KEY_Init();//按键初始化
        XSHUT_Init();
        bsp_InitI2C();
        AVDD_EN_Init();
       
        BUZZER_Init();//蜂鸣器初始化
        USART1_Init(115200); //串口初始化,参数中写波特率
        USART1_RX_STA=0xC000; //初始值设为有回车的状态,即显示一次欢迎词
//        VI530x_Cali_Data.VI530x_Interrupt_Mode_Status = 0x00;                //软件中断
        GPIO_SetBits(AVDD_EN_PORT,AVDD_EN_PIN);
        ret |= VI530x_Chip_Init();
        ret |= VI530x_Download_Firmware((uint8_t *)VI5301_M40_firmware_buff, FirmwareSize());
       
        ret |= VI530x_Set_Californiation_Data(VI530x_Cali_Data.VI530x_Cali_Offset);
        //7、其它配置
        //开启温度校准:0x00-关,0x01-开
        ret |= VI530x_Set_Sys_Temperature_Enable(0x01);
//        ret |= VI530x_Set_Integralcounts_Frame(30,196608); //帧率,积分次数
        //8、开启测距
        ret |= VI530x_Start_Continue_Ranging_Cmd();        //连续模式
        //ret = VI530x_Start_Single_Ranging_Cmd();        //单次模式
       
               

        while(1){
               
        if(ret)
                {
                        printf("VI530x Configer Error!\r\n");
                }
                else
                {
                        printf("VI530x Configer Ok!\r\n");
                }
                ret = VI530x_Get_Measure_Data(&result);
               
                printf("tof = %4d, confidece = %3d, peak = %4d, noise = %4d, xtalk_count = %4d\r\n", result.correction_tof,result.confidence,result.peak,result.noise,result.xtalk_count);
        delay_ms(2000);
               
        }
       
}




使用特权

评论回复
沙发
小小蚂蚁举千斤| | 2024-6-23 17:33 | 只看该作者
这个应该是官方给出的标准的一些案例程序,移植是不是有问题?

使用特权

评论回复
板凳
elephant00| | 2024-6-24 10:05 | 只看该作者
尝试关闭并重新启动TOFVL500红外测距仪,看是否能解决问题。

使用特权

评论回复
地板
两只袜子| | 2024-6-24 10:06 | 只看该作者
TOFVL500有没有被摔过

使用特权

评论回复
5
jcky001| | 2024-6-24 12:00 | 只看该作者
电池老化问题?

使用特权

评论回复
6
cr315| | 2024-6-24 13:00 | 只看该作者
红外测距仪的测量过程依赖于激光发射器,如果激光发射器失灵,将直接影响测量结果的准确性。

使用特权

评论回复
7
AdaMaYun| | 2024-6-24 22:34 | 只看该作者
还是结合发生问题的地方进行排查

使用特权

评论回复
8
喂什么玩意| | 2024-6-30 14:43 | 只看该作者
如VL53L0X_Write_Len和VL53L0X_Read_Len,需要确保地址和数据传输的正确性。

使用特权

评论回复
9
喂什么玩意| | 2024-6-30 14:43 | 只看该作者
在代码中加入调试输出语句,打印每个步骤的执行情况,以便定位问题所在。

使用特权

评论回复
10
ewyu| | 2024-7-23 12:10 | 只看该作者
啥问题啊?是读不出数据吗、

使用特权

评论回复
11
suiziq| | 2024-7-23 13:15 | 只看该作者
你用官方的例程试试呢

使用特权

评论回复
12
hhdhy| | 2024-7-23 14:23 | 只看该作者
其实可以使用cubemx配置底层函数,这样就能减少一些问题的发生

使用特权

评论回复
13
tiakon| | 2024-7-23 15:36 | 只看该作者
测距不都是SPI或者I2C接口吗,你配置好应该就可以了吧

使用特权

评论回复
14
wamed| | 2024-7-23 16:45 | 只看该作者
用逻辑分析仪抓一下波形看看

使用特权

评论回复
15
gongqijuns| | 2024-7-23 19:00 | 只看该作者
怎么个问题,你描述一下呗?

使用特权

评论回复
16
canfeil| | 2024-7-24 08:00 | 只看该作者
我看程序好像也没啥大问题吧,就是配置i2C的啊

使用特权

评论回复
17
清芯芯清| | 2024-7-24 09:01 | 只看该作者
最好是找个关于你这个红外测距的例程,然后跑一下看看

使用特权

评论回复
18
gra22ce| | 2024-7-24 10:12 | 只看该作者
是不是硬件故障导致的啊?

使用特权

评论回复
19
呐咯密密| | 2024-7-24 11:37 | 只看该作者
所以是啥问题,不能只说有问题

使用特权

评论回复
20
twinkhahale| | 2024-7-24 12:00 | 只看该作者
这没法判断,用仿真调试的方式看看,怎么做吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

4

帖子

0

粉丝