【STM32】AT24C256硬件I2C读写,基于HAL库

这篇具有很好参考价值的文章主要介绍了【STM32】AT24C256硬件I2C读写,基于HAL库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、简单介绍

二、配置工程

打开CubeMX,配置时钟,调试接口,工程名,目录等

配置iic

配置串口用于显示信息

三、硬件连接

四、代码编写

一、随机写入一个字节

测试代码

波形如下

代码编写

二、连续写入

代码如下

三、随机读取

测试代码

波形如下

代码编写

四、连续读取

代码如下

五、效果展示

五、驱动附录

AT24C256.h

AT24C256.c


一、简单介绍

EEPROM (Electrically Erasable Programmable read only memory)是指带电可擦可编程只读存储器。是一种掉电后数据不丢失的存储芯片。 EEPROM 可以在电脑上或专用设备上擦除已有信息,重新编程。一般用在即插即用。

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

笔者所用模块为AT24C256,存储容量256Kb即32KB(32K字节)。模块的原理图如下

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

引脚名称  功能
A0-A1(A2其实是NC脚,原理图画得不对) 器件地址输入
SDA(原理图中的DATA脚) 串行数据
SCL 时钟
WP(原理图中的HOLD脚) 写保护(高电平有效)
VCC 接高电平(1.8-5.5V宽电压)
GND

驱动协议是IIC,考虑开启硬件IIC进行通信,笔者选择使用IIC2

二、配置工程

打开CubeMX,配置时钟,调试接口,工程名,目录等

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

配置iic

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

配置串口用于显示信息

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

三、硬件连接

如上一步的配置,将模块与单片机如下连接

PB10---->SCL

PB11---->SDA

VCC---->3V3

GND---->GND

四、代码编写

一、随机写入一个字节

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

先发送器件地址或上读写指令,再发送要写入的地址(占2个字节),再发送写入的字节,再发送停止位。

由于A0和A1均为低电平,即0,那么器件地址为0x50(0101 0000)

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

此时为写入,R/W就是0,经过组合后为0xA0

测试代码

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

即向AT24C256内存地址为0的地方写入数据“1”,需要注意的是AT24C256写入数据需要等待5~10ms,要加一个延时

波形如下

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

代码编写

void AT24C256_WriteByte(uint16_t addr,uint8_t dat)
{
	HAL_I2C_Mem_Write(&hi2c2,AT24C256_ADDR_WRITE,addr,AT24C256_ADDR_LEN,&dat,1,0xffff);
	HAL_Delay(AT24C256_WAIT_TIME_UINT);
}

二、连续写入

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

连续写入和随机写入差不多,只是如果一次写的个数超过一页的字节数或者地址计到一页的尾部时,会重新回到这页开头覆盖写过的数而不会自动翻页,这是需要处理的地方。

代码如下

/*
AT24C256有256K个位,即32KB,32k字节,寻址空间为0~0x7FFF,
分为两个字节,地址1为0~0x7F,地址AT24C256_ADDR_LEN为0~0xFF
一页有64个字节,分为512页
*/
void AT24C256_WriteMultiByte(uint16_t addr,uint8_t* dat,uint16_t n)
{
	uint16_t i = 0;
    uint16_t cnt = 0;        //写入字节计数
	uint16_t head;
	uint16_t left;
	uint16_t tail;
	
	if((n + addr)/AT24C256_PAGE_SIZE == addr/AT24C256_PAGE_SIZE)		//如果在同一页
	{
		HAL_I2C_Mem_Write(&hi2c2, AT24C256_ADDR_WRITE, addr, AT24C256_ADDR_LEN, dat, n, 0xFFFF);
    HAL_Delay(AT24C256_WAIT_TIME_UINT*n);
	}
	else
	{
		head = (addr / AT24C256_PAGE_SIZE+1) * AT24C256_PAGE_SIZE - addr;	//开始页剩余待写入字节数
		left = n - head;													//除去开始页剩下字节数
		tail=left-left/AT24C256_PAGE_SIZE*AT24C256_PAGE_SIZE;				//末页待写入字节数
		HAL_I2C_Mem_Write(&hi2c2, AT24C256_ADDR_WRITE,addr,AT24C256_ADDR_LEN,dat,head,0xffff);
		HAL_Delay(AT24C256_WAIT_TIME_UINT*head);
		for(i=0;i<left/AT24C256_PAGE_SIZE;i++)
		{
			HAL_I2C_Mem_Write(&hi2c2, AT24C256_ADDR_WRITE, addr+head+i*AT24C256_PAGE_SIZE,\
			AT24C256_ADDR_LEN, dat+head+i*AT24C256_PAGE_SIZE,AT24C256_PAGE_SIZE, 0xFFFF);
			HAL_Delay(AT24C256_WAIT_TIME_UINT*AT24C256_PAGE_SIZE);
		}
		HAL_I2C_Mem_Write(&hi2c2, AT24C256_ADDR_WRITE,addr+head+i*AT24C256_PAGE_SIZE,AT24C256_ADDR_LEN,\
		dat+head+i*AT24C256_PAGE_SIZE,tail,0xffff);
		HAL_Delay(AT24C256_WAIT_TIME_UINT*tail);
	}	
}

