【STM32CubeMX+HAL库】I2C详解+读写EEPROM

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

在之前的标准库中,STM32的硬件IIC非常复杂,更重要的是它并不稳定,所以都不推荐使用。但是在我们的HAL库中,对硬件IIC做了全新的优化,使得之前软件IIC几百行代码,在HAL库中,只需要寥寥几行就可以完成 那么这篇文章将带你去感受下它的优异之处。

本文将详细地讲解I2C协议,并基于I2C
来读写EEPROM模块以达到练习的目的

通过本篇博客您将学到:

  • I2C的基本原理
  • STM32CubeMX创建I2C例程
  • I2C函数库(HAL)
  • AT24C256芯片原理及读写方法

I2C简介 

IIC(Inter-Integrated Circuit)总线是一种由NXP(原PHILIPS)公司开发的两线式串行总线,用于连接微控制器及其外围设备。多用于主控制器和从器件间的主从通信。

I2C特性

  • 半双工
  • 没有严格的波特率要求
  • 小数据量场合使用
  • 传输距离短、传输速率不如SPI
  • 任何时刻只能有一个主机,但任何设备都可成为主机
  •  只需要两条总线——SDA与SCL 

 IIC一共有只有两个总线: 一条是双向的数据线SDA,一条是串行时钟线SCL

所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。I2C总线上的每一个设备都对应一个唯一的地址。

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

 I2C起始信号与终止信号(代码段为软件I2C)

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

1、起始信号:SCL为高电平时,SDA由高->低

void I2C_Start()
{
SDA=1;               //确保SDA为高电平
HAL_Delay(1);
SCL=1;               //确保SCL为高电平
HAL_Delay(1);
SDA=0;              //SCL为高时拉低SDA线
HAL_Delay(1);
SCL=0;              //钳住I2C总线,准备数据的发送与接收
}

2、终止信号:SCL为高电平时,SDA由低->高

void I2C_Stop()
{
SCL=0;            
SDA=0;
HAL_Delay(1);
SCL=1;             //确保SCL为高电平
HAL_Delay(1);
SDA=1;            //SCL为高时拉高SDA
} 

I2C应答信号与非应答信号 (代码段为软件I2C)

每当主机向从机发送完一个字节的数据,主机总是需要等待从机给出一个应答信号,以确认从机是否成功接收到了数据。

  • 应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字节;
  • 应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。
     

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

1、应答信号‘0’:SCL高时SDA低

void I2C_Ack()        //产生应答信号
{
SCL=0;
SDA=0;
HAL_Delay(1);
SCL=1;             //确保SCL为高时SDA为低
HAL_Delay(1);
SCL=0;
}

2、非应答信号‘1’:SCL高时SDA高

void I2C_NAck()     //不产生应答信号
{
SCL=0;
SDA=1;
HAL_Delay(1);
SCL=1;             //SCL高时SDA高
HAL_Delay(1);
SCL=0;
}

I2C数据有效性

I2C信号在进行数据传输时, 当SCL=1高电平时,数据线SDA必须保持稳定状态,不允许有电平跳变,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。

SCL=1时 数据线SDA的任何电平变换会看做是总线的起始信号或者停止信号。也就是在IIC传输数据的过程中,SCL时钟线会频繁的转换电平,以保证数据的传输

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

 接着我们介绍一下基于AT24C256的I2C通信

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

AT24C256芯片手册如下:

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

 描述:

AT24C256是提供131072/262144位串行电可擦除可编程只读存储器(EEPROM),该设备最多允许4个设备共享一条公共的双线总线。

特征:

  • 低电压和标准电压操作-2.7V(Vcc=2.7V至5.5V)(一般选择3.3V)
  • 双线串行接口
  • 施密特触发器,用于噪声抑制的滤波输入
  • 双向数据传输协议
  • 400kHz兼容性
  • 硬件和软件的写保护引脚
  • 64字节页写入模式(允许部分页写入)
  • 自定时写入周期
  • 高可靠性(数据保留:40年)

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

  •  A0,A1,A2:硬件地址引脚
  • WP:写保护引脚,接高电平只读,接地允许读和写

 芯片的寻址:

AT24C设备地址为如下,前四位固定为1010,A2~A0为由管脚电平。AT24CXX EEPROM Board模块中默认为接地。所以A2~A0默认为000,最后一位表示读写操作。所以AT24Cxx的读地址为0xA1,写地址为0xA0。

