110VCGQ/project/110VCGQV6/user/Src/AT24C16.c
2024-11-18 10:09:39 +08:00

99 lines
3.0 KiB
C

/*
* AT24C16.c
*
* Created on: Sep 26, 2024
* Author: 10425
*/
#include "user.h"
/**
* @brief 写入一个字节到 AT24C16
* @param mem_address EEPROM 的目标地址
* @param data 要写入的数据
* @return HAL 状态
*/
HAL_StatusTypeDef AT24C16_WriteByte(uint16_t mem_address, uint8_t data)
{
return HAL_I2C_Mem_Write(&I2C_HANDLE, AT24C16_ADDR << 1, mem_address, I2C_MEMADD_SIZE_16BIT, &data, 1, AT24C16_TIMEOUT);
}
/**
* @brief 从 AT24C16 读取一个字节
* @param mem_address EEPROM 的目标地址
* @param data 用于存放读取数据的指针
* @return HAL 状态
*/
HAL_StatusTypeDef AT24C16_ReadByte(uint16_t mem_address, uint8_t *data)
{
return HAL_I2C_Mem_Read(&I2C_HANDLE, AT24C16_ADDR << 1, mem_address, I2C_MEMADD_SIZE_16BIT, data, 1, AT24C16_TIMEOUT);
}
/**
* @brief 从 AT24C16 写入多个字节
* @param mem_address EEPROM 的目标地址
* @param data 要写入的数据指针
* @param size 要写入的字节数
* @return HAL 状态
*/
HAL_StatusTypeDef AT24C16_WriteBytes(uint16_t mem_address, uint8_t *data, uint16_t size)
{
HAL_StatusTypeDef status;
uint16_t bytes_written = 0;
uint16_t current_page_size;
// 写入多个字节,考虑跨页问题
while (bytes_written < size)
{
// 计算当前页的剩余字节数,确保不会超出页面边界
current_page_size = AT24C16_PAGE_SIZE - (mem_address % AT24C16_PAGE_SIZE);
// 如果当前数据剩余量小于当前页大小,则写入剩余数据量
if (size - bytes_written < current_page_size)
current_page_size = size - bytes_written;
// 向当前页写入数据
status = HAL_I2C_Mem_Write(&I2C_HANDLE, AT24C16_ADDR<<1, mem_address,
I2C_MEMADD_SIZE_8BIT, data + bytes_written, current_page_size, AT24C16_TIMEOUT);
if (status != HAL_OK)
return status; // 如果写入失败,立即返回错误
// 更新地址和已写入的字节数
mem_address += current_page_size;
bytes_written += current_page_size;
// EEPROM 写入需要等待写周期,确保数据已写入
HAL_Delay(5); // 根据 AT24C16 数据手册,写入周期一般为 5ms
}
return HAL_OK;
}
/**
* @brief 从 AT24C16 读取多个字节
* @param mem_address EEPROM 的目标地址
* @param data 用于存放读取数据的指针
* @param size 要读取的字节数
* @return HAL 状态
*/
HAL_StatusTypeDef AT24C16_ReadBytes(uint16_t mem_address, uint8_t *data, uint16_t size)
{
return HAL_I2C_Mem_Read(&I2C_HANDLE, AT24C16_ADDR << 1, mem_address, I2C_MEMADD_SIZE_8BIT, data, size, HAL_MAX_DELAY);
}
/**
* @brief 初始化 AT24C16 驱动
* @return HAL 状态
*/
HAL_StatusTypeDef AT24C16_Init(void)
{
// 此函数可以包含特定的初始化代码,通常包括对 I²C 的配置和校验
if (HAL_I2C_IsDeviceReady(&I2C_HANDLE, AT24C16_ADDR << 1, 3,AT24C16_TIMEOUT) != HAL_OK)
{
return HAL_ERROR; // 如果设备未准备好则返回错误
}
return HAL_OK;
}