请选择 进入手机版 | 继续访问电脑版

硬汉嵌入式论坛

 找回密码
 立即注册
查看: 632|回复: 3
收起左侧

i2c硬件配置读取lsm6dsow传感器

[复制链接]

37

主题

149

回帖

260

积分

高级会员

积分
260
发表于 2022-5-23 16:37:05 | 显示全部楼层 |阅读模式
关于i2c硬件配置读取lsm6dsow传感器:
i2c3_scl :pg7
i2c3_sda:pg8
int I2CInit(int Index)
{
   if (Index == I2C3_ID){
        /*##-1- Configure the I2C peripheral ######################################*/
        I2cHandle[Index].Instance             = I2C3;
        I2cHandle[Index].Init.Timing          = 0x307075B1;
        I2cHandle[Index].Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;   
        I2cHandle[Index].Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
        I2cHandle[Index].Init.OwnAddress1     = 0;
        I2cHandle[Index].Init.OwnAddress2     = 0;
        I2cHandle[Index].Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
        I2cHandle[Index].Init.NoStretchMode   = I2C_NOSTRETCH_DISABLE;
        if(HAL_I2C_Init(&I2cHandle[Index]) != HAL_OK){        
            printf("I2C3 init error \r\n");
            while(1);
        }        
        /* Enable the Analog I2C Filter使能模拟i2c过滤器 */
        HAL_I2CEx_ConfigAnalogFilter(&I2cHandle[Index],I2C_ANALOGFILTER_ENABLE);
    }
    return 0;

}
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{
    GPIO_InitTypeDef  GPIO_InitStruct;
    RCC_PeriphCLKInitTypeDef  RCC_PeriphCLKInitStruct;

    static DMA_HandleTypeDef hdma_tx;
    static DMA_HandleTypeDef hdma_rx;

    if (hi2c->Instance == I2C3){   
      /*##-1- Configure the I2C clock source. The clock is derived from the SYSCLK #*/
      RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C3;
      RCC_PeriphCLKInitStruct.I2c3ClockSelection = RCC_I2C3CLKSOURCE_SYSCLK;   
      HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
        
      /*##-2- Enable peripherals and GPIO Clocks #################################*/
      /* Enable GPIO TX/RX clock */
      __HAL_RCC_GPIOG_CLK_ENABLE();
      /* Enable I2Cx clock */
      __HAL_RCC_I2C3_CLK_ENABLE();
        
      /* Enable DMAx clock */
      __HAL_RCC_DMA1_CLK_ENABLE();
      __HAL_RCC_DMAMUX1_CLK_ENABLE();

    //pg8是sda、pg7是sck
      /*##-3- Configure peripheral GPIO ##########################################*/  
      /* I2C TX GPIO pin configuration  发送gpio芯片配置*/
      GPIO_InitStruct.Pin              = GPIO_PIN_7;
      GPIO_InitStruct.Mode             = GPIO_MODE_OUTPUT_OD;//开漏
      GPIO_InitStruct.Pull             = GPIO_NOPULL;
      GPIO_InitStruct.Speed            = GPIO_SPEED_FREQ_VERY_HIGH;//高速
      GPIO_InitStruct.Alternate        = GPIO_AF4_I2C3; //引脚复用
      HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

      /* I2C RX GPIO pin configuration  读gpio芯片配置*/
      GPIO_InitStruct.Pin              = GPIO_PIN_8;
      GPIO_InitStruct.Alternate        = GPIO_AF4_I2C3;
      HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

      /*##-4- Configure the DMA Channels #########################################*/
      /* Configure the DMA handler for Transmission process */
      hdma_tx.Instance                 = DMA1_Channel2;//通道2发送
      hdma_tx.Init.Request             = DMA_REQUEST_I2C3_TX;//i2c3发射
      hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;//内存到外设模式
      
      hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;//外设地址
      hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;//内存地址递增
      
      hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;//外设数据以字节对齐
      hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;//内存数据以字节对齐
      
      hdma_tx.Init.Mode                = DMA_NORMAL;//正常模式传输
      hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;//低优先级
      if(HAL_DMA_Init(&hdma_tx)!= HAL_OK){
            printf("hdma_tx error\r\n");
      }
      
      /* Associate the initialized DMA handle to the the I2C handle */
      __HAL_LINKDMA(hi2c, hdmatx, hdma_tx);

      /* Configure the DMA handler for Transmission process */
      hdma_rx.Instance                 = DMA1_Channel3;//接收
      hdma_rx.Init.Request             = DMA_REQUEST_I2C3_RX;
      hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;//外设到内存
      hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
      hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
      hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
      hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
      hdma_rx.Init.Mode                = DMA_NORMAL;
      hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;
      
      if(HAL_DMA_Init(&hdma_rx)!= HAL_OK){
            printf("hdma_rx error\r\n");
      }

      /* Associate the initialized DMA handle to the the I2C handle */
      __HAL_LINKDMA(hi2c, hdmarx, hdma_rx);

      /*##-5- Configure the NVIC for DMA #########################################*/
      /* NVIC configuration for DMA transfer complete interrupt (I2Cx_TX) */
      HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
      HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
      
      /* NVIC configuration for DMA transfer complete interrupt (I2Cx_RX) */
      HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);   
      HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);

      /*##-6- Configure the NVIC for I2C #########################################*/
      /* NVIC for I2Cx */
      HAL_NVIC_SetPriority(I2C3_ER_IRQn, 0, 1);
      HAL_NVIC_EnableIRQ(I2C3_ER_IRQn);
      
      HAL_NVIC_SetPriority(I2C3_EV_IRQn, 0, 2);
      HAL_NVIC_EnableIRQ(I2C3_EV_IRQn);
  }
}

