【STM32L496】使用HAL库实现I2C写入/读取数据(M24C32)

这篇具有很好参考价值的文章主要介绍了【STM32L496】使用HAL库实现I2C写入/读取数据(M24C32)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

I2C原理与配置

IIC原理超详细讲解—值得一看
【嵌入式硬件芯片开发笔记】EEPROM芯片M24C32配置流程
STM32硬件I2C与软件模拟I2C超详解

M24C32芯片了解

实现通信功能的芯片为M24C32,对此,芯片手册上第一页就有对其概括描述。

Automotive 32-Kbit serial I²C bus EEPROM with 1 MHz clock

启动/停止条件:当串行时钟(SCL)位于高电平状态,串行数据(SDA)位于下降沿时,M24C32开始接收数据;串行数据(SDA)位于上升沿时,M24C32停止接收数据。
数据输入:SCL上升沿时SDA进行采样。SDA必须在SCL的上升沿期间保持稳定,且当SCL被驱动为低电平时,SDA才改变电平状态。
设备寻址:设备选择代码由一个4位设备类型标识符和一个3位芯片使能地址(E2、E1、E0)组成,设备类型标识符中,1010b为选择存储器(to select the memory),1011b为选择标识页(to select the Identification page)。
在一条I2C总线上最多可连接8个存储器设备。每个片上使能输入(E2、E1、E0)上都有一个唯一的3位代码;当收到设备选择代码时,只有当芯片使能地址与E2、E1、E0输入解码值相同时,存储器设备才会响应。
第八位是读写位,1=read,0=write.
i2c读取24aa256数据 csdn,stm32,单片机,嵌入式硬件

读操作

看到Current Address Read这行,它是一次读当前地址数据的过程。在开始信号发出后,主设备会发出一个7位片选信号,第八位是设备读/写模式,ACK是从设备应答信号,当从设备发来一个应答信号时,主设备会发送数据,数据传输完成后,从设备不需要发应答信号,最后是主设备发送停止位结束这一次的读操作。Random Address Read是随机地址读操作,而后面的Sequential Current Read就是按顺序读了。Random Address ReadSequential Random Read模式下,需要设备发送地址才能读,所以有两次发送地址的序列。
i2c读取24aa256数据 csdn,stm32,单片机,嵌入式硬件
读指令后,若总线发送额外的时钟脉冲并确认每个传输的数据字节,则设备可按顺序输出下一字节。若终止字节流,总线必须不确认最后一个字节,并且必须生成一个停止条件。
读模式下确认:对于所有读指令,设备在发送每个字节后,在第9位时间内等待一个确认标识符,若总线主设备不发送确认(主驱动器SDA在第9位时间为高),则设备终止数据传输并进入待机模式。

写操作

看到Byte Wirte这行,它是一次写操作过程。在开始信号发出后,主设备会发出一个7位片选信号,第八位是设备读/写模式,ACK是从设备应答信号,当从设备发来一个应答信号时,主设备会给从设备发送一个字节地址,如果从设备发来应答信号,主设备此时会再发一次字节地址,当从设备应答后,主设备才会发送数据,数据传输完成后,从设备发来应答信号,最后是主设备发送停止位结束这一次的写操作。Page Write是连续写操作,前面的发片选和地址和Byte Write一样,不一样的是主设备会一直发数据。
i2c读取24aa256数据 csdn,stm32,单片机,嵌入式硬件

HAL库配置及初始化

根据原理图和芯片手册配置相关参数
i2c读取24aa256数据 csdn,stm32,单片机,嵌入式硬件

i2c读取24aa256数据 csdn,stm32,单片机,嵌入式硬件i2c读取24aa256数据 csdn,stm32,单片机,嵌入式硬件
配置完成后,会生成一个i2c的句柄,当我们需要对i2c进行读写等操作时,对hi2c取地址,它就会调用HAL库中的寄存器回调,然后实现i2c规范中的功能(比如说init、status、mode、errcode这种)。

I2C_HandleTypeDef hi2c1;

部分代码

一开始列出的大概框架如下。

