OpenEdv-开源电子网

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

stm32F103用IIC读写EEPROM读写不对

[复制链接]

1

主题

6

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-8-4
在线时间
6 小时
发表于 2020-11-4 16:41:08 | 显示全部楼层 |阅读模式
10金钱
本帖最后由 hss123 于 2020-11-4 16:43 编辑

用IIC读写EEPROM,不知道是没写进去,还是什么原因,每次读到的都是0xFF,用逻辑分析仪看时序好像也没有什么问题,eeprom没有写保护(WP低电平)
代码如下:
/** ****************************************************************************
* @brief    初始化I2C的gpio   SCL SDA复用引脚配置
* @param    hi2c I2C结构体指针
* @return   GPIO初始化结果
*******************************************************************************/
static int I2cGpioInit(I2C_Device *i2c)
{

    if(I2C1 == i2c->i2cx)
    {
        GpioInit2AfOd(IIC1_SCL, GPIO_AF_PP_PULLUP);
        GpioInit2AfOd(IIC1_SDA, GPIO_AF_PP_PULLUP);  

        // __HAL_RCC_I2C1_FORCE_RESET();
        // __HAL_RCC_I2C1_RELEASE_RESET();      
    }
    else if(I2C2 == i2c->i2cx)
    {
        GpioInit2AfOd(IIC2_SCL, GPIO_AF_PP_PULLUP);   //开漏
        GpioInit2AfOd(IIC2_SDA, GPIO_AF_PP_PULLUP);  

        // __HAL_RCC_I2C2_FORCE_RESET();
        // __HAL_RCC_I2C2_RELEASE_RESET();      

    }
    else
    {
        I2C_DEBUG("I2C prot not define!");
        return I2C_NULL;
    }

    return  I2C_OK;
}

/** ****************************************************************************
* @brief    I2C工作模式配置
* @param    i2c I2C结构体指针
* @return   配置结果
*******************************************************************************/
static int32_t I2cModeCfg(I2C_Device *i2c)
{

    i2c->hi2c.Instance = i2c->i2cx;
    i2c->hi2c.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
    i2c->hi2c.Init.ClockSpeed      = 100000;
    i2c->hi2c.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    i2c->hi2c.Init.DutyCycle       = I2C_DUTYCYCLE_2;
    i2c->hi2c.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    i2c->hi2c.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLE;
    i2c->hi2c.Init.OwnAddress1     = 0x0A ;
    i2c->hi2c.Init.OwnAddress2     = 0;

    if(HAL_I2C_Init(&i2c->hi2c) != HAL_OK)               //初始化I2C
    {
        SPI_DEBUG("I2C init error!");
        return I2C_ERROR_INIT;
    }

    return I2C_OK;
}

/** ****************************************************************************
* @brief    IIC初始化
* @param    i2c I2C结构体指针
* @param    i2cx: 取值I2C1/I2C2
* @return   初始化结果
*******************************************************************************/
int32_t I2cInit(I2C_Device *i2c, I2C_TypeDef* i2cx)
{
    i2c->i2cx = i2cx;
    I2cGpioInit(i2c);

    if(I2C1 == i2c->i2cx)
    {
        __HAL_RCC_I2C1_CLK_ENABLE();  
    }
    else if(I2C2 == i2c->i2cx)
    {
        __HAL_RCC_I2C2_CLK_ENABLE();  
    }
    else
    {
        I2C_DEBUG("I2C prot not define!");
        return I2C_NULL;
    }

    I2cModeCfg(i2c);

    return I2C_OK;
}

/** ****************************************************************************
* @brief    IIC写数据到EEPROM
* @param    buf 写入数据buffer指针  
* @param    addr 写地址
* @param    num  写的字节数
* @return   写状态
*******************************************************************************/
uint32_t I2cWrite(I2C_Device* i2c, uint8_t* buf, uint16_t addr, uint16_t num)
{
    HAL_StatusTypeDef status = HAL_OK;

    status = HAL_I2C_Mem_Write(&i2c->hi2c, ((EEPROM_W_ADDRESS & 0x14) | 0xA0), addr, I2C_MEMADD_SIZE_8BIT, buf, num, 100);

    /* Check the communication status */
    if(status != HAL_OK)
    {
    /* Execute user timeout callback */
    //I2Cx_Error(Addr);
    }
    while (HAL_I2C_GetState(&i2c->hi2c) != HAL_I2C_STATE_READY)
    {

    }

    /* Check if the EEPROM is ready for a new operation */
    while (HAL_I2C_IsDeviceReady(&(i2c->hi2c), ((EEPROM_W_ADDRESS & 0x14) | 0xA0), EEPROM_MAX_TRIALS, I2Cx_TIMEOUT_MAX) == HAL_TIMEOUT);

    /* Wait for the end of the transfer */
    while (HAL_I2C_GetState(&i2c->hi2c) != HAL_I2C_STATE_READY)
    {

    }
    return status;

}

