[活动专区]

【AT-START-F407测评】+I2C接口实验读取传感器

[复制链接]
6891|74
手机看帖
扫描二维码
随时随地手机跟帖
WoodData|  楼主 | 2021-2-8 18:10 | 显示全部楼层 |阅读模式
#申请原创#      本次测试的是I2C外设,测试使用了ROHM的传感器,光照度传感器RPR-0521RS,气压传感器BM1383AGLV,地磁传感器BM1422AGMV。这几个传感器都是I2C接口,可以一起接I2C测试。
如图:使用arduino接口插在开发板。I2C使用的是I2C1,对应管脚为PB8:SCL,PB9:SDA。
4.jpg

PBB8,PB9对应的I2C功能引脚是重映射功能,需要重映射使能。
5.jpg

下面是重映射寄存器,为1就使能。未使能时I2C对应的PB6,PB7。
1.jpg

程序参考官方的BSP中的EEPROM例程的I2C程序,需要注意的是要使能IO复用重映射的时钟和I2C1的IO重映射使能。再就是I2C设备地址。
I2C初始化:
  GPIO_InitType GPIO_InitStructure;
  I2C_InitType  I2C_InitStructure;  
   
  /* GPIO Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB|RCC_APB2PERIPH_AFIO , ENABLE);
  /* I2C Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_I2C1, ENABLE);
   
  /* GPIO configuration */  
  /* Configure I2C pins: SCL */
  GPIO_InitStructure.GPIO_Pins = I2C_SCL_PIN;
  GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  GPIO_Init(I2C_SCL_Port, &GPIO_InitStructure);
  /* Configure I2C pins: SDA */
  GPIO_InitStructure.GPIO_Pins = I2C_SDA_PIN;
  GPIO_Init(I2C_SDA_Port, &GPIO_InitStructure);
  
  //重映射到PB8,PB9
  GPIO_PinsRemapConfig(GPIO_Remap_I2C1,ENABLE);


  /* I2C configuration */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2CDevice;
  I2C_InitStructure.I2C_FmDutyCycle = I2C_FmDutyCycle_2_1;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AddrMode = I2C_AddrMode_7bit;
  I2C_InitStructure.I2C_BitRate = 100000;        //100KHz
  
  /* I2C Peripheral Enable */
  I2C_Cmd(I2C1, ENABLE);
  
  /* Apply I2C configuration after enabling it */
  I2C_Init(I2C1, &I2C_InitStructure);


下面是实现读写函数,通过修改例程实现的。

