你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 HAL库 关于IIC硬件多字读写的疑问

[复制链接]
billjiang2008 提问时间:2018-2-10 11:21 /
本帖最后由 billjiang2008 于 2018-2-10 11:23 编辑

最近在做IIC读写程序,用到HAL库,发现利用HAL库 对IIC读写问题,求助一下!

在HA库对IIC读写操作的2个库函数如下:

HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)



HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)


我利用库函数对EEPROM的多字节读写做了实验如下:

HAL_StatusTypeDef EEPROM_WriteData(uint16_t MemAddr,uint8_t *pData,uint16_t Size)
{
        uint16_t i;
        HAL_StatusTypeDef sta;
        
        for(i=0;i<Size;i++)
        {
                MemAddr += i;
                sta = HAL_I2C_Mem_Write(&hi2c1,0XA0,MemAddr,I2C_MEMADD_SIZE_8BIT,&pData,1,HAL_MAX_DELAY);//利用库函数一个一个字节的将 数据写到EEPROM中
                if(sta != HAL_OK)
                        return sta;
                HAL_Delay(1);
        }
}

HAL_StatusTypeDef EEPROM_ReadData(uint16_t MemAddr,uint8_t *pData,uint16_t Size)
{
        uint16_t i;
        HAL_StatusTypeDef sta;
        
        for(i=0;i<Size;i++)
        {
                MemAddr += i;
                sta = HAL_I2C_Mem_Read(&hi2c1,0XA0,MemAddr,I2C_MEMADD_SIZE_8BIT,&pData,1,HAL_MAX_DELAY);//利用库函数一个一个字节的将数据读到缓存中
                if(sta != HAL_OK)
                        return sta;
                HAL_Delay(1);
        }
}


开始测试连续读写数据:

        uint16_t i;
        uint8_t Dat_Write[256];
        uint8_t Datread[256] ;//读缓存
  /* Infinite loop */
        taskENTER_CRITICAL();
        
        printf("*************EEPROM数据测试******************** \r\n");
        printf("待写入数据:\n");
        for(i=0;i<256;i++)
        {
                Datread=0;
                Dat_Write=0X00;
                printf("0X%02X",Dat_Write);
                if(i%16==15)
                {
                        printf("\n");
                }
        }
        
        EEPROM_WriteData(0,Dat_Write,8);
        EEPROM_WriteData(8,&Dat_Write[8],8);
        EEPROM_WriteData(16,&Dat_Write[16],8);
        
                printf("\n");
        printf("读出的数据:\n");
               
        EEPROM_ReadData(0,&Datread[0],8);
        printf("0X%02X",Datread[0]);        
        printf("0X%02X",Datread[1]);        
        printf("0X%02X",Datread[2]);
        printf("0X%02X",Datread[3]);
        printf("0X%02X",Datread[4]);               
        printf("0X%02X",Datread[5]);
        printf("0X%02X",Datread[6]);        
        printf("0X%02X\r\n",Datread[7]);        
        
        EEPROM_ReadData(8,&Datread[8],8);
        printf("0X%02X",Datread[8]);        
        printf("0X%02X",Datread[9]);        
        printf("0X%02X",Datread[10]);
        printf("0X%02X",Datread[11]);
        printf("0X%02X",Datread[12]);               
        printf("0X%02X",Datread[13]);
        printf("0X%02X",Datread[14]);        
        printf("0X%02X",Datread[15]);
        
        EEPROM_ReadData(16,&Datread[16],8);
        printf("0X%02X",Datread[16]);        
        printf("0X%02X",Datread[17]);        
        printf("0X%02X",Datread[18]);
        printf("0X%02X",Datread[19]);
        printf("0X%02X",Datread[20]);               
       printf("0X%02X",Datread[21]);
        printf("0X%02X",Datread[22]);        
        printf("0X%02X",Datread[23]);


以上程序,输出结果正常,数据读写正常!

于是想直接利用库函数,进行多字节读写,出现了问题,
这个库函数
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

于是把以上程序的        EEPROM_WriteData(0,Dat_Write,8);
                                EEPROM_WriteData(8,&Dat_Write[8],8);
                                EEPROM_WriteData(16,&Dat_Write[16],8);
改写为:
                   HAL_I2C_Mem_Write(&hi2c1,0XA0,0,I2C_MEMADD_SIZE_8BIT,&Dat_Write[0],8,HAL_MAX_DELAY);//红色字体的8是表示连续读8个字节?
                   HAL_I2C_Mem_Write(&hi2c1,0XA0,8,I2C_MEMADD_SIZE_8BIT,&Dat_Write[8],8,HAL_MAX_DELAY);
                   HAL_I2C_Mem_Write(&hi2c1,0XA0,16,I2C_MEMADD_SIZE_8BIT,&Dat_Write[16],8,HAL_MAX_DELAY);


