参考博客连接:
1、存储芯片24C02的总结
2、蓝桥杯嵌入式(G431RBT6): EEPROM进阶学习
3、一bit,一Byte,一KB,一MB,到底是个什么概念,有多大,可以做什么事情?
链接:https://www.zhihu.com/question/487a932289/answer/3329964107
一、硬件原理图
两个设备共同接在同一个I2C总线上,但是仅测试24C02的功能,暂时可以不用管,当他该I2C总线只接了24C02芯片就好。
二、软件工程创建
使用数据包中的液晶显示屏LCD的例程,直接用他的工程进行测试就好。
将数据包中的MDK5_LCD_HAL整个工程文件夹复制,然后粘贴到桌面,然后将数据包中GPIO_I2C_HAL中的I2C文件复制并粘贴桌面的MDK5_LCD_HAL文件夹的Src、Inc文件夹中。这一步骤就是利用数据包中液晶显示屏的例程,然后加上数据包中的I2C文件。
三、代码示例
.c文件如下:
//************ EEPROM的源文件 ************//
#include "AT24C02.h"
// AT24C02 写 一个8位数据
// 8位数据(uint8_t类型:0-255)
void EEPROM_Write(uint8_t address,uint8_t dat)
{
I2CStart(); // I2C起始信号
I2CSendByte(AT24C02_Address_W); // I2C发送从机地址 (写)
I2CWaitAck(); // I2C等待从机应答
I2CSendByte(address); // I2C发送EEPROM片内单元地址给从机
I2CWaitAck(); // I2C等待从机应答
I2CSendByte(dat); // I2C发送要写入的数据到EEPROM片内单元地址
I2CWaitAck(); // I2C等待从机应答
I2CStop(); // I2C停止信号
}
// AT24C02 读 一个8位数据
// 8位数据(uint8_t类型:0-255)
uint8_t EEPROM_Read(uint8_t address)
{
uint8_t Temp;
I2CStart(); // I2C起始信号
I2CSendByte(AT24C02_Address_W); // I2C发送从机地址 (写)
I2CWaitAck(); // I2C等待从机应答
I2CSendByte(address); // I2C发送EEPROM片内单元地址给从机
I2CWaitAck(); // I2C等待从机应答
I2CStop(); // I2C停止信号
I2CStart(); // I2C起始信号
I2CSendByte(AT24C02_Address_R); // I2C发送从机地址 (读)
I2CWaitAck(); // I2C等待从机应答
Temp = I2CReceiveByte(); // I2C读取一字节(一个8位数据)
I2CSendNotAck();
I2CStop(); // I2C停止信号
return Temp;
}
// 全片擦除,2Kb内存全写255
void EEPROM_Full_Chip(void)
{
for(uint8_t loop=0;loop<=255;loop++)
{
EEPROM_Write(0x00+loop,(uint8_t)255);
if(loop==255) break; // 莫名的bug,如果不break,loop从0到255之后又回到0继续循环
}
}
.h文件如下:
#ifndef _AT24C02_H_
#define _AT24C02_H_
#include "i2c_hal.h"
#include "stdio.h"
#define AT24C02_Address_W 0xA0 // I2C地址 写 操作
#define AT24C02_Address_R 0xA1 // I2C地址 读 操作
// AT24C02 写 一个8位数据
// 8位数据(uint8_t类型:0-255)
void EEPROM_Write(uint8_t address,uint8_t dat);
// AT24C02 读 一个8位数据
// 8位数据(uint8_t类型:0-255)
uint8_t EEPROM_Read(uint8_t address);
// 全片擦除,2Kb内存全写255
void EEPROM_Full_Chip(void);
#endif
四、EEPROM应用
(1)实验1
实验内容:将芯片内256个空间即0x00-0xFF,全部读取一遍并显示在显示屏上。
测试代码如下:
char CH[20];
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();
/* USER CODE BEGIN 2 */
LCD_Init(); // LCD初始化
HAL_Delay(100);;C
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
LCD_SetBackColor(Black); // 设置背景色
LCD_SetTextColor(White); // 设置字体色
LCD_Clear(Black); // 清屏
HAL_Delay(100);
I2CInit(); // I2C初始化,即初始化了EEPROM
while (1)
{
/* USER CODE END WHILE */
for(uint8_t loop=0;loop<=255;loop++) // 256个存储空间
{
LCD_DisplayStringLine(Line2, (unsigned char *)" Hello,world. ");
sprintf(CH," AT24C02:%X,%d ",0x00+loop,EEPROM_Read(0x00+loop));
LCD_DisplayStringLine(Line4, (unsigned char *)CH);
HAL_Delay(200);
}
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
(2)实验2
实验内容:先将EEPROM中256个存储空间全部存储数据 0 ,并全部读取一遍并显示在显示屏上。
使用到的关键函数之一:EEPROM_Full_Chip();
// 全片擦除,2Kb内存全写255
void EEPROM_Full_Chip(void)
{
for(uint8_t loop=0;loop<=255;loop++)
{
EEPROM_Write(0x00+loop,(uint8_t)0); // 这里这个 0 ,就是要写入的数据
if(loop==255) break; // 莫名的bug,如果不break,loop从0到255之后又回到0继续循环
}
}
测试代码如下:
char CH[20];
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();
/* USER CODE BEGIN 2 */
LCD_Init(); // LCD初始化
HAL_Delay(100);;C
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
LCD_SetBackColor(Black); // 设置背景色
LCD_SetTextColor(White); // 设置字体色
LCD_Clear(Black); // 清屏
HAL_Delay(100);
I2CInit(); // I2C初始化,即初始化了EEPROM
EEPROM_Full_Chip(); // 全片存储空间写入数据 0 ,数据内容在函数内修改
while (1)
{
/* USER CODE END WHILE */
for(uint8_t loop=0;loop<=255;loop++) // 256个存储空间
{
LCD_DisplayStringLine(Line2, (unsigned char *)" Hello,world. ");
sprintf(CH," AT24C02:%X,%d ",0x00+loop,EEPROM_Read(0x00+loop));
LCD_DisplayStringLine(Line4, (unsigned char *)CH);
HAL_Delay(200);
}
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
(3)实验3
实验内容:默认第一个存储空间上的数据为0,然后利用EEPROM掉电不会丢失数据的特性,记录板子上电的次数。
char CH[20];
uint8_t Times=0;
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();
/* USER CODE BEGIN 2 */
LCD_Init(); // LCD初始化
HAL_Delay(100);;C
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
LCD_SetBackColor(Black); // 设置背景色
LCD_SetTextColor(White); // 设置字体色
LCD_Clear(Black); // 清屏
HAL_Delay(100);
I2CInit(); // I2C初始化,即初始化了EEPROM
Times = EEPROM_Read(0x00); // 先读
EEPROM_Write(0x00,Times+1); // 然后将上次记录的上电次数加一后再存回EEPROM中
while (1)
{
/* USER CODE END WHILE */
LCD_DisplayStringLine(Line2, (unsigned char *)" Hello,world. ");
sprintf(CH," AT24C02:%d,%d ",0x00,EEPROM_Read(0x00));
LCD_DisplayStringLine(Line4, (unsigned char *)CH); // 将上电次数显示出来
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}