LSM6DS3TR-C姿态传感器的使用(一)--- 模拟IIC

最近做一个测量角度的项目,经过同事推荐发现这款强大的芯片LSM6DS3TR-C,它的功能很多,有加速计、陀螺仪、计步、单击/双击、方向检测、活动/不活动检测等,在此记录自己项目过程,预留备份,高手请绕行,勿喷,多谢!

该芯片的通信是II2或SPI,我是使用的IIC,分别使用了模拟IIC、HAL库IIC对其通信。

改芯片的IIC地址需要注意一下,资料上是根据SA0引脚的电平决定的,如下

LSM6DS3TR-C姿态传感器的使用(一)--- 模拟IIC_第1张图片 我原理图上的SA0是接地的,所以IIC写地址为0XD4,读地址为0XD5

模拟IIC代码如下:

void IIC_delay(void)
{
    __nop();__nop();__nop();
    __nop();__nop();__nop();
    __nop();__nop();__nop();
    __nop();__nop();__nop();
}

static IIC_State LSM6D3S_Start(void)
{
    SDA_OUT;
    SCL_H;
    SDA_H;
    IIC_delay();
    SDA_L;
    IIC_delay();
    return TRUE;
}

static IIC_State LSM6D3S_Wait_ACK()//第9个时钟信号,检测DIO电平
{
    SDA_IN;
    SCL_L;
    IIC_delay();
    SDA_H;
    IIC_delay();
    SCL_H;
    IIC_delay();
    while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11)==GPIO_PIN_SET);
    SCL_L;
    return TRUE;
}

//产生ACK应答
static void IIC_Ack(void)
{
    SCL_L;
    SDA_OUT;
    SDA_L;
    IIC_delay();
    SCL_H;
    IIC_delay();
    SCL_L;
}
//不产生ACK应答            
static void IIC_NAck(void)
{
    SCL_L;
    SDA_OUT;
    SDA_H;
    IIC_delay();
    SCL_H;
    IIC_delay();
    SCL_L;
}


static IIC_State LSM6D3S_Stop(void)//SLK高电平,DIO变高  为停止信号
{
    SDA_OUT;
    SDA_L;
    IIC_delay();
    SCL_H;
    IIC_delay();
    SDA_H;
    IIC_delay();
    return TRUE;
}

static void LSM6D3S_SendByte(uint8_t data)
{
    uint8_t i=0;
    SDA_OUT;
    for(i=0;i<8;i++)
    {
        SCL_L;
        IIC_delay();
        if(data&0x80)
        {
            SDA_H;
        }
        else
        {
            SDA_L;
        }
        data<<=1;
        IIC_delay();
        SCL_H;
        IIC_delay();
    }
    SCL_L;//这里一定要使SLK为低电平
}

         
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
static int8_t LSM6D3S_Read_Byte(unsigned char ack)
{
     int8_t i,receive=0;
    
    SDA_IN;//SDA设置为输入
    
  for(i=0;i<8;i++ )
    {
    SCL_L; 
    IIC_delay();
        SCL_H;
    receive<<=1;
        
        
    if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11))
        receive++; 
        
        IIC_delay(); 
   }
    
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
    }

测试时,先读出芯片ID,其寄存器地址为0X0F,其值为0X6A

uint8_t Read_LSM6DS3_WHO_AM_I(void)
{
    uint8_t rev;
    
    LSM6D3S_Start();
    LSM6D3S_SendByte(LSM6DS3_I2C_ADDRESS);
    LSM6D3S_Wait_ACK();
    LSM6D3S_SendByte(0X0F);
    LSM6D3S_Wait_ACK();
    
    LSM6D3S_Start();
    LSM6D3S_SendByte(LSM6DS3_I2C_ADDRESS+1);
    LSM6D3S_Wait_ACK();
    
    rev = LSM6D3S_Read_Byte(0);
    LSM6D3S_Stop();
    
    return rev;
}

主函数可以测试一下

void main(){

.......

HAL_Delay(20);
  if( LSM6DS3_WHO_AM_I != Read_LSM6DS3_WHO_AM_I())
        while(1);
    
    LSM6DS3_Init();
    HAL_Delay(10);    

while(1)

{

}

}

该工程只读取ID、温度、陀螺仪的数据,未对加速计寄存器配置及读取。

在读取操作的时候,也有一点插曲,读取温度的时候,温度只要小于25度,读取的数据显示成温度值就不对,排查原因发现,自己写的读取函数返回值为无符号的数据,所以导致 显示的温度小于25度就乱了(特别大),对于为什么是小于25度,具体查看官方例程如下

做此记录,希望以后不要犯类似错误

下篇记录:利用hal库 及 官网例程 编写LSM6DS3TR-C操作配置程序

整个工程下载连接如下:

(8条消息) LSM6DS3TR-C姿态传感器的使用---模拟IIC-单片机文档类资源-CSDN文库

你可能感兴趣的:(c语言)