配置SYS和时钟
https://blog.csdn.net/hmxm6/article/details/136636793
配置I2C
I2C Speed Mode: IIC模式设置 快速模式和标准模式。实际上也就是速率的选择。
I2C Clock Speed:I2C传输速率,默认为100KHz
Fast Mode Duty Cycle:快速模式下的I2C占空比
Clock No Stretch Mode: 时钟没有扩展模式
Primary Address Length selection: 从设备地址长度 设置从设备的地址是7bit还是10bit 大部分为7bit
Dual Address Acknowledged: 双地址确认
Primary slave address: 从设备初始地址
查看原理图对应引脚
注意事项
AT24C02有不同型号,对应每页的字节不同
型号 | 容量bit | 容量byte | 页数 | 字节/页 | 器件寻址位 | 可寻址器件数 | WordAddress位数/字节数 |
---|---|---|---|---|---|---|---|
AT24C32 | 32k | 4K | 128 | 32 | A2A1A0 | 8 | 12/2 |
AT24C64 | 64k | 8K | 256 | 32 | A2A1A0 | 8 | 13/2 |
AT24C128 | 128k | 16K | 256 | 64 | A1A0 | 4 | 14/2 |
AT24C256 | 256k | 32K | 512 | 64 | A1A0 | 4 | 15/2 |
AT24C512 | 512k | 64K | 512 | 128 | A2A1A0 | 8 | 16/2 |
I2C设备地址
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|
1 | 0 | 1 | 0 | A2 | A1 | A0 | R/~W |
写入数据
每次写入数据不得超过页字节数
测试代码
头文件
#ifndef __BSP_I2C_EEPROM_H__
#define __BSP_I2C_EEPROM_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f4xx.h"
#define EEPROM_ADDRESS 0xA0
#define EEPROM_MAX_TRIALS 300
#define I2Cx_TIMEOUT_MAX 300
#define EEPROM_PAGESIZE 8
// 初始化
void I2C_EEPROM_Init(I2C_HandleTypeDef i2cHandle);
// 写入页数据
void I2C_EEPROM_BufferWrite(uint8_t* pBuffer, uint8_t DeviceAddress, uint8_t WriteAddr, uint16_t NumByteToWrite);
// 写入数据
uint32_t I2C_EEPROM_PageWrite(uint8_t* pBuffer, uint8_t DeviceAddress, uint8_t WriteAddr, uint8_t NumByteToWrite);
// 读取数据
uint32_t I2C_EEPROM_BufferRead(uint8_t* pBuffer,uint8_t DeviceAddress, uint8_t ReadAddr, uint16_t NumByteToRead);
#ifdef __cplusplus
}
#endif
#endif /* __BSP_I2C_EEPROM_H__ */
初始化函数
I2C_HandleTypeDef I2C_Handle;
void I2C_EEPROM_Init(I2C_HandleTypeDef i2cHandle)
{
I2C_Handle = i2cHandle;
}
EEPROM读取函数
uint32_t I2C_EEPROM_BufferRead(uint8_t* pBuffer,uint8_t DeviceAddress, uint8_t ReadAddr, uint16_t NumByteToRead)
{
HAL_StatusTypeDef status = HAL_OK;
status=HAL_I2C_Mem_Read(&I2C_Handle, DeviceAddress, ReadAddr, I2C_MEMADD_SIZE_8BIT, (uint8_t *)pBuffer, NumByteToRead, 1000);
return status;
}
EEPROM单页写入函数
uint32_t I2C_EEPROM_PageWrite(uint8_t* pBuffer, uint8_t DeviceAddress, uint8_t WriteAddr, uint8_t NumByteToWrite)
{
HAL_StatusTypeDef status = HAL_OK;
// 写入数据
status=HAL_I2C_Mem_Write(&I2C_Handle, DeviceAddress, WriteAddr, I2C_MEMADD_SIZE_8BIT, (uint8_t*)(pBuffer),NumByteToWrite, 100);
// 检查总线是否准备好
while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)
{
}
// 检查设备是否准备好
while (HAL_I2C_IsDeviceReady(&I2C_Handle, DeviceAddress, EEPROM_MAX_TRIALS, I2Cx_TIMEOUT_MAX) == HAL_TIMEOUT);
// 检查总线是否准备好
while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY)
{
}
return status;
}
EEPROM多页写函数
void I2C_EEPROM_BufferWrite(uint8_t* pBuffer, uint8_t DeviceAddress, uint8_t WriteAddr, uint16_t NumByteToWrite)
{
uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
Addr = WriteAddr % EEPROM_PAGESIZE;
count = EEPROM_PAGESIZE - Addr;
NumOfPage = NumByteToWrite / EEPROM_PAGESIZE;
NumOfSingle = NumByteToWrite % EEPROM_PAGESIZE;
/* If WriteAddr is I2C_PageSize aligned */
if(Addr == 0)
{
/* If NumByteToWrite < I2C_PageSize */
if(NumOfPage == 0)
{
I2C_EEPROM_PageWrite(pBuffer, DeviceAddress, WriteAddr, NumOfSingle);
}
/* If NumByteToWrite > I2C_PageSize */
else
{
for(int i=0;i<NumOfPage;i++)
{
I2C_EEPROM_PageWrite(pBuffer+(i*EEPROM_PAGESIZE), DeviceAddress, WriteAddr+(i*EEPROM_PAGESIZE), EEPROM_PAGESIZE);
}
if(NumOfSingle!=0)
{
I2C_EEPROM_PageWrite(pBuffer, DeviceAddress, WriteAddr, NumOfSingle);
}
}
}
}
main函数
#define DATA_Size 256
uint8_t I2c_Buf_Write[DATA_Size] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
uint8_t I2c_Buf_Read[DATA_Size];
I2C_EEPROM_Init(hi2c1);
printf("\r\n AT24C02 I2C Test \r\n");
printf("write Data \r\n");
I2C_EEPROM_BufferWrite( I2c_Buf_Write, EEPROM_ADDRESS, 0x00, DATA_Size);
printf("read Data \r\n");
I2C_EEPROM_BufferRead(I2c_Buf_Read, EEPROM_ADDRESS, 0x00, DATA_Size);
for (int i=0; i<DATA_Size; i++)
{
printf("[%d]:%d \r\n", i, I2c_Buf_Read[i]);
}
测试
测试程序下载
https://download.csdn.net/download/hmxm6/88969827