微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 使用I2C通讯EEPROM,无法正确读取数据,请教各位大神。

使用I2C通讯EEPROM,无法正确读取数据,请教各位大神。

时间:10-02 整理:3721RD 点击:
这个是使用STM8数据库的I2C通讯,我遇到的问题是,在跟EEPROM通讯的时候,第一次写入数据,一个一个读取的话,能知道写入EEPROM的值是没有错的,但是在连续读取数据的时候,就会出现,上电第一次读取数据串的时候,是全部读取正确,然后再读取一遍数据串的时候,只有第一个读取的数据是正确的,后面的数据会全部变成FF FF 这是怎么回事?
#define  OWN_ADDRESS    0x00FE
#define  EEPROM_ADDRESS 0xA0  
void IIC_Init(void)
{
   I2C_DeInit();
   I2C_Init(100, OWN_ADDRESS, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 1);
   I2C_Cmd(ENABLE);
}
void EEPROM_WriteOnePage(u8 address, u8 Number, u8 *DataBuffer)
{
   while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)); //等待空闲
   I2C_GenerateSTART(ENABLE);
   while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));//测试EV5,检测从器件返回一个应答值
   I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);//设置I2C从器件地址,I2C主设备写模式
   while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//测试EV6 ,检测从器件返回一个应答信号
   I2C_SendData((u8)(address));
   while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));// 测试EV8 ,检测从器件返回一个应答信号
   while(Number--)//不断往从设备写数据
    {
      I2C_SendData(*DataBuffer);
      DataBuffer++; //指针指向下一个地址
      while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));//测试EV6 ,检测从器件返回一个应答信号
      I2C_AcknowledgeConfig(I2C_ACK_CURR);
     }
   I2C_GenerateSTOP(ENABLE); //发结束位
   DataBuffer=0;
}
void EEPROM_ReadOnePageData(u8 *pBuffer, u8 address, u8 Number)
{
   while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)); // 等待空闲
   I2C_GenerateSTART(ENABLE); //发起始位
   while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));//测试EV5 ,检测从器件返回一个应答信号
   I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);//设置I2C 从器件地址,I2C 主设备为写模式
   while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//测试EV6 ,检测从器件返回一个应答信号
   I2C_SendData(address);
   while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));// 测试EV8 ,检测从器件返回一个应答信号
   I2C_GenerateSTART(ENABLE);// 发起始位
   while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));// 测试EV5 ,检测从器件返回一个应答信号
   I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_RX);//设置I2C 从器件地址,I2C 主设备为读模式
   while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));// 测试EV6 ,检测从器件返回一个应答信号
   while(Number)//不断在从从设备读取数据
    {
     if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))//测试EV6
      {
        I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
        *pBuffer = I2C_ReceiveData();//从EEPROM 读取一个字节
        pBuffer++;//指针指向下个存放字节的地址
        if(Number == 1)//读到最后一个字节
         {
           I2C_AcknowledgeConfig(I2C_ACK_NONE);//不需要应答
          
           I2C_GenerateSTOP(ENABLE);// 发结束位
           pBuffer=0;
         }
        else
         {
         I2C_AcknowledgeConfig(I2C_ACK_CURR);//不是最后一个字节向从设备发送应答信号
         }
         Number--;
      }
    }
}
u8 EEPROM_ReadOneData(u8 address)
{
   u8 EEPRom_Read;
   while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)); // 等待空闲
   I2C_GenerateSTART(ENABLE); //发起始位
   while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));//测试EV5 ,检测从器件返回一个应答信号
   I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);//设置I2C 从器件地址,I2C 主设备为写模式
   while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//测试EV6 ,检测从器件返回一个应答信号
   I2C_SendData(address);
   while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));// 测试EV8 ,检测从器件返回一个应答信号
   I2C_GenerateSTART(ENABLE);// 发起始位
   while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));// 测试EV5 ,检测从器件返回一个应答信号
   I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_RX);//设置I2C 从器件地址,I2C 主设备为读模式
   while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));// 测试EV6 ,检测从器件返回一个应答信号
   EEPRom_Read=I2C_ReceiveData();//从EEPROM 读取一个字节
   I2C_AcknowledgeConfig(I2C_ACK_NONE);//不需要应答
   I2C_GenerateSTOP(ENABLE);// 发结束位
   return EEPRom_Read;
}

大家都说STM32的IIC有点bug,所以很少人用其自带的IIC,一般都是用IO口模拟IIC,模拟很简单而且不会出错,你可以去网上搜下,如果搜不到我可以把代码发给你。
IIC是个很常用的通讯方式,用stm32自带设置会让你知其然不知其所以然,离开了STM32就不知道怎么办了,所以用IO模拟可以好好学习下IIC的通讯协议,也可以移植到其他任何单片机上

谢谢,我已经使用模拟I2C通讯实现了,只是有点不太明白,这个自带I2C到底是哪里有问题,是他这个stm8库问题,还是这个stm8硬件方面的问题?

我使用的是stm8,不是stm32

stm8没用过,但都是arm内核的产品,所以估计都存在一样的问题,网上说是硬件不稳定,可能是会出现通信不畅或卡死等,具体的去网上了解下。我们做的产品都不用stm硬件IIC,都是模拟IO,这样也方便移植

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top