STM32 HAL库 关于IIC硬件多字读写的疑问
本帖最后由 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;
uint8_t Datread ;//读缓存
/* 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);
EEPROM_WriteData(16,&Dat_Write,8);
printf("\n");
printf("读出的数据:\n");
EEPROM_ReadData(0,&Datread,8);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X\r\n",Datread);
EEPROM_ReadData(8,&Datread,8);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
EEPROM_ReadData(16,&Datread,8);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
printf("0X%02X",Datread);
以上程序,输出结果正常,数据读写正常!
于是想直接利用库函数,进行多字节读写,出现了问题,
这个库函数
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);
EEPROM_WriteData(16,&Dat_Write,8);
改写为:
HAL_I2C_Mem_Write(&hi2c1,0XA0,0,I2C_MEMADD_SIZE_8BIT,&Dat_Write,8,HAL_MAX_DELAY);//红色字体的8是表示连续读8个字节?
HAL_I2C_Mem_Write(&hi2c1,0XA0,8,I2C_MEMADD_SIZE_8BIT,&Dat_Write,8,HAL_MAX_DELAY);
HAL_I2C_Mem_Write(&hi2c1,0XA0,16,I2C_MEMADD_SIZE_8BIT,&Dat_Write,8,HAL_MAX_DELAY);
把读 EEPROM_ReadData(0,&Datread,8);
EEPROM_ReadData(8,&Datread,8);
EEPROM_ReadData(16,&Datread,8);
改写为:
HAL_I2C_Mem_Read(&hi2c1,0XA0,0,I2C_MEMADD_SIZE_8BIT,&Datread,8,HAL_MAX_DELAY);//红色字体的8是表示连续读8个字节?
HAL_I2C_Mem_Read(&hi2c1,0XA0,8,I2C_MEMADD_SIZE_8BIT,&Datread,8,HAL_MAX_DELAY);
HAL_I2C_Mem_Read(&hi2c1,0XA0,16,I2C_MEMADD_SIZE_8BIT,&Datread,8,HAL_MAX_DELAY);
改后,看串口输出数据,发现数据不正确,望高手指点,哪里出了问题!多谢!
本帖最后由 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,8,HAL_MAX_DELAY);//红色字体的8是表示连续读8个字节?
HAL_I2C_Mem_Write(&hi2c1,0XA0,8,I2C_MEMADD_SIZE_8BIT,&Dat_Write,8,HAL_MAX_DELAY);
HAL_I2C_Mem_Write(&hi2c1,0XA0,16,I2C_MEMADD_SIZE_8BIT,&Dat_Write,8,HAL_MAX_DELAY);
toofree 发表于 2018-2-11 01:59
HAL_Delay(1);
这一条延时很重要。
你在下面这三条之间必须加个延时。一般的EEPROM在发送完前一个停止位后 ...
这个厉害呀:半夜还没休息,还在帮助坛友。
nyszx 发表于 2018-2-11 09:53
这个厉害呀:半夜还没休息,还在帮助坛友。
要睡之前扫了一眼坛子,正好遇到了,就又坚持了一会儿 toofree 发表于 2018-2-11 01:59
HAL_Delay(1);
这一条延时很重要。
你在下面这三条之间必须加个延时。一般的EEPROM在发送完前一个停止位后 ...
加了延时还是数据不正确!
HAL_I2C_Mem_Write(&hi2c1,0XA0,0,I2C_MEMADD_SIZE_8BIT,&Dat_Write,8,HAL_MAX_DELAY);//红色字体的8是表示连续读8个字节
我想知道参数中的8 是连续写8个字节数据吗? billjiang2008 发表于 2018-2-11 11:38
加了延时还是数据不正确!
HAL_I2C_Mem_Write(&hi2c1,0XA0,0,I2C_MEMADD_SIZE_8BIT,&Dat_Write,8,HAL_ ...
是的,一般来说是连续写8个,不带停止位的。也就是说这个写不能跨页 像6楼提及的 EPROM的连续写操作是不支持跨page的 一般EPROM的一个page 是128字节以开始写地址算 如果某个地址超过了开始写地址的当前page的话EPROM会自动回到盖page的开始处写 并不是按给的地址 到下个page所以如果一个写操作跨了多个page的话简易根据EPROM的page地址 每个page这行一次连续写操作 EEPROM读取的地址不应该是0xa1吗?为什么我看你发送和读取的地址都是0xa0,并且还能读取成功?
楼主你好,我现在用cubemx生成的hal_i2c_mem_read函数,发设备地址0x6b,寄存器地址0x01。用示波器发现,发设备地址的时候函数把最低位置0了,也就是改为了写的逻辑电平,我把他改回来发出0x6b的波形后,无法产生0x01的波形,请问你产生的波形是什么样子,谢谢!我的邮箱是768839134@qq.com,方便的话是否可以分享一下你成功的代码
页:
[1]