当前位置: 首页 > news >正文

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即可

  1. 将代码中的地址修改如下
    slave_addr = pdev->slave_addr | (addr>>8);
    改为
    slave_addr = pdev->slave_addr << 1;

  2. 增加写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) ;
  1. 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);
}
  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;
}
  1. 代码使用
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 */
}
http://www.dtcms.com/a/98931.html

相关文章:

  • STM32单片机的桌面宠物机器人(基于HAL库)
  • Tomcat生产服务器性能优化
  • hi3516cv610编译sdk报错,解决方法
  • 深入理解Agentic Workflows
  • 迭代加深 IDE*
  • Git和GitCode使用(从Git安装到上传项目一条龙)
  • OpenCV基础——梯度计算、边缘检测、图像金字塔
  • Spring AI ToolCalling 扩展模型能力边界
  • JDK11.0.25
  • Java开发者の模型召唤术:LangChain4j咏唱指南(二)
  • Python 笔记 (二)
  • Python导论
  • HTTP介绍以及(GET/POST/PUT/DELETE)应用介绍
  • Kubernetes》》K8S》》Deployment 、Pod、Rs 、部署 nginx
  • 【C++重点】虚函数与多态
  • 责任链模式_行为型_GOF23
  • MQTT之重复消息(5、TCP重连和MQTT重连)
  • 【研究方向】联邦|自然语言
  • 自动关机监控器软件 - 您的电脑节能助手
  • JavaScript中集合常用操作方法详解
  • RHINO 转 STL,解锁 3D 打印与工业应用新通道
  • QT图片轮播器(QT实操学习2)
  • Windows 下 Rust 快速安装指南
  • puppeteer+express服务端导出页面为pdf
  • JavaScript中的Math对象和随机数
  • [ 春秋云境 ] Initial 仿真场景
  • Linux系统中应用端控制串口的基本方法
  • GEO(生成引擎优化)实施策略全解析:从用户意图到效果追踪
  • CANoe入门——CANoe的诊断模块,调用CAPL进行uds诊断
  • 鸿蒙项目源码-外卖点餐-原创!原创!原创!