int i2c_write(const unsigned char *pwbuf, const unsigned short wbuflen);

int i2c_read(unsigned char *prBuf, const unsigned short *rbuflen);

void main(void)
{
	//write
	unsigned short wBuflen = 128;
	unsigned char wBuf[wBuflen] = {0};
	for(unsigned char i =0 ;i<wBuflen;i++)
	{
		wBuf[i] = i;
	}	
	int wret = i2c_write(wBuf, wBuflen);

	//read
	unsigned char rBuf[128] = {0};
	unsigned short rlen = 128;
	int rret = i2c_read(rBuf, rlen);
}

因为之前设置的是七位设备地址(第八位是读写位),所以在读写时需要左移一位,HAL库中I2C的读写存储器比较方便,只需要调用HAL_I2C_Mem_WriteHAL_I2C_Mem_Read函数即可。

int i2c_write(uint8_t devadd,uint16_t memadd,uint16_t memsize,uint8_t *pwbuf, const unsigned short wbuflen)
{
	devadd = (devadd<<1)&0xFF;
	if(pwbuf != NULL || wbuflen != 0)
	{
		if(HAL_I2C_Mem_Write(&hi2c1,devadd,memadd,memsize,pwbuf, wbuflen,0xFFFF)==HAL_OK)
		{
			return 1;
		}
	}
	else
	{
		return 0;
	}
}

int i2c_read(uint8_t devadd,uint16_t memadd,uint16_t memsize,uint8_t *prbuf, const unsigned short rbuflen)
{
	devadd = (devadd<<1)&0xFF;
	
	if(prbuf != NULL || rbuflen != 0)
	{
		if(HAL_I2C_Mem_Read(&hi2c1, devadd, memadd,memsize, prbuf,rbuflen,0xFFFF)==HAL_OK)
		{
			return 1;
		}
	}
	else
	{
		return 0;
	}
}

这两个函数在stm32l4xx_hal_i2c.c文件下

HAL_StatusTypeDef 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)
HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
                                   uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

实际实现示例,当i2c开始写的时候,因为是一个字一个字地写,所以存储器地址每次加i,即0x0000+i,并且需要延迟一会,否则太快了芯片来不及存数据。
读就直接读,从0x0000开始读。

void I2C_ReadorWrite(uint8_t flag)
{
	if(flag == 1)
	{
		//write
		unsigned char i;
		uint8_t dat=0;
		if(HAL_I2C_IsDeviceReady(&hi2c1,M24C32_ADD<<1,2,0x00ff)==HAL_OK)
		{
			i=0;
		}
		unsigned short wBuflen = 128;
		for(i = 0;i<wBuflen;i++)//i2c clear
		{
			dat=0;
			i2c_write(M24C32_ADD,0x0000+i,I2C_MEMADD_SIZE_16BIT,&dat,1);
			delay_ms(10);
		}	
		for(i = 0;i<wBuflen;i++)//i2c write
		{
			dat=i;
			i2c_write(M24C32_ADD,0x0000+i,I2C_MEMADD_SIZE_16BIT,&dat,1);
			delay_ms(10);
		}	
	}
	else if(flag == 0)
	{
		//read
		unsigned char rBuf[128] = {0};
		unsigned short rlen = 128;
		i2c_read(M24C32_ADD,0x0000,I2C_MEMADD_SIZE_16BIT,rBuf,rlen);
//	for(i=0;i<rlen;i++)
//	{
//		printf("rBuf[%d] = %02X \n",i,rBuf[i]);
//	}
		//uint16_t re_dat=0;
		//i2c_write(M24C32_ADD,0x0000,I2C_MEMADD_SIZE_16BIT,&dat,1);
		//delay_ms(55);

		//i2c_write(M24C32_ADD,0x0000,I2C_MEMADD_SIZE_16BIT,&dat,1);
		//delay_ms(50);
		//i2c_read(M24C32_ADD,0x0000,I2C_MEMADD_SIZE_16BIT,&re_dat,1);
	}
}

遇到的问题

