【蓝桥杯嵌入式拓展板】—I2C读写EEPROM详解

关于蓝桥杯嵌入式板子的I2C,如果你以前没有接触过I2C通信。
重点:

  1. 懂得通过电路图判断出I2C设备的地址
  2. 会看I2C读写时序图。
  3. 底层驱动,考试会给你

当然,如果你真的是0基础,还有救!

《【STM32-I2C学习总结】STM32:硬件-IIC详解 , 固件库编程 , 手把手教你实现IIC》这里是我以前写的,硬件实现I2C的一个文章,文章末尾有软件实现I2C的方法,硬件都会了,软件就很简单了

传送门:https://blog.csdn.net/qq_45689790/article/details/113725196?spm=1001.2014.3001.5501

不得不说,官方给了你I2C的底层驱动,写读取函数,参考手册,看时序图,真的是太简单了。

一、硬件原理图

在这里插入图片描述
通过原理图,判断 [SCL->PB6][PB7->SDA]
在这里插入图片描述
板载EEPROM 为2k ,E0~E2接地均为0,因此设备地址 0xA0,当然 读写标志位也是跟在设备地址的后面

  1. 读命令:设备地址 0xA0 + 1 = 0xA1
  2. 写命令:设备地址 0xA0 + 0 = 0xA0

这点在编程的时候会有所体现,想知道具体细节,翻到上面,找传送门。

二、实现读写函数
1、void Byte_Write(uint8_t Write_addr,uint8_t data)
在这里插入图片描述

void Byte_Write(uint8_t Write_addr,uint8_t data)
{
	I2CStart(); 				//1、发送开始信号
	I2CSendByte(0xA0);			//2、发送设备地址  写命令 0xA0 + 0 = 0xA0
	I2CWaitAck();				//3、等待响应
	I2CSendByte(Write_addr);	//4、等待响应 发送要写入EEPROM的地址
	I2CWaitAck();				//5、等待响应
	I2CSendByte(data);			//6、发送要写入的地址
	I2CWaitAck();				//7、等待响应
	I2CStop();					//8、发送停止信号
}

2、uint8_t Byte_Read(uint8_t Read_Addr)
在这里插入图片描述
我好像标错了,详见代码备注

uint8_t Byte_Read(uint8_t Read_Addr)
{
	uint8_t data = 0;
	I2CStart();						//1、发送开始信号		
	I2CSendByte(0xA0);				//2、发送设备地址  先写操作,0xA0	+ 0 = 0xA0
	I2CWaitAck();					//3、等待响应	
	I2CSendByte(Read_Addr);			//4、写入要读的地址,告诉EEPROM等下需要返回哪个值
	I2CWaitAck();					//5、等待响应
	
	I2CStart();						//6、发送开始信号,接受EEPROM返回的数据
	I2CSendByte(0xa1);				//7、发送设备地址,读操作 0xA0 + 1 =0xA1
	I2CWaitAck();					//8、等待响应
	data = I2CReceiveByte();		//9、读出数据
	I2CSendNotAck();				//10、发送非应答信号,准备停止
	I2CStop();						//11、停止信号
	
	return data;
}

3Buffer_Write(uint8_t *_pWriteBuf ,uint8_t Write_Addr,uint8_t Write_Num)

void Buffer_Write(uint8_t *_pWriteBuf,uint8_t Write_Addr,uint8_t Write_Num)
{
//最多连续写8个  注意地址对齐
	uint8_t i ;
	
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(Write_Addr);
	I2CWaitAck();
	
	for(i = 0;i < Write_Num;i++)
	{
		I2CSendByte(_pWriteBuf[i]);
		I2CWaitAck();
	}
	I2CStop();
}

4、void Buffer_Read(uint8_t *_pReadBuf,uint8_t Read_Addr,uint8_t Read_Num)

自己写把,尝试一下

在这里插入图片描述
有问题,可以留言

欢迎交流探讨

/更新*/void Buffer_Read(uint8_t *_pReadBuf,uint8_t Read_Addr,uint8_t Read_Num)
{
uint8_t data = 0;
uint8_t i ;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();

I2CSendByte(Read_Addr);
I2CWaitAck();

I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();

for(i = 0; i < Read_Num; i++)
{
	_pReadBuf[i] = I2CReceiveByte();

	if(i!=Read_Num-1)
	{
		I2CSendAck();
	}
	else
	{
		I2CSendNotAck();
	}
}
I2CStop();

}
/———————————————— 更新——————————————————/

有读者私信,连续读取写不出来,参考如下:

void Buffer_Read(uint8_t *_pReadBuf,uint8_t Read_Addr,uint8_t Read_Num)
{
	uint8_t data = 0;
	uint8_t i ;
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	
	I2CSendByte(Read_Addr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	
	for(i = 0; i < Read_Num; i++)
	{
		_pReadBuf[i] = I2CReceiveByte();
	
		if(i!=Read_Num-1)
		{
			I2CSendAck();
		}
		else
		{
			I2CSendNotAck();
		}
	}
	I2CStop();
}
  • 10
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
您好!对于在嵌入式系统中使用I2C总线读写EEPROM,您可以通过HAL库来实现。以下是一个基本的示例代码: 1. 首先,您需要在STM32的CubeMX工具中配置I2C外设和GPIO引脚。 2. 在代码中包含必要的头文件: ```c #include "stm32f4xx_hal.h" #include "stm32f4xx_hal_i2c.h" ``` 3. 初始化I2C外设: ```c I2C_HandleTypeDef hi2c1; void I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; // I2C总线速度 hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { // 初始化失败处理 Error_Handler(); } } ``` 4. 实现EEPROM的写操作函数: ```c #define EEPROM_ADDRESS 0xA0 // EEPROM的I2C地址 void EEPROM_Write(uint16_t address, uint8_t *data, uint16_t size) { HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS, address, I2C_MEMADD_SIZE_16BIT, data, size, HAL_MAX_DELAY); } ``` 5. 实现EEPROM的读操作函数: ```c void EEPROM_Read(uint16_t address, uint8_t *data, uint16_t size) { HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDRESS, address, I2C_MEMADD_SIZE_16BIT, data, size, HAL_MAX_DELAY); } ``` 6. 在主函数中调用这些函数进行读写操作: ```c int main(void) { // 初始化硬件和外设 I2C1_Init(); // 写入数据到EEPROM uint8_t writeData[] = {0x01, 0x02, 0x03}; EEPROM_Write(0x0000, writeData, sizeof(writeData)); // 从EEPROM读取数据 uint8_t readData[3]; EEPROM_Read(0x0000, readData, sizeof(readData)); // 处理读取的数据 // 其他代码 while (1) { // 主循环 } } ``` 这是一个基本的示例代码,您可以根据您的具体需求进行修改和扩展。希望对您有帮助!如果您还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Successful 、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值