STM32MX配置EEPROM(AT24C02)------保姆级教程

这篇具有很好参考价值的文章主要介绍了STM32MX配置EEPROM(AT24C02)------保姆级教程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

————————————————————————————————————
⏩ 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的大三学生。
⏩最近在开发一个STM32H723ZGT6的板子,使用STM32CUBEMX做了很多驱动,包括ADC、UART、RS485、EEPROM(IIC)、FLASH(SPI)等等。
⏩本篇文章对STM32CUBEMX配置RRPROM(AT24C02)做一个详细的使用教程。
⏩感谢你的阅读,不对的地方欢迎指正。
————————————————————————————————————

AT24C02工作原理

引脚封装
STM32MX配置EEPROM(AT24C02)------保姆级教程,STM32CEBUMX,stm32,嵌入式硬件,单片机
SCL 串行时钟
AT24C02串行时钟输入管脚用于产生器件所有数据发送或接收的时钟,这是一个输入管脚。
SDA 串行数据/地址
AT24C02 双向串行数据/地址管脚用于器件所有数据的发送或接收,SDA 是一个开漏输出管脚,可与其它开漏输出或集电极开路输出进行线或(wire-OR)。
A0、A1、A2 器件地址输入端
这些输入脚用于多个器件级联时设置器件地址,当这些脚悬空时默认值为0。当使用AT24C02 时最大可级联8个器件。如果只有一个AT24C02被总线寻址,这三个地址输入脚(A0、A1、A2 )可悬空或连接到Vss or GND。
WP 写保护
如果WP管脚连接到Vcc,所有的内容都被写保护只能读。当WP管脚连接到Vss or GND 或悬空允许器件进行正常的读/写操作。

具体原理可以参考
AT24C02芯片使用介绍

实验环境

  • USB转串口
  • AT24C02
  • STM32H723ZGT6开发板

硬件连接:
STM32MX配置EEPROM(AT24C02)------保姆级教程,STM32CEBUMX,stm32,嵌入式硬件,单片机

我这里接的是PB8和PB9

MX配置

板子、时钟、调试之类的配置就不说了,具体可以看看这篇:
STM32CUBEMX配置ADC(多通道轮询)(STM32H7)–保姆级教程
这里只说一下IIC的具体配置
根据你的连接自己配置
STM32MX配置EEPROM(AT24C02)------保姆级教程,STM32CEBUMX,stm32,嵌入式硬件,单片机
我的引脚是PB8,PB9
STM32MX配置EEPROM(AT24C02)------保姆级教程,STM32CEBUMX,stm32,嵌入式硬件,单片机

驱动代码

at24C02.h
我使用两个共用体去存储浮点型和整形的数据,这是最简单的方法。

#ifndef AT24C02_H_
#define AT24C02_H_

#include "stm32H7xx_hal.h" //HAL库文件声明

#define        AT24C02_ADDR_WRITE          0xA0    // 写命令
#define        AT24C02_ADDR_READ           0xA1    // 读命令

#define ADDR_24LCxx_Write 0xA0 //AT24C02写地址
#define ADDR_24LCxx_Read 0xA1  //AT24C02读地址
#define BufferSize 256         //读写缓冲区大小

union float_union{
	float float_write_dat;        // 浮点数占4个字节
	double double_write_dat;    // 双精度浮点数占8个字节
	uint8_t buf[8];                // 定义 8个字节 的空间
};
union int_union{
	int int_dat; //整型数占四个字节
	uint8_t buf[4];    //定义4个字节的空间	
};

uint8_t At24c02_Write_Byte(uint16_t addr, uint8_t* dat);  //AT24C02任意地址写一个字节数据
uint8_t At24c02_Read_Byte(uint16_t addr, uint8_t* read_buf);//AT24C02任意地址读一个字节数据
uint8_t At24c02_Write_Amount_Byte(uint16_t addr, uint8_t* dat, uint16_t size);// AT24C02任意地址连续写多个字节数据
uint8_t At24c02_Read_Amount_Byte(uint16_t addr, uint8_t* recv_buf, uint16_t size);//AT24C02任意地址连续读多个字节数据
#endif

at24c02.c

#include "at24c02.h"
#include "i2c.h"
/**
 * @brief        AT24C02任意地址写一个字节数据
 * @param        addr —— 写数据的地址(0-255)
 * @param        dat  —— 存放写入数据的地址
 * @retval       成功 —— HAL_OK
*/
uint8_t At24c02_Write_Byte(uint16_t addr, uint8_t* dat)
{
    HAL_StatusTypeDef result;
    result = HAL_I2C_Mem_Write(&hi2c1, AT24C02_ADDR_WRITE, addr, I2C_MEMADD_SIZE_8BIT, dat, 1, 0xFFFF);
    HAL_Delay(5);    // 写一个字节,延迟一段时间,不能连续写
    return result;
}
 
