OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2200|回复: 1

stm32f207 I2C AT24C256通讯问题

[复制链接]

26

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
235
金钱
235
注册时间
2014-12-18
在线时间
13 小时
发表于 2018-3-16 16:18:04 | 显示全部楼层 |阅读模式
用STM32F207 I2C读写AT24C256,读取后要延时一段时间才可以得到正确的值,不知各位遇到过没有
读写函数用的从ST网上下载包中的EPPROM 例程

  sEE_ReadBuffer((uint8_t *)&time, r_addr, (uint16_t*)&read_num);
在此处加延时,才可以输出time值为0xFF,否则time的值为0
printf("%d",time);


uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
{  
  /* Set the pointer to the Number of data to be read. This pointer will be used
      by the DMA Transfer Completer interrupt Handler in order to reset the
      variable to 0. User should check on this variable in order to know if the
      DMA transfer has been complete or not. */
  sEEDataReadPointer = NumByteToRead;
  
  /*!< While the bus is busy */
  sEETimeout = sEE_LONG_TIMEOUT;
  while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send START condition */
  I2C_GenerateSTART(sEE_I2C, ENABLE);
  
  /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send EEPROM address for write */
  I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter);
  /*!< Test on EV6 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
   
if(sEEAddress==AT24C256_ADDRESS)
{
  /*!< Send the EEPROM's internal address to write to : MSB of the address first */
  I2C_SendData(sEE_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));
  /*!< Test on EV8 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;  
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING))
  {
   if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }  
  
  /*!< Send the EEPROM's internal address to write to : LSB of the address */
  I2C_SendData(sEE_I2C, (uint8_t)(ReadAddr & 0x00FF));
}
else if(sEEAddress==MCP23017_ADDRESS)
{
  /*!< Send the EEPROM's internal address to write to : only one byte Address */
  I2C_SendData(sEE_I2C, ReadAddr);
}

//#ifdef sEE_M24C08
//  /*!< Send the EEPROM's internal address to read from: Only one byte address */
//  I2C_SendData(sEE_I2C, ReadAddr);  
//#elif defined (sEE_M24C02)  
//  /*!< Send the EEPROM's internal address to read from: Only one byte address */
//  I2C_SendData(sEE_I2C, ReadAddr);  
//#elif defined (sEE_M24C64_32)
//  /*!< Send the EEPROM's internal address to read from: MSB of the address first */
//  I2C_SendData(sEE_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));   
//  /*!< Test on EV8 and clear it */
//  sEETimeout = sEE_FLAG_TIMEOUT;
//  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING))
//  {
//    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
//  }
//  /*!< Send the EEPROM's internal address to read from: LSB of the address */
//  I2C_SendData(sEE_I2C, (uint8_t)(ReadAddr & 0x00FF));   
//  
//#endif /*!< sEE_M24C08 */
  /*!< Test on EV8 and clear it */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BTF) == RESET)
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send STRAT condition a second time */  
  I2C_GenerateSTART(sEE_I2C, ENABLE);
  
  /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
  sEETimeout = sEE_FLAG_TIMEOUT;
  while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  {
    if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
  }
  
  /*!< Send EEPROM address for read */
  I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Receiver);  
  
  /* If number of data to be read is 1, then DMA couldn't be used */
  /* One Byte Master Reception procedure (POLLING) ---------------------------*/
  if ((uint16_t)(*NumByteToRead) < 2)
  {
    /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_ADDR) == RESET)
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }     
   
    /*!< Disable Acknowledgment */
    I2C_AcknowledgeConfig(sEE_I2C, DISABLE);   
   
    /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
    (void)sEE_I2C->SR2;
   
    /*!< Send STOP Condition */
    I2C_GenerateSTOP(sEE_I2C, ENABLE);
   
    /* Wait for the byte to be received */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_RXNE) == RESET)
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }
   
    /*!< Read the byte received from the EEPROM */
    *pBuffer = I2C_ReceiveData(sEE_I2C);
   
    /*!< Decrement the read bytes counter */
    (uint16_t)(*NumByteToRead)--;        
   
    /* Wait to make sure that STOP control bit has been cleared */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while(sEE_I2C->CR1 & I2C_CR1_STOP)
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }  
   
    /*!< Re-Enable Acknowledgment to be ready for another reception */
    I2C_AcknowledgeConfig(sEE_I2C, ENABLE);   
  }
  else/* More than one Byte Master Reception procedure (DMA) -----------------*/
  {
    /*!< Test on EV6 and clear it */
    sEETimeout = sEE_FLAG_TIMEOUT;
    while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
    {
      if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
    }  
   
    /* Configure the DMA Rx Channel with the buffer address and the buffer size */
    sEE_LowLevel_DMAConfig((uint32_t)pBuffer, (uint16_t)(*NumByteToRead), sEE_DIRECTION_RX);
   
    /* Inform the DMA that the next End Of Transfer Signal will be the last one */
    I2C_DMALastTransferCmd(sEE_I2C, ENABLE);
   
    /* Enable the DMA Rx Stream */
    DMA_Cmd(sEE_I2C_DMA_STREAM_RX, ENABLE);   
  }
  /* If all operations OK, return sEE_OK (0) */
  return sEE_OK;
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

26

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
235
金钱
235
注册时间
2014-12-18
在线时间
13 小时
 楼主| 发表于 2018-3-18 09:37:26 | 显示全部楼层
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 04:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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