要了解手头这个芯片的i2c地址位数,一般都是7位,在读写时不能忘记移位。
在存储数据时记得调用delay,否则会出现输出的数据有漏掉的情况。
除了这个EEPROM芯片还有一个LP87702芯片的,在熟悉中。文章来源地址https://www.toymoban.com/news/detail-768449.html

到了这里,关于【STM32L496】使用HAL库实现I2C写入/读取数据(M24C32)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • STM32之I2C总线知识和HAL库函数

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

    2024年02月21日
    浏览(44)
  • STM32基于CubeMX与HAL库的I2C应用

    1.1 物理层         I2C协议和摩托罗拉公司的SPI协议一样,是一种通讯协议。串行外围设备接口,是一种高速全双工的通信总线,是由 Phiilps 公司开发的。由于它引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内

    2024年02月21日
    浏览(67)
  • STM32学习笔记(十)丨I2C通信(使用I2C实现MPU6050和STM32之间通信)

    ​  本次课程采用单片机型号为STM32F103C8T6。(鉴于笔者实验时身边只有STM32F103ZET6,故本次实验使基于ZET6进行的) ​  课程链接:江协科技 STM32入门教程   往期笔记链接:   STM32学习笔记(一)丨建立工程丨GPIO 通用输入输出   STM32学习笔记(二)丨STM32程序调试

    2024年01月19日
    浏览(57)
  • STM32 HAL库硬I2C的TOF050C模块

    最近在倒腾毕业设计,需要用到TOF050C,但是现有的案例都是软IIC,并且还是基于STM32F103的,笔者用的STM32F767,没有GPIO-CRH寄存器。问题来了,如果我每次都要去看寄存器手册属实费时间,这不干脆直接用硬IIC? 于是乎,打开了TOF050C手册,硬啃! 这手册好在它有工作流程图,

    2024年02月14日
    浏览(58)
  • STM32设置为I2C从机模式(HAL库版本)

    我之前出过一篇关于STM32设置为I2C从机的博客,现在应粉丝要求,出一篇HAL库版本的I2C从机编程。 基于官方库版本的可以看下我之前发的文章:STM32设置为I2C从机模式 测试芯片:STM32F103RCT6 测试方法:用一个USB转I2C的工具接到STM32的I2C引脚上,通过上位机工具进行读写操作。如

    2024年02月12日
    浏览(62)
  • 【STM32CubeMX+HAL库】I2C详解+读写EEPROM

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

    2024年02月03日
    浏览(53)
  • Clion开发STM32之HAL库I2C封装(基础库)

    引用参考: Clion开发STM32之HAL库GPIO宏定义封装(最新版)

    2024年02月13日
    浏览(46)
  • 01_STM32软件+硬件I2C读取MPU6050(HAL库)

    目录 1、I2C简介 2、I2C时序单元 2.1 起始条件 2.2 终止条件 2.3 发送一个字节 2.4 接收一个字节 2.5 发送应答 2.6 接收应答 3、I2C完整时序 3.1 指定地址写一个字节 3.2 当前地址读一个字节 3.2 指定地址读一个字节 4、简单软件I2C代码(HAL) 4.1 软件I2C 4.2 软件I2C读MPU6050寄存器 5、ST

    2024年04月17日
    浏览(47)
  • 【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪

    MPU-6000(6050)为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时间轴之差的问题,减少了大量的封装空间。当连接到三轴磁强计时,MPU-60X0提供完整的9轴运动融合输出到其主I2C或SPI端口(SPI仅在MPU-6000上可用)。 寄存器地址 寄存器内容 0X3B

    2024年02月16日
    浏览(50)
  • 【STM32】AT24C256硬件I2C读写,基于HAL库

    目录 一、简单介绍 二、配置工程 打开CubeMX,配置时钟,调试接口,工程名,目录等 配置iic 配置串口用于显示信息 三、硬件连接 四、代码编写 一、随机写入一个字节 测试代码 波形如下 代码编写 二、连续写入 代码如下 三、随机读取 测试代码 波形如下 代码编写 四、连续

    2024年02月03日
    浏览(48)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包