I2C_StatusType I2C_Mem_Read(I2C_Type* I2Cx, uint16_t DevAddr, uint16_t DataAddr,  
                                                                uint8_t *pBuffer, uint16_t NumByte,  uint32_t Timeout)
{
  /* Wait until BUSY flag is reset */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BUSYF, SET, I2C_EVT_CHECK_NONE, I2C_TIMEOUT_BUSY_FLAG) != I2C_OK)
  {
    return I2C_ERROR_STEP_1;
  }

  /* Disable Pos */
  I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Current);
  /* Enable Acknowledge */
  I2C_AcknowledgeConfig(I2Cx, ENABLE);   
  /* Send START condition */
  I2C_GenerateSTART(I2Cx, ENABLE);
  /* Wait until SB flag is set */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_STARTF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  {
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);   
    return I2C_ERROR_STEP_2;
  }
  /* Send slave address for write */
  I2C_Send7bitAddress(I2Cx, (uint8_t)(DevAddr&0xff), I2C_Direction_Transmit);  
  /* Wait until ADDR flag is set */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_ADDRF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  {
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);   
    return I2C_ERROR_STEP_3;
  }  
  /* Clear ADDR flag */
  I2C_ClearADDRFlag(I2Cx);
  /* Wait until TDE flag is set */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  {
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);   
    return I2C_ERROR_STEP_4;
  }   
  /* Send Memory Address */
  I2C_SendData(I2Cx, (uint8_t)(DataAddr&0xff));  
  /* Wait until TDE flag is set */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
  {
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);   
    return I2C_ERROR_STEP_5;
  }   
  
  /* Send START condition */
  I2C_GenerateSTART(I2Cx, ENABLE);
  /* Wait until SB flag is set */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_STARTF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  {
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);   
    return I2C_ERROR_STEP_6;
  }   
  /* Send slave address for read */
  I2C_Send7bitAddress(I2Cx, (uint8_t)(DevAddr&0xff), I2C_Direction_Receive);
  
  /* Wait until ADDR flag is set */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_ADDRF, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
  {
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);   
    return I2C_ERROR_STEP_7;
  }
  
  if(NumByte == 1)
  {
    /* Disable Acknowledge */
    I2C_AcknowledgeConfig(I2Cx, DISABLE);
    /* Clear ADDR flag */
    I2C_ClearADDRFlag(I2Cx);
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);
  }
  else if(NumByte == 2)
  {
    /* Enable Pos */
    I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Next);   
    /* Clear ADDR flag */
    I2C_ClearADDRFlag(I2Cx);
    /* Disable Acknowledge */
    I2C_AcknowledgeConfig(I2Cx, DISABLE);
  }
  else
  {
    /* Enable Acknowledge */
    I2C_AcknowledgeConfig(I2Cx, ENABLE);
    /* Clear ADDR flag */
    I2C_ClearADDRFlag(I2Cx);
  }

  while(NumByte > 0)
  {
    if(NumByte <= 3)
    {
      /* One byte */
      if(NumByte == 1)
      {
        /* Wait until RXNE flag is set */
        if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_RDNE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
        {
          /* Send STOP Condition */
          I2C_GenerateSTOP(I2Cx, ENABLE);
          return I2C_ERROR_STEP_8;
        }
        /* Read data from DR */
        (*pBuffer++) = I2C_ReceiveData(I2Cx);
        NumByte--;
      }
      /* Two bytes */
      else if(NumByte == 2)
      {
        /* Wait until BTF flag is set */
        if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
        {
          /* Send STOP Condition */
          I2C_GenerateSTOP(I2Cx, ENABLE);         
          return I2C_ERROR_STEP_9;
        }
        /* Send STOP Condition */
        I2C_GenerateSTOP(I2Cx, ENABLE);
        /* Read data from DR */
        (*pBuffer++) = I2C_ReceiveData(I2Cx);
        NumByte--;        
        /* Read data from DR */
        (*pBuffer++) = I2C_ReceiveData(I2Cx);
        NumByte--;
      }
      /* 3 Last bytes */
      else
      {
        /* Wait until BTF flag is set */
        if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
        {
          /* Send STOP Condition */
          I2C_GenerateSTOP(I2Cx, ENABLE);         
          return I2C_ERROR_STEP_10;
        }
        /* Disable Acknowledge */
        I2C_AcknowledgeConfig(I2Cx, DISABLE);

        /* Read data from DR */
        (*pBuffer++) = I2C_ReceiveData(I2Cx);
        NumByte--;

        /* Wait until BTF flag is set */
        if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
        {
          /* Send STOP Condition */
          I2C_GenerateSTOP(I2Cx, ENABLE);         
          return I2C_ERROR_STEP_11;
        }

        /* Send STOP Condition */
        I2C_GenerateSTOP(I2Cx, ENABLE);

        /* Read data from DR */
        (*pBuffer++) = I2C_ReceiveData(I2Cx);
        NumByte--;
        
        /* Read data from DR */
        (*pBuffer++) = I2C_ReceiveData(I2Cx);
        NumByte--;
      }
    }
    else
    {
      /* Wait until RXNE flag is set */
      if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_RDNE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)   
      {
        /* Send STOP Condition */
        I2C_GenerateSTOP(I2Cx, ENABLE);        
        return I2C_ERROR_STEP_12;
      }
      /* Read data from DR */
      (*pBuffer++) = I2C_ReceiveData(I2Cx);
      NumByte--;
    }
  }
  return I2C_OK;
}