三、随机读取

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

要先发送一个假写的动作,把地址定位到要读的地方,然后再发送读指令,此时模块就会把数据一个接一个地clock出来了

测试代码

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

波形如下

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

代码编写

uint8_t AT24C256_ReadByte(uint16_t addr)
{
	uint8_t p;
	HAL_I2C_Mem_Read(&hi2c2,AT24C256_ADDR_READ,addr,AT24C256_ADDR_LEN,&p,1,0xffff);
	return p;
}

四、连续读取

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节

由于连续读写的时候,地址会自动增加,并且会翻页,所以不必担心重复读取的问题,只要别读比最大地址范围还大的地址一般没有问题(经过笔者测试,如果读取0x8000地址的值,得到的是0x0000处的值),而且读数据不用等待,非常不错

代码如下

/*
连续读字节,参数为开始读地址,用来存储数据的地址,要读取的个数
*/
void AT24C256_ReadMultiByte(uint16_t addr,uint8_t* dat,uint16_t n)
{
	if(addr+n<0x8000)
	HAL_I2C_Mem_Read(&hi2c2,AT24C256_ADDR_READ,addr,AT24C256_ADDR_LEN,dat,n,0xffff);
}

五、效果展示

主函数main.c主要代码如下

#include "main.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "AT24C256.h"
#include "stdio.h"
#include "stdlib.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define TEST_BUFFER_LEN 1024
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint16_t x;
uint8_t buffer[TEST_BUFFER_LEN];
uint8_t b[TEST_BUFFER_LEN];
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* 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();
  MX_I2C2_Init();
  MX_TIM2_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

for(x=0;x<TEST_BUFFER_LEN;x++)
{
	*(buffer+x)=x%256;
}
printf("start\r\n");
AT24C256_WriteMultiByte(0x0,buffer,TEST_BUFFER_LEN);
printf("end\r\n");

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  AT24C256_ReadMultiByte(0,b,TEST_BUFFER_LEN);
	  for(uint16_t i=0;i<TEST_BUFFER_LEN;i++)
	  {
		  x=AT24C256_ReadByte(i);
		  printf("addr:%d\t-->:%d\r\n",i,b[i]);
	  }
	  printf("\r\n\r\n\r\n");
	  HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节at24c256,STM32单片机,stm32,嵌入式硬件,单片机,1024程序员节文章来源地址https://www.toymoban.com/news/detail-768295.html

五、驱动附录

AT24C256.h

#ifndef AT24C256_H
#define AT24C256_H
#include "main.h"
#define	   AT24C256_ADDR_LEN 		2
#define    AT24C256_ADDR_WRITE  	0xA0
#define    AT24C256_ADDR_READ   	0xA1
#define    AT24C256_PAGE_SIZE		64
#define	   AT24C256_WAIT_TIME_UINT 	2
#define	   AT24C256_MEM_LEN 		0x8000
void AT24C256_WriteByte(uint16_t add,uint8_t dat);
uint8_t AT24C256_ReadByte(uint16_t add);
void AT24C256_WriteMultiByte(uint16_t add,uint8_t* dat,uint16_t n);
void AT24C256_Fill(uint8_t fill);
void AT24C256_ReadMultiByte(uint16_t addr,uint8_t* dat,uint16_t n);
#endif