/**
 * @brief        AT24C02任意地址读一个字节数据
 * @param        addr —— 读数据的地址(0-255)
 * @param        read_buf —— 存放读取数据的地址
 * @retval       成功 —— HAL_OK
*/
uint8_t At24c02_Read_Byte(uint16_t addr, uint8_t* read_buf)
{
    return HAL_I2C_Mem_Read(&hi2c1, AT24C02_ADDR_READ, addr, I2C_MEMADD_SIZE_8BIT, read_buf, 1, 0xFFFF);
}
 
/**
 * @brief        AT24C02任意地址连续写多个字节数据
 * @param        addr —— 写数据的地址(0-255)
 * @param        dat  —— 存放写入数据的地址
 * @retval       成功 —— HAL_OK
*/
uint8_t At24c02_Write_Amount_Byte(uint16_t addr, uint8_t* dat, uint16_t size)
{
    uint8_t i = 0;
    uint16_t cnt = 0;        // 写入字节计数
    HAL_StatusTypeDef result;    // 返回是否写入成功
 
    /* 对于起始地址,有两种情况,分别判断 */
    if(0 == addr % 8)
    {
        /* 起始地址刚好是页开始地址 */
        /* 对于写入的字节数,有两种情况,分别判断 */
        if(size <= 8)
        {
            // 写入的字节数不大于一页,直接写入
            result = HAL_I2C_Mem_Write(&hi2c1, AT24C02_ADDR_WRITE, addr, I2C_MEMADD_SIZE_8BIT, dat, size, 0xFFFF);
            HAL_Delay(20);    // 写完八个字节(最多八个字节),延迟久一点
            return result;
        }
        else
        {
            // 写入的字节数大于一页,先将整页循环写入
            for(i = 0; i < size/8; i++)
            {
                HAL_I2C_Mem_Write(&hi2c1, AT24C02_ADDR_WRITE, addr, I2C_MEMADD_SIZE_8BIT, &dat[cnt], 8, 0xFFFF);
                // 一次写入了八个字节,延迟久一点
                HAL_Delay(20);    // 写完八个字节,延迟久一点
                addr += 8;
                cnt += 8;
            }
            // 将剩余的字节写入
            result = HAL_I2C_Mem_Write(&hi2c1, AT24C02_ADDR_WRITE, addr, I2C_MEMADD_SIZE_8BIT, &dat[cnt], size - cnt, 0xFFFF);
            HAL_Delay(20);    // 写完八个字节(最多八个字节),延迟久一点
            return result;
        }
    }
    else
    {
        /* 起始地址偏离页开始地址 */
        /* 对于写入的字节数,有两种情况,分别判断 */
        if(size <= (8 - addr%8))
        {
            /* 在该页可以写完 */
            result = HAL_I2C_Mem_Write(&hi2c1, AT24C02_ADDR_WRITE, addr, I2C_MEMADD_SIZE_8BIT, dat, size, 0xFFFF);
            HAL_Delay(20);    // 写完八个字节(最多八个字节),延迟久一点
            return result;
        }
        else
        {
            /* 该页写不完 */
            // 先将该页写完
            cnt += 8 - addr%8;
            HAL_I2C_Mem_Write(&hi2c1, AT24C02_ADDR_WRITE, addr, I2C_MEMADD_SIZE_8BIT, dat, cnt, 0xFFFF);
            HAL_Delay(20);    // 写完八个字节(最多八个字节),延迟久一点
            addr += cnt;
 
            // 循环写整页数据
            for(i = 0;i < (size - cnt)/8; i++)
            {
                HAL_I2C_Mem_Write(&hi2c1, AT24C02_ADDR_WRITE, addr, I2C_MEMADD_SIZE_8BIT, &dat[cnt], 8, 0xFFFF);
                HAL_Delay(20);    // 写完八个字节,延迟久一点
                addr += 8;
                cnt += 8;
            }
            // 将剩下的字节写入
            result = HAL_I2C_Mem_Write(&hi2c1, AT24C02_ADDR_WRITE, addr, I2C_MEMADD_SIZE_8BIT, &dat[cnt], size - cnt, 0xFFFF);
            HAL_Delay(20);    // 写完八个字节(最多八个字节),延迟久一点
            return result;
        }            
    }
}
 
/**
 * @brief        AT24C02任意地址连续读多个字节数据
 * @param        addr —— 读数据的地址(0-255)
 * @param        dat  —— 存放读出数据的地址
 * @retval       成功 —— HAL_OK
*/
uint8_t At24c02_Read_Amount_Byte(uint16_t addr, uint8_t* recv_buf, uint16_t size)
{
    return HAL_I2C_Mem_Read(&hi2c1, AT24C02_ADDR_READ, addr, I2C_MEMADD_SIZE_8BIT, recv_buf, size, 0xFFFF);
}