I2C_StatusType I2C_Mem_Write(I2C_Type* I2Cx, uint16_t DevAddr, uint16_t DataAddr,  
                                                                uint8_t *pBuffer, uint16_t NumByte,  uint32_t Timeout)
{
  /* Wait until BUSY flag is reset */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BUSYF, SET, I2C_EVT_CHECK_NONE, I2C_TIMEOUT_BUSY_FLAG) != I2C_OK)
  {
    return I2C_ERROR_STEP_1;
  }
  
  /* Disable Pos */
  I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Current);  
  /* Send START condition */
  I2C_GenerateSTART(I2Cx, ENABLE);
  /* Wait until SB flag is set */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_STARTF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  {
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);   
    return I2C_ERROR_STEP_2;
  }
  /* Send slave address for write */
  I2C_Send7bitAddress(I2Cx, (uint8_t)(DevAddr&0xff), I2C_Direction_Transmit);
  /* Wait until ADDR flag is set */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_ADDRF, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
  {
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);   
    return I2C_ERROR_STEP_3;
  }
  
  /* Clear ADDR flag */
  I2C_ClearADDRFlag(I2Cx);
  /* Wait until TDE flag is set */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
  {
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);   
    return I2C_ERROR_STEP_4;
  }  
  /* Send Memory Address */
  I2C_SendData(I2Cx, (uint8_t)(DataAddr&0xff));  
  /* Wait until TDE flag is set */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
  {
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);   
    return I2C_ERROR_STEP_5;
  }
  
  while(NumByte > 0)
  {
    /* Wait until TDE flag is set */
    if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
    {
      /* Send STOP Condition */
      I2C_GenerateSTOP(I2Cx, ENABLE);      
      return I2C_ERROR_STEP_6;
    }
    /* Write data to DR */
    I2C_SendData(I2Cx, (*pBuffer++));
    NumByte--;
  }

  /* Wait until BTF flag is set */
  if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
  {
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2Cx, ENABLE);   
    return I2C_ERROR_STEP_7;
  }  
  
  /* Send STOP Condition */
  I2C_GenerateSTOP(I2Cx, ENABLE);
  return I2C_OK;
}



通过逻辑分析仪捕的I2C协议时序。
2.jpg


6.jpg

通过串口输出,读取的3个传感器的数值。
3.jpg



代码
游客,如果您要查看本帖隐藏内容请回复







使用特权

评论回复
saintloong| | 2021-2-9 08:25 | 显示全部楼层
有源码的都是好同志

使用特权

评论回复
zhengfish| | 2021-2-9 08:40 | 显示全部楼层
kankan

使用特权

评论回复
jinglixixi| | 2021-2-9 17:16 | 显示全部楼层
学习学习

使用特权

评论回复
caizhiwei| | 2021-2-10 17:49 | 显示全部楼层
牛X,好家伙我也试试看!

使用特权

评论回复
cangbai| | 2021-2-14 20:59 | 显示全部楼层
学习学习

使用特权

评论回复
wziyi| | 2021-2-15 12:36 | 显示全部楼层
学习了

使用特权

评论回复
billy_2005| | 2021-3-1 14:25 | 显示全部楼层
感谢楼主分享

使用特权

评论回复
psh12| | 2021-8-2 16:04 | 显示全部楼层
谢谢分享

使用特权

评论回复
单片小菜| | 2021-8-2 17:03 | 显示全部楼层
看见源码了,一般人都没有看见源码的。没有办法的。

使用特权

评论回复
sobadman| | 2021-11-30 16:06 | 显示全部楼层
有源码的都是好同志

使用特权

评论回复
schow| | 2021-11-30 16:51 | 显示全部楼层
有源码的都是好同志

使用特权

评论回复
xiang752| | 2021-12-21 21:26 | 显示全部楼层
6666

使用特权

评论回复
dbayj| | 2021-12-28 22:56 | 显示全部楼层
谢谢分享

使用特权

评论回复
wifi99| | 2022-1-1 21:27 | 显示全部楼层
学习学习

使用特权

评论回复
betterchips| | 2022-1-10 14:59 | 显示全部楼层
有源码的都是好同志

使用特权

评论回复
usysm| | 2022-1-11 20:44 | 显示全部楼层
I2C接口的硬件接口吗   

使用特权

评论回复
typeof| | 2022-1-11 20:54 | 显示全部楼层
使用keil开发的吗   

使用特权

评论回复
yujielun| | 2022-1-11 20:54 | 显示全部楼层
AT-START-F407性能怎么样  

使用特权

评论回复
htmlme| | 2022-1-11 20:54 | 显示全部楼层
RPR-0521RS一般都是光敏电阻之类

使用特权

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

本版积分规则

115

主题

4363

帖子

25

粉丝