void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
{
    static DMA_HandleTypeDef hdma_tx;
    static DMA_HandleTypeDef hdma_rx;

    if (hi2c->Instance == I2C3)
    {
        /* I2C3:SCL: PG7   SDA: PG8 */
        /*##-1- Reset peripherals ##################################################*/
        __HAL_RCC_I2C3_FORCE_RESET();
        __HAL_RCC_I2C3_RELEASE_RESET();

        /*##-2- Disable peripherals and GPIO Clocks #################################*/
        /* Configure I2C Tx as alternate function  */
        HAL_GPIO_DeInit(GPIOG, GPIO_PIN_7);
        /* Configure I2C Rx as alternate function  */
        HAL_GPIO_DeInit(GPIOG, GPIO_PIN_8);

        /*##-3- Disable the DMA Channels ###########################################*/
        /* De-Initialize the DMA Channel associated to transmission process */
        HAL_DMA_DeInit(&hdma_tx);
        /* De-Initialize the DMA Channel associated to reception process */
        HAL_DMA_DeInit(&hdma_rx);

        /*##-4- Disable the NVIC for DMA ###########################################*/
        HAL_NVIC_DisableIRQ(DMA1_Channel2_IRQn);
        HAL_NVIC_DisableIRQ(DMA1_Channel3_IRQn);

        /*##-5- Disable the NVIC for I2C ###########################################*/
        HAL_NVIC_DisableIRQ(I2C3_ER_IRQn);
        HAL_NVIC_DisableIRQ(I2C3_EV_IRQn);
    }

}

void I2C_Read(int Index,unsigned char DeviceAddress,int AddressStart,unsigned char *pReadBuf,int ReadNum)
{   
    /* LPS33K_I2C_ADD   0x5D --->0xBA      LPS33K_ID            0xB1  */
    /* NST118_I2C_ADD   0x48 --->0x90        */
    /*lsdow_i2c_add   0xD5 */

    if(Index == I2C3_ID){
         uint8_t  ret = HAL_I2C_Mem_Read_DMA(&I2cHandle[Index],(uint16_t)((DeviceAddress << 1)),
        AddressStart, I2C_MEMADD_SIZE_8BIT, pReadBuf, ReadNum);
        if(ret == 0)
            printf("hal ok\r\n");
        else if(ret == 1){
            printf("hal error\r\n");
        }
        else if(ret == 2){
            printf("hal busy\r\n");
        }
        else
            printf("hal timeout\r\n");
        
        /* Wait for the end of the transfer */
        while (HAL_I2C_GetState(&I2cHandle[Index]) != HAL_I2C_STATE_READY){
        };
    }
}
void I2C_Write(int Index,unsigned char DeviceAddress,int AddressStart,unsigned char *pWriteBuf,int WriteNum)
{
    /* Write EEPROM_PAGESIZE */
    if(HAL_I2C_Mem_Write_DMA(&I2cHandle[Index] , (uint16_t)(DeviceAddress<<1), AddressStart,
    I2C_MEMADD_SIZE_8BIT, (unsigned char*)pWriteBuf, WriteNum)!= HAL_OK)
    {
        /* Writing process Error */
        // Error_Handler();
        printf("HAL_I2C_Mem_Write_DMA error ! \r\n");
    }
    /* Wait for the end of the transfer */
    /*  Before starting a new communication transfer, you need to check the current
    state of the peripheral; if it抯 busy you need to wait for the end of current
    transfer before starting a new one.
    For simplicity reasons, this example is just waiting till the end of the
    transfer, but application may perform other tasks while transfer operation
    is ongoing. */
    while (HAL_I2C_GetState(&I2cHandle[Index]) != HAL_I2C_STATE_READY){
    } ;
}
static int32_t platform_write1(void *handle, uint8_t reg,uint8_t *bufp, uint16_t len)
{
    I2C_Write(I2C3_ID,LSM6DSO_I2C_ADD_L,reg,(uint8_t*)bufp,len);
    return 0;
}

//i2c3读寄存器操作
static int32_t platform_read1(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
    I2C_Read(I2C3_ID,LSM6DSO_I2C_ADD_L,reg,(uint8_t*)bufp,len);
    printf("reg = 0x%x\r\n",reg);
    return 0;
}

static void platform_delay(uint32_t ms)
{
    HAL_Delay(ms);
}

void LSM6DSO_Init(void)
{
    uint8_t whoamI,rst;   
    lsm6dso_dev_ctx.write_reg1 = platform_write1;
    lsm6dso_dev_ctx.read_reg1 = platform_read1;
    lsm6dso_dev_ctx.handle = NULL;
   
    platform_delay(BOOT_TIME);
   
    lsm6dso_device_id_get(&lsm6dso_dev_ctx, &whoamI);
    printf("whoamI = 0x%x\r\n",whoamI);
}


38a30ee65ce647ad3ab120670428d28.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
105942
QQ
发表于 2022-5-24 01:57:12 | 显示全部楼层
楼主的是什么问题,程序分享还是什么。
回复

使用道具 举报

37

主题

149

回帖

260

积分

高级会员

积分
260
 楼主| 发表于 2022-5-26 13:55:47 | 显示全部楼层
eric2013 发表于 2022-5-24 01:57
楼主的是什么问题,程序分享还是什么。

都显示了图片内容了……,咨询问题
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
105942
QQ
发表于 2022-5-27 01:05:38 | 显示全部楼层
gck 发表于 2022-5-26 13:55
都显示了图片内容了……,咨询问题

这个看不出来有啥问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-3-29 14:19 , Processed in 0.190016 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表