main.c

//AT24C02
uint8_t WriteBuffer[BufferSize] = {0};//AT24C02写缓冲区
uint8_t ReadBuffer[BufferSize] = {0}; //AT24C02读缓冲区

//测试
    // 单个字节 读写测试
    uint8_t simple_write_dat = 0xa5;    // 一个字节
    uint8_t simple_recv_buf = 0;
 
    if(HAL_OK == At24c02_Write_Byte(10, &simple_write_dat)){
        printf("Simple data write success \r\n");
    } else {
        printf("Simple data write fail \r\n");
    }
    
    HAL_Delay(50);      // 写一次和读一次之间需要短暂的延时
    
    if(HAL_OK == At24c02_Read_Byte(10, &simple_recv_buf)){
        printf("Simple data read success, recv_buf = 0x%02X \r\n", simple_recv_buf);
    } else {
        printf("Simple data read fail \r\n");
    }
    printf("--------------------- \r\n");
    // 单个字节读写 测试结束
    
    // 浮点数 读写测试
    union float_union send_float_data;    // 用来发送
    union float_union rev_float_data;     // 用来接收
    union int_union   send_int_data;      //发送
		union int_union   rev_int_data;       //接收
    // 先测试第一个 浮点数
    send_float_data.float_write_dat = 3.1415f;
    if(HAL_OK == At24c02_Write_Amount_Byte(20, send_float_data.buf, 4)){
        printf("Float data write success \r\n");
    } else {
        printf("Float data write fail \r\n");
    }
    HAL_Delay(50);
    if(HAL_OK == At24c02_Read_Amount_Byte(20, rev_float_data.buf, 4)){
        // 默认输出六位小数
        printf("Float data read success, recv_buf = %f \r\n", rev_float_data.float_write_dat);
    } else {
        printf("Float data read fail \r\n");
    }
    // 测试第二个 双精度浮点数
    send_float_data.double_write_dat = 3.1415f;
    if(HAL_OK == At24c02_Write_Amount_Byte(20, send_float_data.buf, 8)){
        printf("Double data write success \r\n");
    } else {
        printf("Double data write fail \r\n");
    }
    HAL_Delay(50);
    if(HAL_OK == At24c02_Read_Amount_Byte(20, rev_float_data.buf, 8)){
        // 最多15位小数
        printf("Double data read success, recv_buf = %.15f \r\n", rev_float_data.double_write_dat);
    } else {
        printf("Double data read fail \r\n");
    }
    printf("--------------------- \r\n");
    // 浮点数读写测试 测试结束
		// 测试第三个 整形数
		send_int_data.int_dat = 2147483647;
    if(HAL_OK == At24c02_Write_Amount_Byte(30,send_int_data.buf, 4)){
        printf("int data write success \r\n");
    } else {
        printf("int data write fail \r\n");
    }
    HAL_Delay(50);
    if(HAL_OK == At24c02_Read_Amount_Byte(30, rev_int_data.buf, 4)){
        printf("int data read success, recv_buf = %d \r\n", rev_int_data.int_dat);
    } else {
        printf("int data read fail \r\n");
    }
    printf("--------------------- \r\n");
    // 整型数读写测试 测试结束
    // 连续数据读写测试
    uint8_t write_dat[22] = {0};        // 22个字节
    uint8_t recv_buf[22] = {0};
    
    printf("正在往数组中填充数据... \r\n");
    for(int i = 0; i < 22; i++){
        write_dat[i] = i;
        printf("%02X ", write_dat[i]);
    }
    printf("\r\n 数组中数据填充完毕... \r\n");
    
    if(HAL_OK == At24c02_Write_Amount_Byte(0, write_dat, 22)){
        printf("24c02 write success \r\n");
    } else {
        printf("24c02 write fail \r\n");
    }
    
    HAL_Delay(50);      // 写一次和读一次之间需要短暂的延时
    
    if(HAL_OK == At24c02_Read_Amount_Byte(0, recv_buf, 22)){
        printf("read success \r\n");
        for(int i = 0; i < 22; i++) {
            printf("0x%02X ", recv_buf[i]);
        }
    } else {
        printf("read fail\r\n");
    }
    // 连续数据读写 测试结束


测试结果

STM32MX配置EEPROM(AT24C02)------保姆级教程,STM32CEBUMX,stm32,嵌入式硬件,单片机
可以看到存取单个字节、多个字节、浮点数、双精度浮点数、整型数都没有问题。文章来源地址https://www.toymoban.com/news/detail-603989.html