AT24C256.c


#include "i2c.h"
#include "AT24C256.h"
#include "string.h"
uint8_t erase[512];

void AT24C256_WriteByte(uint16_t addr,uint8_t dat)
{
	HAL_I2C_Mem_Write(&hi2c2,AT24C256_ADDR_WRITE,addr,AT24C256_ADDR_LEN,&dat,1,0xffff);
	HAL_Delay(AT24C256_WAIT_TIME_UINT);
}
/*
AT24C256有256K个位,即32KB,32k字节,寻址空间为0~0x7FFF,
分为两个字节,地址1为0~0x7F,地址2为0~0xFF
一页有64个字节,分为512页
*/
void AT24C256_WriteMultiByte(uint16_t addr,uint8_t* dat,uint16_t n)
{
	uint16_t i = 0;
    uint16_t cnt = 0;        //写入字节计数
	uint16_t head;
	uint16_t left;
	uint16_t tail;
	
	if((n + addr)/AT24C256_PAGE_SIZE == addr/AT24C256_PAGE_SIZE)		//如果在同一页
	{
		HAL_I2C_Mem_Write(&hi2c2, AT24C256_ADDR_WRITE, addr, AT24C256_ADDR_LEN, dat, n, 0xFFFF);
    HAL_Delay(AT24C256_WAIT_TIME_UINT*n);
	}
	else
	{
		head = (addr / AT24C256_PAGE_SIZE+1) * AT24C256_PAGE_SIZE - addr;	//开始页剩余待写入字节数
		left = n - head;													//除去开始页剩下字节数
		tail=left-left/AT24C256_PAGE_SIZE*AT24C256_PAGE_SIZE;				//末页待写入字节数
		HAL_I2C_Mem_Write(&hi2c2, AT24C256_ADDR_WRITE,addr,AT24C256_ADDR_LEN,dat,head,0xffff);
		HAL_Delay(AT24C256_WAIT_TIME_UINT*head);
		for(i=0;i<left/AT24C256_PAGE_SIZE;i++)
		{
			HAL_I2C_Mem_Write(&hi2c2, AT24C256_ADDR_WRITE, addr+head+i*AT24C256_PAGE_SIZE,\
			AT24C256_ADDR_LEN, dat+head+i*AT24C256_PAGE_SIZE,AT24C256_PAGE_SIZE, 0xFFFF);
			HAL_Delay(AT24C256_WAIT_TIME_UINT*AT24C256_PAGE_SIZE);
		}
		HAL_I2C_Mem_Write(&hi2c2, AT24C256_ADDR_WRITE,addr+head+i*AT24C256_PAGE_SIZE,AT24C256_ADDR_LEN,\
		dat+head+i*AT24C256_PAGE_SIZE,tail,0xffff);
		HAL_Delay(AT24C256_WAIT_TIME_UINT*tail);
	}	
}


uint8_t AT24C256_ReadByte(uint16_t addr)
{
	uint8_t p;
	HAL_I2C_Mem_Read(&hi2c2,AT24C256_ADDR_READ,addr,AT24C256_ADDR_LEN,&p,1,0xffff);
	return p;
}
/*
连续读字节,参数为开始读地址,用来存储数据的地址,要读取的个数
*/
void AT24C256_ReadMultiByte(uint16_t addr,uint8_t* dat,uint16_t n)
{
	if(addr+n<0x8000)
	HAL_I2C_Mem_Read(&hi2c2,AT24C256_ADDR_READ,addr,AT24C256_ADDR_LEN,dat,n,0xffff);
}
void AT24C256_Fill(uint8_t fill)
{
	memset(erase,fill,512);
	for(uint16_t i=0;i<64;i++)
	{
		AT24C256_WriteMultiByte(i*512,erase,512);
	}
}