也就是说如果是\写24C02的时候,从器件地址为10100000(0xA0);读24C02的时候,从器件地址为10100001(0xA1)。

注意:

  1. 在写数据的过程中,每成功写入一个字节,E2PROM存储空间的地址就会自动加1当加到0xFF后,再写一个字节,地址就会溢出又变成0x00。
  2. 当我们在写多个字节时,写入一个字节之后,再写入下一个字节之前,必须延时5ms才可以

 STM32CubeMX创建I2C例程(作者使用的是STM32f4ccu6)

1、设置RCC时钟

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

2、配置I2C

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

  •  Master  features  主模式特性
  • I2C Speed Mode: IIC模式设置 快速模式和标准模式。实际上也就是速率的选择。I2C Clock Speed:I2C传输速率,默认为100KHz
  • Slave  features  从模式特性
  • Clock No Stretch Mode: 时钟没有扩展模式
  • IIC时钟拉伸(Clock stretching) - -clock stretching通过将SCL线拉低来暂停一个传输.直到释放SCL线为高电平,传输才继续进行.clock stretching是可选的,实际上大多数从设备不包括SCL驱动,所以它们不能stretch时钟.
  • Primary Address Length selection: 从设备地址长度 设置从设备的地址是7bit还是10bit 大部分为7bit
  • Dual Address Acknowledged: 双地址确认
  • Primary slave address:  从设备初始地址

3、配置串口

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

这里配置串口是为了读EEPROM并打印出来。 

4、时钟树配置

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