把读                   EEPROM_ReadData(0,&Datread[0],8);
                           EEPROM_ReadData(8,&Datread[8],8);
                           EEPROM_ReadData(16,&Datread[16],8);
改写为:
                        HAL_I2C_Mem_Read(&hi2c1,0XA0,0,I2C_MEMADD_SIZE_8BIT,&Datread[0],8,HAL_MAX_DELAY);//红色字体的8是表示连续读8个字节?
                        HAL_I2C_Mem_Read(&hi2c1,0XA0,8,I2C_MEMADD_SIZE_8BIT,&Datread[8],8,HAL_MAX_DELAY);
                        HAL_I2C_Mem_Read(&hi2c1,0XA0,16,I2C_MEMADD_SIZE_8BIT,&Datread[16],8,HAL_MAX_DELAY);

改后,看串口输出数据,发现数据不正确,望高手指点,哪里出了问题!多谢!
收藏 2 评论8 发布时间:2018-2-10 11:21

举报

8个回答
七哥 回答时间:2018-2-11 01:59:01
本帖最后由 toofree 于 2018-2-11 02:07 编辑

HAL_Delay(1);
这一条延时很重要。
你在下面这三条之间必须加个延时。一般的EEPROM在发送完前一个停止位后,到下一个起始位开始之前,需要保证最大5ms的延时,最小多少得自己实际测试摸底。不知道你用的EEPROM需要多少延时。
HAL_I2C_Mem_Write(&hi2c1,0XA0,0,I2C_MEMADD_SIZE_8BIT,&Dat_Write[0],8,HAL_MAX_DELAY);//红色字体的8是表示连续读8个字节?
                   HAL_I2C_Mem_Write(&hi2c1,0XA0,8,I2C_MEMADD_SIZE_8BIT,&Dat_Write[8],8,HAL_MAX_DELAY);
                   HAL_I2C_Mem_Write(&hi2c1,0XA0,16,I2C_MEMADD_SIZE_8BIT,&Dat_Write[16],8,HAL_MAX_DELAY);

傲游截图20180211020630.jpg

傲游截图20180211020655.jpg

评分

参与人数 1蝴蝶豆 +4 收起 理由
zero99 + 4 辛苦了

查看全部评分

nyszx 回答时间:2018-2-11 09:53:06
toofree 发表于 2018-2-11 01:59
HAL_Delay(1);
这一条延时很重要。
你在下面这三条之间必须加个延时。一般的EEPROM在发送完前一个停止位后 ...

这个厉害呀: QQ截图20180211095036.jpg 半夜还没休息,还在帮助坛友。
七哥 回答时间:2018-2-11 09:59:50
nyszx 发表于 2018-2-11 09:53
这个厉害呀:半夜还没休息,还在帮助坛友。

要睡之前扫了一眼坛子,正好遇到了,就又坚持了一会儿
billjiang2008 回答时间:2018-2-11 11:38:37
toofree 发表于 2018-2-11 01:59
HAL_Delay(1);
这一条延时很重要。
你在下面这三条之间必须加个延时。一般的EEPROM在发送完前一个停止位后 ...

加了延时还是数据不正确!
HAL_I2C_Mem_Write(&hi2c1,0XA0,0,I2C_MEMADD_SIZE_8BIT,&Dat_Write[0],8,HAL_MAX_DELAY);//红色字体的8是表示连续读8个字节

我想知道参数中的8 是连续写8个字节数据吗?
七哥 回答时间:2018-2-11 12:33:31
billjiang2008 发表于 2018-2-11 11:38
加了延时还是数据不正确!
HAL_I2C_Mem_Write(&hi2c1,0XA0,0,I2C_MEMADD_SIZE_8BIT,&Dat_Write[0],8,HAL_ ...

是的,一般来说是连续写8个,不带停止位的。也就是说这个写不能跨页
Tcreat 回答时间:2018-2-11 13:17:46
像6楼提及的 EPROM的连续写操作是不支持跨page的 一般EPROM的一个page 是128字节  以开始写地址算 如果某个地址超过了开始写地址的当前page的话  EPROM会自动回到盖page的开始处写 并不是按给的地址 到下个page  所以如果一个写操作跨了多个page的话  简易根据EPROM的page地址 每个page这行一次连续写操作
zhangjie2911 回答时间:2019-1-8 11:19:09
EEPROM读取的地址不应该是0xa1吗?为什么我看你发送和读取的地址都是0xa0,并且还能读取成功?
羽夜霜降 回答时间:2019-1-16 21:54:39
楼主你好,我现在用cubemx生成的hal_i2c_mem_read函数,发设备地址0x6b,寄存器地址0x01。用示波器发现,发设备地址的时候函数把最低位置0了,也就是改为了写的逻辑电平,我把他改回来发出0x6b的波形后,无法产生0x01的波形,请问你产生的波形是什么样子,谢谢!我的邮箱是768839134@qq.com,方便的话是否可以分享一下你成功的代码

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版