AT24Cxx移植第三方库到裸机中使用
简介
MCU : STM32F103C8T6
库: HAL库裸机开发
EEPROM : AT24C02, 256Byte容量,I2C接口
电路图
AT24C02 电路图
电路图引用
逻辑直接读写
// 写入数据到 EEPROM
HAL_StatusTypeDef EEPROM_WriteByte(uint16_t MemAddress, uint8_t Data)
{
// 发送数据
uint8_t dataToSend[2] = { (uint8_t)(MemAddress & 0xFF), Data };
return HAL_I2C_Master_Transmit(&hi2c1, (EEPROM_I2C_ADDRESS << 1), dataToSend, 2, 100);
}
// 读取数据从 EEPROM
HAL_StatusTypeDef EEPROM_ReadByte(uint16_t MemAddress, uint8_t *Data)
{
// 发送存储地址
uint8_t addressToSend = (uint8_t)(MemAddress & 0xFF);
if (HAL_I2C_Master_Transmit(&hi2c1, (EEPROM_I2C_ADDRESS << 1), &addressToSend, 1, 100) != HAL_OK)
{
return HAL_ERROR;
}
// 读取数据
return HAL_I2C_Master_Receive(&hi2c1, (EEPROM_I2C_ADDRESS << 1), Data, 1, 100);
}
// 调用
uint8_t dat = 100;
EEPROM_WriteByte(0, dat);
HAL_Delay(10);
EEPROM_ReadByte(0, &dat);
移植第三方AT24Cxx库
引用库
AT24CXX库源码
AT24CXX系列读写算法
修改库
只需要 _24cxx_dev.c 和 _24cxx_dev.h即可
-
将代码中的地址修改如下
slave_addr = pdev->slave_addr | (addr>>8);
改为
slave_addr = pdev->slave_addr << 1; -
增加写pageBuffer
/*24cxx eeprom devcie struct*/
typedef struct
{
int (*i2c_send_thend_recv)(uint8_t slave_addr, const void *send_buff, /* i2c bus fun */
uint32_t send_size, void *recv_buff, uint32_t recv_size);
int (*i2c_send_thend_send)(uint8_t slave_addr, const void *send_buff1, /* i2c bus fun */
uint32_t send_size1,const void *send_buff2, uint32_t send_size2);
uint8_t slave_addr; /*eeprom i2c addr*/
//uint8_t type; /*eeprom type, 0:eeprom;1:fram*/
_24_model_t model; /*eeprom model*/
void(*wp)(uint8_t ctrl); /*protect of write function*/
void(*page_write_delay)(void); /*there is a delay in continuous writin for EEPROM,FRAM not need*/
uint8_t *pageBuffer;
}_24cxx_dev_t;
/*extern function*/
extern void __24cxx_dev_init(_24cxx_dev_t *pdev) ;
- pageBuffer 初始化
void __24cxx_dev_init(_24cxx_dev_t *pdev)
{
uint16_t ee_page_size = get_eeprom_pagesize(pdev->model);
if (pdev->model > _24C16_E)
pdev->pageBuffer = (uint8_t*)malloc(ee_page_size+2);
else
pdev->pageBuffer = (uint8_t*)malloc(ee_page_size+1);
}
- 将写的部分合并之后发送
写时序的问题,不合并无法正常写
/**
* @brief write one page.
* @param pdev pointer to the eeprom device struct.
* @param addr the address of write to.
* @param pbuf the data to write.
* @param size number of bytes to write..
* @retval return 0 if 0k,anything else is considered an error.
*/
static int16_t _24cxx_write_page(_24cxx_dev_t *pdev, uint32_t addr, uint8_t *pbuf, uint32_t size)
{
// uint8_t buf[2];
// uint8_t buf_size = 0;
uint8_t slave_addr = 0;
uint16_t ee_page_size = 0;
int16_t ret = 0;
if (pdev == 0)
{
return _24CXX_ERR_DEV_NONE;
}
ee_page_size = get_eeprom_pagesize(pdev->model);
if (((addr % ee_page_size) + size) > ee_page_size) /*the over flow of page size*/
{
return _24CXX_ERR_PAGE_SIZE;
}
if (pdev->model > _24C16_E)
{/*24c32-24c1024*/
slave_addr = pdev->slave_addr;
// buf[0] = (addr >>8)& 0xff;
// buf[1] = addr & 0xff;
pdev->pageBuffer[0] = (addr >>8)& 0xff;
pdev->pageBuffer[1] = addr & 0xff;
memcpy(&pdev->pageBuffer[2], pbuf, size);
size += 2;
}
else
{/*24c01-24c16*/
slave_addr = pdev->slave_addr << 1;
// buf[0] = addr & 0xff;
pdev->pageBuffer[0] = addr & 0xff;
memcpy(&pdev->pageBuffer[1], pbuf, size);
size += 1;
}
if (pdev->wp) /*release write protect*/
{
pdev->wp(0);
}
// ret = pdev->i2c_send_thend_send(slave_addr, buf, buf_size, pbuf, size);
ret = pdev->i2c_send_thend_send(slave_addr, pdev->pageBuffer, size, 0, 0);
if (pdev->wp)
{
pdev->wp(1); /*write protect*/
}
return ret;
}
- 代码使用
int hw_i2c_send_then_recv(uint8_t slave_addr, const void *send_buff, uint32_t send_size, void *recv_buff, uint32_t recv_size)
{
// 发送数据
if (HAL_OK != HAL_I2C_Master_Transmit(&hi2c1, slave_addr, (uint8_t*)send_buff, send_size, 10))
{
return _24CXX_ERR_I2C_WR;
}
if (HAL_OK != HAL_I2C_Master_Receive(&hi2c1, slave_addr, (uint8_t*)recv_buff, recv_size, 1000))
{
return _24CXX_ERR_I2C_WR;
}
return _24CXX_OK;
}
int hw_i2c_send_then_send(uint8_t slave_addr, const void *send_buff1, uint32_t send_size1,const void *send_buff2, uint32_t send_size2)
{
if (HAL_OK != HAL_I2C_Master_Transmit(&hi2c1, slave_addr, (uint8_t*)send_buff1, send_size1, 2000))
{
return _24CXX_ERR_I2C_WR;
}
if (0 != send_size2)
{
if (HAL_OK != HAL_I2C_Master_Transmit(&hi2c1, slave_addr, (uint8_t*)send_buff2, send_size2, 1000))
{
return _24CXX_ERR_I2C_WR;
}
}
return _24CXX_OK;
}
static void page_write_delay(void)
{
uint16_t i;
i = 0xFFFF;
while(i--);
}
_24cxx_dev_t at24cxx_dev =
{
.i2c_send_thend_recv=hw_i2c_send_then_recv,
.i2c_send_thend_send=hw_i2c_send_then_send,
.slave_addr=0x51, /* eeprom address */
.model=_24C02_E,
.wp=0, /* no write protect */
.page_write_delay=page_write_delay,
};
uint8_t buffer[256];
uint16_t size = 0;
uint8_t readBuffer[256];
uint16_t readSize = 256;
void readWriteBufferInit()
{
int writeSize = 256;
for (int i = 0; i < writeSize; ++i)
{
buffer[i] = 255-i;
}
size = readSize = writeSize;
memset(readBuffer, 0, sizeof(readBuffer));
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
static int ret = _24CXX_OK;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
__24cxx_dev_init(&at24cxx_dev);
/* USER CODE BEGIN 2 */
readWriteBufferInit();
ret = _24cxx_write(&at24cxx_dev, 0, (uint8_t*)buffer, size);
if (ret != _24CXX_OK)
{
}
else
{
}
HAL_Delay(100);
ret = _24cxx_read(&at24cxx_dev, 0, (uint8_t*)readBuffer, readSize);
if (ret != _24CXX_OK)
{
}
else
{
}
//for (int i = 0; i < size; ++i)
//{
// ret = EEPROM_WriteByte(i, buffer[i]);
// HAL_Delay(5);
//}
// HAL_Delay(50);
//for (int i = 0; i < size; ++i)
//{
// ret = EEPROM_ReadByte(i, &readBuffer[i]);
// HAL_Delay(5);
//}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}