5、项目文件配置

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

  • 设置项目名称
  • 设置项目路径(不能包含中文
  • 选择IDE(作者用的是keil5)  

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

  • 复制所用的.c和.h文件 
  • 不同功能生成独立的.c和.h文件

6、 生成代码

7、配置下载工具

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

8、重写printf函数

重写printf函数能更方便与上位机通信 ,方法参考printf重写

I2C函数库(HAL)

在I2C.c文件中可以看到I2C初始化函数。在stm32f1xx_hal_i2c.h头文件中可以看到I2C的操作函数。分别对应轮询中断DMA三种控制方式

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机
 

 这里我们简单介绍一下等下用到的函数

HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

功能: IIC写多个数据 该函数适用于IIC外设里面还有子地址寄存器的设备,比方说E2PROM,除了设备地址,每个存储字节都有其对应的地址 

  • I2C_HandleTypeDef *hi2c  i2c句柄,例如上文配置的&hi2c1,实际上是一个结构体hal_i2c_mem_read,stm32,嵌入式,stm32,单片机
  • uint16_t DevAddress    从机设备地址,对AT24Cxx来说,0xA0代表写数据,0xA1代表读数据
  • uint16_t MemAddress    从机寄存器地址,每写入一个字节的数据,地址自动+1
  • uint16_t MemAddSize    从机寄存器地址长度,8bit和16bit可选
  • uint8_t *pData    发送数据的起始地址
  •  uint16_t Size     传输数据的大小
  • uint32_t Timeout     传输超时时间 

 读写AT24C256

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define AT24C256_Write 0xA0
#define AT24C256_Read 0xA1
#define BufferSize 64
/* USER CODE END PD */

宏定义,增加了程序的可读性

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

/* USER CODE BEGIN PV */
uint8_t w[BufferSize],r[BufferSize];
uint16_t i,j;
/* USER CODE END PV */

定义接收与发送数组

 /* USER CODE BEGIN 2 */
for(i=0;i<64;i++)
{
	w[i]=i;
}
printf("I2C Example Test\n");
//for( j=0;j<16;j++)
//{
	if(HAL_I2C_Mem_Write(&hi2c1,AT24C256_Write,0,I2C_MEMADD_SIZE_16BIT,w,64,10000)==HAL_OK)
	{
		printf("EEPROM AT24C256 Write Test OK\n");
		HAL_Delay(100);
	}
	else
	{
		printf("EEPROM AT24C256 Write Test False");
		HAL_Delay(50);
	}
//}
HAL_Delay(100);
HAL_I2C_Mem_Read(&hi2c1,AT24C256_Read,0,I2C_MEMADD_SIZE_16BIT,r,BufferSize,10000);
for(i=0;i<64;i++)
{
	HAL_Delay(10);
	printf("0x%02X  ",r[i]);
}
  /* USER CODE END 2 */

64字节一次性写入

 /* USER CODE BEGIN 2 */
for(i=0;i<64;i++)
{
	w[i]=i;
}
printf("I2C Example Test\n");
for( j=0;j<16;j++)
{
	if(HAL_I2C_Mem_Write(&hi2c1,AT24C256_Write,0+16*j,I2C_MEMADD_SIZE_16BIT,w+16*j,16,10000)==HAL_OK)
	{
		printf("EEPROM AT24C256 Write Test OK\n");
		HAL_Delay(100);
	}
	else
	{
		printf("EEPROM AT24C256 Write Test False");
		HAL_Delay(50);
	}
}
HAL_Delay(100);
HAL_I2C_Mem_Read(&hi2c1,AT24C256_Read,0,I2C_MEMADD_SIZE_16BIT,r,BufferSize,10000);
for(i=0;i<64;i++)
{
	HAL_Delay(10);
	printf("0x%02X  ",r[i]);
}
  /* USER CODE END 2 */

分批次写入

单片机烧录,运行

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

 注意:确保写入时地址不会溢出,否则可能像当时的菜鸡博主一样搞半天(如下)

hal_i2c_mem_read,stm32,嵌入式,stm32,单片机

 文章来源地址https://www.toymoban.com/news/detail-779969.html

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

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

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

相关文章

  • 【STM32 CubeMX】I2C层次结构、I2C协议

    在STM32 CubeMX环境中,I2C(Inter-Integrated Circuit)是一种常用的串行通信协议,广泛应用于连接各种外设和传感器。理解I2C的层次结构、协议和硬件结构对于STM32微控制器的开发至关重要。通过STM32 CubeMX提供的图形化配置工具,我们能够更轻松地理解和配置I2C通信,同时深入了解

    2024年02月22日
    浏览(24)
  • 4针0.96寸OLED的HAL库代码(硬件I2C/全代码/stm32f1/CubeMX配置/包含有正负浮点数/100%一次点亮)

    一、HC-SR04超声波模块的使用 二、4针OLED的HAL库代码介绍及使用(本篇) 三、7针OLED的HAL库代码介绍及使用 四、编码电机以及双电机驱动 更多有意思的文章点击“我的主页” --------😐 更多有意思的视频 ----- B站 @想要亿只独角兽 --------😐 之前在做一些小项目时用到了OLED,到

    2024年02月10日
    浏览(14)
  • STM32 HAL库函数学习 I2C篇

    本篇内容讲述STM32的硬件IIC功能。硬件IIC的使用在F1系列上可能会有问题。本次使用的测试平台是H7,用于AT24C02芯片的读写正常,暂不清楚在其他芯片上使用是否正常。 1、HAL_StatusTypeDef HAL_I2C_Init (I2C_HandleTypeDef * hi2c) I2C初始化函数,使用CubeMx生成。需要选中I2C硬件指定的IO口。

    2023年04月08日
    浏览(13)
  • STM32 HAL FreeRTOS 硬件I2C 使用

    因为某个项目想要颜色识别,去识别球的颜色,但是又不想多来个摄像头,所以想尝试一下颜色传感器的方案。但是经过尝试,HAL库生成的 FreeRTOS 硬件 I2C 读写一直在报错。 刚好手头上有九轴陀螺仪的例程代码。最后用FreeRTOS 硬件 I2C 读取数据。 这里提到了阻塞式 HAL 函数(

    2024年02月20日
    浏览(19)
  • 【stm32】软件I2C读写MPU6050

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

    2024年04月26日
    浏览(20)
  • 【STM32 CubeMX】I2C中断方式与DMA方式

    在STM32 CubeMX环境中,I2C(Inter-Integrated Circuit)通信协议的实现可以采用中断方式或DMA(Direct Memory Access)方式。中断方式通过触发中断来处理数据传输,而DMA方式则利用直接内存访问技术来实现数据传输,减轻了CPU的负担。在选择I2C通信方式时,开发者需要根据具体的应用需

    2024年02月20日
    浏览(17)
  • STM32之I2C总线知识和HAL库函数

    一、 I2C总线知识 I2C总线物理拓扑结构 I2C 总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控制,来 产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时,这两根线一般被上面所接

    2024年02月21日
    浏览(19)
  • 【STM32】STM32学习笔记-软件I2C读写MPU6050(33)

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

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

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

    2024年01月25日
    浏览(22)
  • 【STM32学习】——I2C通信协议&MPU6050姿态传感器&软件I2C读写MPU6050

    ​   目录 前言 一、I2C通信协议 1.简介 2.硬件电路设计 3.I2C时序(软件)

    2024年02月16日
    浏览(20)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包