到了这里,关于【STM32】AT24C256硬件I2C读写,基于HAL库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AT24C02(I2C总线)通信的学习

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 学习AT24C02(I2C总线)芯片 RAM()存储速度较快,但容易丢失数据。ROM(Read Only Memory)存储速度较慢,但掉电不丢失数据。在使用时需要两者结合先存入RAM再转存到ROM中。 AT24C02是一种可以实现掉电不丢失

    2024年02月20日
    浏览(49)
  • 【51单片机】AT24C20数据帧(I2C总线)

    🎊专栏【51单片机】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Love Story】 🥰大一同学小吉,欢迎并且感谢大家指出我的问题🥰 小吉先向大家道个歉,因为最近在期末突击,所以文章久久没有更新,也请大家多多见谅😥 目录   🎁I2C总线 🏳️‍🌈

    2024年02月08日
    浏览(72)
  • 51单片机——模拟I2C总线与AT24C02通信

    目录 一、写在前面 二、功能描述 三、主要模块介绍 3.1 I2C总线介绍 3.2 I2C总线协议 3.2.1数据有效规定 3.2.2起始信号和停止信号  3.2.3 发送应答和接收应答 3.2.4 主机发送一个字节和接收一个字节 3.3 AT24C02介绍 3.3 字节写和随机读 四、测试文件test.c 五、现象描述 AT24C02芯片有I

    2024年02月14日
    浏览(56)
  • 【STM32L496】使用HAL库实现I2C写入/读取数据(M24C32)

    IIC原理超详细讲解—值得一看 【嵌入式硬件芯片开发笔记】EEPROM芯片M24C32配置流程 STM32硬件I2C与软件模拟I2C超详解 实现通信功能的芯片为M24C32,对此,芯片手册上第一页就有对其概括描述。 Automotive 32-Kbit serial I²C bus EEPROM with 1 MHz clock 启动/停止条件 :当串行时钟(SCL)位于

    2024年02月03日
    浏览(70)
  • 【STM32学习】——STM32-I2C外设&硬件读写MPU6050&软硬件读写波形对比

    目录 前言 一、I2C外设 二、硬件I2C操作流程 1.主机发送时序 3.其他时序

    2024年02月10日
    浏览(49)
  • 【STM32】STM32学习笔记-硬件I2C读写MPU6050(35)

    I2C(Inter-Integrated Circuit)总线是一种由NXP(原PHILIPS)公司开发的两线式串行总线,用于连接微控制器及其外围设备。多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。 串行的 8 位双向数据传输位速率在标准模式下可

    2024年01月25日
    浏览(62)
  • 【IMX6ULL驱动开发学习】10.Linux I2C驱动实战:AT24C02驱动设计流程

    前情回顾:【IMX6ULL驱动开发学习】09.Linux之I2C框架简介和驱动程序模板_阿龙还在写代码的博客-CSDN博客 目录 一、修改设备树(设备树用来指定引脚资源) 二、编写驱动 2.1 i2c_drv_read 2.2 i2c_drv_write 2.3 完整驱动程序 三、上机测试 放在哪个I2C控制器下面 AT24C02的I2C设备地址(查

    2024年02月11日
    浏览(52)
  • STM32硬件I2C通信外设

    本文主要介绍stm32自带的I2C通信外设,对比与软件模拟I2C,硬件I2C可以自动生成时序,时序的操作更加及时规范,可以实现更加高性能的IIC通信。 本文内容与I2C软件通信有诸多类似之处,I2C软件通信可见:https://blog.csdn.net/qq_53922901/article/details/136662006?spm=1001.2014.3001.5501 在8位指

    2024年04月08日
    浏览(98)
  • 【stm32】软件I2C读写MPU6050

    概况 首先建立通信层的.c和.h模块 在通信层里写好I2C底层的GPIO初始化 以及6个时序基本单元 起始、终值、发送一个字节、接收一个字节、发送应答、接收应答 写好I2C通信层之后,再建立MPU6050的.c和.h模块 基于I2C通信的模块,来实现指定地址读、指定地址写 再实现写寄存器对

    2024年04月26日
    浏览(53)
  • 【STM32】入门(七):I2C硬件控制方式

    之所以叫“I2C硬件控制方式”是与“软件控制方式”相对。I2C软件控制,就是写程序直接操作两个GPIO引脚,分别作为时钟线SCL和数据线SDA,按照I2C协议的时序要求,操作GPIO输入、输出、高电平、低电平。 听着就很复杂,好在STM32中有I2C的硬件实现,即通过简单的操作寄存器

    2023年04月08日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包