到了这里,关于STM32MX配置EEPROM(AT24C02)------保姆级教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • STM32 第19讲 IIC(协议简介/读取驱动AT24C02/实验)

    IIC: Inter Integrated Circuit,集成电路总线,是一种 同步 串行 半双工通信协议 ①总线由数据线 SDA 和时钟线 SCL 构成的串行总线,数据线用来传输数据,时钟线用来同步数据收发。 ②总线上每一个器件都有一个唯一的地址识别,所以我们只需要知道器件的地址,根据时序就可以

    2024年02月03日
    浏览(38)
  • STM32-I2C通信在AT24C02的应用

    AT24C02是一种失去电源供给后依旧能保持数据的储存器,常用来储存一些配置信息,在系统重新上电之后也可以加载。它的容量是2k bit的EEPROM存储器,采用I2C通信方式。 AT24C02支持两种写操作:字节写操作和页写操作。本实验中我们采用的是字节写操作,就是一个地址一个数据

    2024年02月09日
    浏览(52)
  • STM32基于HAL工程硬件I2C读写AT24C02/04/08数据

    ✨申明:本文章仅发表在CSDN网站,任何其他网站,未注明来源,见此内容均为盗链和爬取,请多多尊重和支持原创! 🍁对于文中所提供的相关资源链接将作不定期更换。 相关篇针对AT24C32及以上容量《STM32基于STM32-HAL工程硬件I2C读取AT24Cxx数据》 🎯本工程使用STM32F103VE+AT24C02实

    2023年04月11日
    浏览(55)
  • 6、单片机与AT24C02的通讯(IIC)实验(STM32F407)

    IIC简介 I2C(IIC,Inter-Integrated Circuit),两线式串行总线,由PHILIPS公司开发用于连接微控制器及其外围设备。 它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbps以上。 IIC是半双工通信方式。 多主机

    2024年02月20日
    浏览(69)
  • AT24C32、AT24C64、AT24C128、AT24C256、AT24C512系列EEPROM芯片单片机读写驱动程序

    1.AT24C01/AT24C02系列EEPROM芯片单片机读写驱动程序 2.AT24C04、AT24C08、AT24C16系列EEPROM芯片单片机读写驱动程序 3.AT24C32、AT24C64、AT24C128、AT24C256、AT24C512系列EEPROM芯片单片机读写驱动程序 4.x24Cxx系列EEPROM芯片C语言通用读写程序 在前两篇博文中,分别记录了AT24C01、AT24C02,以及AT24C04、

    2024年02月02日
    浏览(51)
  • ESP8266+STM32+阿里云保姆级教程(AT指令+MQTT)

    前言:在开发过程中,几乎踩便了所有大坑小坑总结出的文章,我是把坑踩满了,帮助更过小白快速上手,如有错误之处,还麻烦各位大佬帮忙指正、 目录 一、ESP-01s介绍         1、ESP-01s管脚功能:                 模组启动模式说明:         2、初始配置和

    2024年02月19日
    浏览(43)
  • STM32存储左右互搏 I2C总线FATS读写EEPROM ZD24C1MA

    在较低容量存储领域,EEPROM是常用的存储介质,可以通过直接或者文件操作方式进行读写。不同容量的EEPROM的地址对应位数不同,在发送字节的格式上有所区别。EEPROM是非快速访问存储,因为EEPROM按页进行组织,在连续操作模式,当跨页时访问地址不是跳到下一页到开始,而

    2024年02月12日
    浏览(68)
  • STM32CUBUMX配置RS485(中断接收)--保姆级教程

    ———————————————————————————————————— ⏩ 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的大三学生。 ⏩最近在开发一个STM32H723ZGT6的板子,使用STM32CUBEMX做了很多驱动,包括ADC、UART、RS485、EEPROM(IIC)、FLASH(SPI)等等。

    2024年02月16日
    浏览(69)
  • stm32使用HAL库配置串口中断收发数据(保姆级教程)

    最近在学习使用hal库,之前都是用标准库来写32代码,所以发个帖子记录一下学习过程,同时也希望能帮助到一些也在学习HAL库的同学。 接下来进入正题 串口中断是指当单片机收到一个串口数据时,单片机会产生一个中断信号,通知处理器中断服务程序去处理这个接收到的数

    2024年02月07日
    浏览(43)
  • 【接口协议】FPGA实现IIC协议对EEPROM进行数据存储与读取(AT24C64)

    使用vivado实现IIC协议对EEPROM进行数据存储与读取。本文是基于正点原子的“达芬奇”开发板资料进行学习的笔记,对部分地方进行了修改,并进行了详细的讲解。 IIC(Inter-Integrated Circuit),即集成电路总线,是一种同步半双工串行总线,用于连接微控制器及外围设备,是用于数据

    2024年02月04日
    浏览(75)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包