/** ****************************************************************************
* @brief    IIC读EEPROM数据
* @param    buf 存放数据buffer指针  
* @param    addr 读地址
* @param    num  读的字节数
* @return   读状态
*******************************************************************************/
int32_t I2cRead(I2C_Device *i2c, uint8_t* buf, uint16_t addr, uint16_t num)
{
    if(HAL_I2C_Mem_Read(&i2c->hi2c, ((EEPROM_W_ADDRESS & 0x14) | 0xA0), addr, I2C_MEMADD_SIZE_8BIT, buf, num, 100) != HAL_OK)
    {
        return I2C_ERR;      
    }
    else
    {
        return I2C_OK;
    }

}



// 测试函数
I2C_Device  i2c;
#define  DATA_Size          256
#define  EEP_Firstpage      0x10
uint8_t Write[DATA_Size];
uint8_t Read[DATA_Size];
int8_t I2cTest(void* argc,void*argv[])
{
    int i = shellExtParsePara(&UartShell,argv[1]);
    int j = shellExtParsePara(&UartShell,argv[2]);

    if(i == 1)
    {
         I2cInit(&i2c, I2C1);
    }
    else
    {
        I2cInit(&i2c, I2C2);

    }

//     for(int16_t i=0; i<DATA_Size; i++ )
//  {   
//        Write =i+1;
// //       printf("0x%02X ", Write);
// //       if(i%16 == 15)   
// //       printf("\n\r");   
//  }
    Write[0] = 5;
    if((j == 1) || (j == 3))
    {
       I2cWrite(&i2c, Write, EEP_Firstpage, 1);
    }

//    I2C_EE_BufferWrite(&i2c, Write, EEP_Firstpage, DATA_Size);
    delay_ms(10);
    if((j == 2 ) || (j == 3))
    {
        I2cRead(&i2c, Read, EEP_Firstpage, 1);
    }


    for (int16_t i=0; i<DATA_Size; i++)
    {   
        if(Read[i] != Write[i])
        {
            printf("eeprom error\r\n");
            printf("0x%02X ", Read[i]);
            return 0;
        }
        printf("0x%02X ", Read[i]);
        if(i%16 == 15)   
        printf("\n\r");
    }

}
SHELL_EXPORT_CMD(i2ctest, I2cTest, I2cTest);



#define EEPROM_W_ADDRESS        0xA0
#define EEPROM_R_ADDRESS        0xA1









再放两张逻辑分析仪的时序
[img]file:///C:\Users\acer\Documents\Tencent Files\787820739\Image\Group2\U}\0%\U}0%G8GZ~9332UGW[06_UF5.png[/img]file:///C:\Users\acer\Documents\Tencent Files\787820739\Image\Group2\B3\~X\B3~X98U3FFER]9HSF5A6~FW.png




QQ图片20201104164236.png
QQ图片20201104164225.png

最佳答案

查看完整内容[请看2#楼]

读写bit设置错了,把8bit改成16bit,现在可以成功读写了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-8-4
在线时间
6 小时
 楼主| 发表于 2020-11-4 16:41:09 | 显示全部楼层
读写bit设置错了,把8bit改成16bit,现在可以成功读写了
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-8-4
在线时间
6 小时
 楼主| 发表于 2020-11-5 08:40:43 | 显示全部楼层
有大神在吗?我使用的是M24C64,总感觉是不是SDA的引脚设置有什么问题
回复

使用道具 举报

2

主题

457

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4431
金钱
4431
注册时间
2018-5-14
在线时间
953 小时
发表于 2020-11-5 10:05:38 | 显示全部楼层
EEPROM写完一次数据后需要等待5ms,这5ms不响应任何操作
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-8-4
在线时间
6 小时
 楼主| 发表于 2020-11-5 10:17:31 | 显示全部楼层
姚先起 发表于 2020-11-5 10:05
EEPROM写完一次数据后需要等待5ms,这5ms不响应任何操作

什么意思呀,我写完以后等了10ms以后再去读的
回复

使用道具 举报

2

主题

457

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4431
金钱
4431
注册时间
2018-5-14
在线时间
953 小时
发表于 2020-11-5 10:45:34 | 显示全部楼层
hss123 发表于 2020-11-5 10:17
什么意思呀,我写完以后等了10ms以后再去读的

而且EEPROM也是分页的,256Byte总共分了32页,每页8字节,连续写只能在一个页里面进行,所以只能从0x00开始写8字节后,再重新开始从0x08再写8字节。不能一次性写100个字节数据。读不受影响。
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-8-4
在线时间
6 小时
 楼主| 发表于 2020-11-5 11:14:07 | 显示全部楼层
姚先起 发表于 2020-11-5 10:45
而且EEPROM也是分页的,256Byte总共分了32页,每页8字节,连续写只能在一个页里面进行,所以只能从0x00开 ...

我现在还在测试读写一个字节呢
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-4-29 23:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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