0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

瑞萨RA系列FSP库开发实战指南之I2C读写EEPROM实验

瑞萨嵌入式小百科 来源:野火电子 2026-01-27 10:02 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

21.4.1

硬件设计

野火启明6M5开发板的EEPROM电路图如图所示:

7b169140-fa6e-11f0-92de-92fbcf53809c.png

图22‑13a EEPROM硬件连接图

野火启明4M2开发板的EEPROM电路图如图所示:

7b83e4e8-fa6e-11f0-92de-92fbcf53809c.png

图22‑13b EEPROM硬件连接图

野火启明2L1开发板的EEPROM电路图如图所示:

7bd856ea-fa6e-11f0-92de-92fbcf53809c.png

图22‑13c EEPROM硬件连接图

EEPROM芯片连接到MCU的引脚如下表所示。

表2:EEPROM引脚

7c3269e6-fa6e-11f0-92de-92fbcf53809c.png

21.4.2

软件设计

使用瑞萨官方提供的FPS库进行编程,瑞萨官方提供的FPS库具有方便、快捷、简洁的特性。

21.4.2.1

新建工程

因为本章节的EEPROM相关实验例程需要用到板子上的串口功能,因此我们可以直接以前面的“19_UART_Receive_Send”工程为基础进行修改。

对于e2studio开发环境:拷贝一份我们之前的e2s工程“19_UART_Receive_Send”“22_EEPROM_Hardware”,然后将工程文件夹重命名为“16_ICU_External_IRQ”,最后再将它导入到我们的e2studio工作空间中。

对于Keil开发环境:拷贝一份我们之前的Keil工程“19_UART_Receive_Send”“22_EEPROM_Hardware”,然后将工程文件夹重命名为“16_ICU_External_IRQ”,并进入该文件夹里面双击Keil工程文件,打开该工程。

21.4.2.2

FSP配置

新建工程后,我们先打开“22_EEPROM_Hardware”项目的FSP配置界面进行配置。新建工程后,

在FSP配置界面里面我们依次点击“Stacks”->“NewStack”->“Connectivity”->“I2CMaster”来配置IIC模块。如图22_14。

7c8be412-fa6e-11f0-92de-92fbcf53809c.png

图22-14 加入IIC

按照图片顺序依次进行点击然后点击“I2CMaster”在左下角的属性界面里进行配置。如图22_15。

7cf59eac-fa6e-11f0-92de-92fbcf53809c.png

图22-15 配置图

配置完成之后可以按下快捷键“Ctrl+S”保存,最后点右上角的“GenerateProjectContent”按钮,让软件自动生成配置代码即可。

21.4.2.3

R_IIC_MASTER_Write函数

列表1:代码清单22_1:

R_IIC_MASTER_Write结构体

左右滑动查看完整内容

fsp_err_tR_IIC_MASTER_Write(i2c_master_ctrl_t*constp_api_ctrl,uint8_t␣
→*constp_src,uint32_tconst bytes,boolconst restart)

当我们调用该函数,在数据传输的开始时会发送从设备的地址位。之后根据p_src数组发送第一个位在数据位,传输的过程中硬件会自动发送确认位和结束位。传输数据的长度与bytes有关,完成之后restart来决定此次通信之后是否通过发出重复的START条件来保持总线。

在调用这个函数之后我们需要延时一段时间或者使用回调函数判断,之后再调用下一段IIC函数,详细的可以看下面IIC的写入代码,原因是因为当你使用了R_IIC_MASTER_Write函数之后,IIC通信还未完成,如果你再次调用其他的IIC函数就会覆盖掉第一次执行的函数,从而出现时序错误。

21.4.2.4

R_IIC_MASTER_Read函数

列表2:代码清单22_2:

R_IIC_MASTER_Read结构体

左右滑动查看完整内容

fsp_err_tR_IIC_MASTER_Read(i2c_master_ctrl_t*constp_api_ctrl,uint8_t*␣
→constp_dest,uint32_tconst bytes,boolconst restart)

当我们调用该函数,在数据传输的开始时会发送从设备的地址位。之后根据p_src数组保存第一个获取的数据,传输的过程中硬件会自动加载应答位和结束位。传输数据的长度与bytes有关,完成之后restart来决定此次通信之后是否通过发出重复的START条件来保持总线。

该函数与之前的R_IIC_MASTER_Write函数一样在使用之后需要需要延时一段时间或者使用回调函数判断。

21.4.2.5. 向EEPROM写入一个字节

初始化好I2C外设后,就可以使用I2C通讯了,更具上面两个函数的介绍我们就可以写出EEPROM的写入以及读取函数。我们看看如何向EEPROM写入一个字节的数据,见代码清单22_3。

代码清单 22_3:EEPROM写入一个字节函数



/**
* @brief 以单字节的方式到I2C EEPROM中
* @param
*   @arg address:写地址
*   @arg byte:写的数据
* @retval  无
*/
void I2C_EE_ByteWrite(unsigned char address, unsigned char byte)
{
   iic_complete = false;
   unsigned char send_buffer[2] = {};

   send_buffer[0] = address;
   send_buffer[1] = byte;
   R_IIC_MASTER_Write(&EEPROM_ctrl, &send_buffer[0], 2, false); //每当写完数据 false 总线拉高

   while ((I2C_MASTER_EVENT_TX_COMPLETE != g_i2c_callback_event) && timeout_ms)
   {
      R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
      timeout_ms--;
   }
   timeout_ms = 500;
}


这里我们只是简单调用库函数R_IIC_MASTER_Write就可以实现,通过封装一次使用更为方便。

在这个通讯过程中,RA6M5实际上通过I2C向EEPROM发送了两个数据, 但为何第一个数据被解释为EEPROM的内存地址? 这是由EEPROM的自己定义的单字节写入时序,见图22_16.

wKgZO2l4HXeAAOYIAAD_2zjG3HM55.jpeg

图 22‑16 EEPROM单字节写入时序(摘自《AT24C02》规格书)

EEPROM的单字节时序规定,向它写入数据的时候,第一个字节为内存地址,第二个字节是要写入的数据内容。所以我们需要理解:命令、地址的本质都是数据,对数据的解释不同,它就有了不同的功能。

21.4.2.6. EEPROM的页写入

在以上的数据通讯中,每写入一个数据都需要向EEPROM发送写入的地址,我们希望向连续地址写入多个数据的时候,只要告诉EEPROM第一个内存地址address1,后面的数据按次序写入到address2、address3… 这样可以节省通讯的内容,加快速度。为应对这种需求,EEPROM定义了一种页写入时序,见图22_17。

wKgZO2l4HXeAMtAdAADKHFsFXwc17.jpeg

图 22‑17 EEPROM页写入时序(摘自《AT24C02》规格书)

根据页写入时序,第一个数据被解释为要写入的内存地址address1,后续可连续发送n个数据, 这些数据会依次写入到内存中。其中AT24C02型号的芯片页写入时序最多可以一次发送8个数据(即n = 8 ),该值也称为页大小,某些型号的芯片每个页写入时序最多可传输16个数据。EEPROM的页写入代码实现 见代码清单22_4。

代码清单 22‑4 EEPROM的页写入


/**
* @brief   将缓冲区中的数据以页写入的方式写到I2C EEPROM中
* @param
*   @arg ptr_write:缓冲区指针
*   @arg WriteAddr:写地址
*     @arg len:写的长度
* @retval  无
*/
void I2C_EE_Writepage(unsigned char* ptr_write , unsigned char WriteAddr,unsigned char len)      //页写入   page 0~31
{

   unsigned char send_buffer[9] = {};
   send_buffer[0] = WriteAddr;

   for(unsigned char i = 0;i

}



21.4.2.7. 多字节写入

多次写入数据时,利用EEPROM的页写入方式,避免单字节读写时候的等待。多个数据写入过程 见代码清单22_5。

代码清单 22‑5 多字节写入


/**
* @brief   将缓冲区中的数据写到I2C EEPROM中
* @param
*   @arg pBuffer:缓冲区指针
*   @arg WriteAddr:写地址
*     @arg NumByteToWrite:写的字节数
* @retval  无
*/
void I2C_EE_BufferWrite(uint8_t* pBuffer, uint8_t WriteAddr,uint16_t NumByteToWrite)
{
   uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

   Addr = WriteAddr % EEPROM_PAGESIZE;
   count = EEPROM_PAGESIZE - Addr;
   NumOfPage =  NumByteToWrite / EEPROM_PAGESIZE;
   NumOfSingle = NumByteToWrite % EEPROM_PAGESIZE;

   /* If WriteAddr is I2C_PageSize aligned  */
   if (Addr == 0) {
      /* If NumByteToWrite < I2C_PageSize */
      if (NumOfPage == 0) {
            I2C_EE_Writepage(pBuffer, WriteAddr, NumOfSingle);
      }
      /* If NumByteToWrite > I2C_PageSize */
      else {
            while (NumOfPage--) {
               I2C_EE_Writepage(pBuffer, WriteAddr, EEPROM_PAGESIZE);
               WriteAddr +=  EEPROM_PAGESIZE;
               pBuffer += EEPROM_PAGESIZE;
            }

            if (NumOfSingle!=0) {
               I2C_EE_Writepage(pBuffer, WriteAddr, NumOfSingle);
            }
      }
   }
   /* If WriteAddr is not I2C_PageSize aligned  */
   else {
      /* If NumByteToWrite < I2C_PageSize */
      if (NumOfPage== 0) {
            I2C_EE_Writepage(pBuffer, WriteAddr, NumOfSingle);
      }
      /* If NumByteToWrite > I2C_PageSize */
      else {
            NumByteToWrite -= count;
            NumOfPage =  NumByteToWrite / EEPROM_PAGESIZE;
            NumOfSingle = NumByteToWrite % EEPROM_PAGESIZE;

            if (count != 0) {
               I2C_EE_Writepage(pBuffer, WriteAddr, count);
               WriteAddr += count;
               pBuffer += count;
            }

            while (NumOfPage--) {
               I2C_EE_Writepage(pBuffer, WriteAddr, EEPROM_PAGESIZE);
               WriteAddr +=  EEPROM_PAGESIZE;
               pBuffer += EEPROM_PAGESIZE;
            }
            if (NumOfSingle != 0) {
               I2C_EE_Writepage(pBuffer, WriteAddr, NumOfSingle);
            }
      }
   }
}



21.4.2.8. EEPROM读取函数

从EEPROM读取数据是一个复合的I2C时序,它实际上包含一个写过程和一个读过程, 见图22_18。

wKgZPGl4HXeAN_ntAAHAl8HPEOo34.jpeg

图 22‑18 EEPROM数据读取时序

读时序的第一个通讯过程中,使用I2C发送设备地址寻址(写方向),接着发送要读取的“内存地址”;第二个通讯过程中, 再次使用I2C发送设备地址寻址,但这个时候的数据方向是读方向;在这个过程之后,EEPROM会向主机返回从“内存地址”开始的数据, 一个字节一个字节地传输,只要主机的响应为“应答信号”,它就会一直传输下去,主机想结束传输时,就发送“非应答信号”, 并以“停止信号”结束通讯,作为从机的EEPROM也会停止传输。FSP库已经帮我们实现了这一个过程, 我们只是简单封装一下就可以直接使用,实现代码见代码清单22_6。

代码清单 22_6:EEPROM读取函数

/**
* @brief 读取I2C EEPROM数据
* @param
*   @arg ptr_read:读取缓冲区指针
*   @arg address:地址
*     @arg byte:读取的字节数
* @retval  无
*/
void I2C_EE_BufferRead(unsigned char* ptr_read,unsigned char address,unsigned char byte)
{

   unsigned char send_buffer[2] = {};
   unsigned char read_buffer[1] = {};

   send_buffer[0] = address;
   R_IIC_MASTER_Write(&EEPROM_ctrl, &send_buffer[0], 1, true);
   while ((I2C_MASTER_EVENT_TX_COMPLETE != g_i2c_callback_event) && timeout_ms)
   {
      R_BSP_SoftwareDelay(400U, BSP_DELAY_UNITS_MICROSECONDS);
      timeout_ms--;
   }
   timeout_ms = 500;

   R_BSP_SoftwareDelay(250U, BSP_DELAY_UNITS_MICROSECONDS);

   R_IIC_MASTER_Read(&EEPROM_ctrl, ptr_read, byte, false);

}



这个函数是在指定的地址读取一个字节的数据,第一个变量EEPROM的地址,最后会返回一个整型的数据。如果不想使用printf函数可以将其进行注释,但需要适当增加延时时间。 这里代码非常简单,我们只需要确定I2C的地址、数据格式、数据存储指针、数据大小、超时设置,就可以把想要的数据读回来。

21.4.2.9. EEPROM测试函数

代码清单 22_7:EEPROM测试函数

/**
* @brief  I2C(AT24C02)读写测试
* @param  无
* @retval 正常返回1 ,不正常返回0
*/
uint8_t I2C_Test(void)
{
   uint16_t i;
   unsigned char DATA_Size = 30;
   unsigned char I2c_Buf_Write[33] = {};
   unsigned char I2c_Buf_Read[33] = {};

   //将I2c_Buf_Write中顺序递增的数据写入EERPOM中
   printf("写入的数据\r\n");
   for ( i=0; i

}


21.4.2.10. 主函数

代码清单 22_8:主函数


void hal_entry(void)
{

   I2C_EE_Init();
   Debug_UART4_Init();

   printf("欢迎使用野火  RA6M5 开发板。\r\n");
   printf("这是一个I2C外设(AT24C02)读写测试例程 \r\n");
   R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);

   while (1)
   {
      I2C_EE_Writedrase();
      if (I2C_Test() ==1) {
            LED_GREEN;
      } else {
            LED_RED;
      }

      while(1);
   }

#if BSP_TZ_SECURE_BUILD
   /* Enter non-secure code */
   R_BSP_NonSecureEnter();
#endif

}


21.4.3. 下载验证

保证开发板相关硬件连接正确,用Type-C线连接开发板“USB TO UART”接口电脑, 在电脑端打开串口调试助手,把编译好的程序下载到开发板, 此时串口调试助手即可收到开发板发过来的数据。 在串口调试助手可看到EEPROM测试的调试信息。如下图所示:

wKgZO2l4HXeAH-36AAI2R70bSpc273.jpg

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 瑞萨
    +关注

    关注

    38

    文章

    22532

    浏览量

    91611
  • EEPROM
    +关注

    关注

    9

    文章

    1148

    浏览量

    86441
  • I2C
    I2C
    +关注

    关注

    28

    文章

    1564

    浏览量

    131877
  • 开发板
    +关注

    关注

    26

    文章

    6476

    浏览量

    121300

原文标题:I²C读写EEPROM实验——瑞萨RA系列FSP库开发实战指南(67)

文章出处:【微信号:瑞萨嵌入式小百科,微信公众号:瑞萨嵌入式小百科】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    RA系列FSP开发实战指南RA6M5的I2C特性及架构

    如果我们直接控制RA6M5的两个GPIO引脚,分别用作SCL及SDA,按照上述信号的时序要求,直接像控制LED灯那样控制引脚的输出(若是接收数据时则读取SDA电平),就可以实现I2C通讯。同样,假如
    的头像 发表于 01-21 13:47 3385次阅读
    <b class='flag-5'>瑞</b><b class='flag-5'>萨</b><b class='flag-5'>RA</b><b class='flag-5'>系列</b><b class='flag-5'>FSP</b><b class='flag-5'>库</b><b class='flag-5'>开发</b><b class='flag-5'>实战</b><b class='flag-5'>指南</b><b class='flag-5'>之</b><b class='flag-5'>瑞</b><b class='flag-5'>萨</b><b class='flag-5'>RA</b>6M5的<b class='flag-5'>I2C</b>特性及架构

    RA MCU众测宝典 | I²C读取EEPROM

    I2C协议读取EEPROM数据。嵌入式小百科将带着大家从I2C总线原理、EEPROM(AT2
    的头像 发表于 01-13 18:05 8656次阅读
    <b class='flag-5'>RA</b> MCU众测宝典 | <b class='flag-5'>I</b>²<b class='flag-5'>C</b>读取<b class='flag-5'>EEPROM</b>

    e2studio(1)----芯片搭建FSP环境

    视频教学 样品申请 请勿添加外链 e2studio软件 e2studio是的集成开发环境,FSP
    发表于 09-30 15:28

    RA6E2地奇星开发板试用】开发板介绍及环境搭建

    2.0 Full-Speed、CAN FD、I3C、Quad SPI、HDMI CEC、12-bit ADC/DAC 等丰富外设 二、开发环境搭建(推荐 e² studio + FSP
    发表于 12-22 00:40

    I2C协议以及I2C读写EEPROM

    I2C协议以及I2C读写EEPROM实验文章目录I2C协议以及
    发表于 08-23 08:25

    RA4系列开发板体验】开发环境搭建和新手点灯指南

    RA4系列开发板体验】开发环境搭建和新手点灯指南
    发表于 11-24 22:54

    RA4系列开发板体验】体验过程

    拿到板子之后,做了几个实验过程,过程如下:1、在好奇心驱动下,逐步接触;参照网上的实例,学习开发环境一、开箱验货二、搭建环境参考“ 【
    发表于 12-18 16:20

    【野火启明6M5开发板体验】开箱+认识开发板+资料

    按键检测29. WiFi——模块通讯板尺寸:3、资料:*附件:[野火EmbedFire]《RA系列FSP
    发表于 12-20 23:28

    I2C总线实验(实时时钟、EEPROM和ZLG7290的实验

    I2C 总线实验(实时时钟、EEPROM 和ZLG7290 的实验) 一. 实验目的加深用户对I2C
    发表于 09-22 16:58 4699次阅读
    <b class='flag-5'>I2C</b>总线<b class='flag-5'>实验</b>(实时时钟、<b class='flag-5'>EEPROM</b>和ZLG7290的<b class='flag-5'>实验</b>

    I2C读写EEPROM

    【*】程序简介 -工程名称:基本读写EEPROM -实验平台: 秉火STM32 F429 开发板 -MDK版本:5.16 -ST固件版本:
    发表于 12-13 15:12 23次下载

    STM32F10x _硬件I2C读写EEPROM(标准外设版本)

    STM32F10x_硬件I2C读写EEPROM(标准外设版本)
    的头像 发表于 03-25 11:11 1.3w次阅读
    STM32F10x _硬件<b class='flag-5'>I2C</b><b class='flag-5'>读写</b><b class='flag-5'>EEPROM</b>(标准外设<b class='flag-5'>库</b>版本)

    STM32学习I2C协议(读写EEPROM

    关于STM32学习分享第七章 I2C协议(读写EEPROM)文章目录关于STM32学习分享前言二、代码1.i2c.c2.i2c.h3.main.c总结前言开始!开始!单片机的
    发表于 11-30 15:21 34次下载
    STM32学习<b class='flag-5'>之</b><b class='flag-5'>I2C</b>协议(<b class='flag-5'>读写</b><b class='flag-5'>EEPROM</b>)

    【有奖直播预报名】电子RA系列产品开发工具FSP4.0.0新特性介绍

    为使用电子RA系列ARM微控制器的嵌入式系统设计提供简单易用且可扩展的高质量软件。 直播主题
    的头像 发表于 11-22 12:20 1788次阅读

    使用e² studio FSP基于RA2E1定时器配置PWM输出

    使用e² studio FSP基于RA2E1定时器配置PWM输出
    的头像 发表于 08-01 00:13 2330次阅读
    使用<b class='flag-5'>瑞</b><b class='flag-5'>萨</b>e² studio <b class='flag-5'>FSP</b>基于<b class='flag-5'>RA2</b>E1定时器配置PWM输出

    RA MCU众测宝典 | OLEDRA-Eco-RA2L1】I²C驱动OLED屏幕 BME280传感器

    L1】呼吸灯RAMCU众测宝典|ADC/DACRA2L1】DAC电压输出及ADC电压采集实验本次实验的目标是把I2C相关的搞定,再尝试驱
    的头像 发表于 05-08 16:08 875次阅读
    <b class='flag-5'>瑞</b><b class='flag-5'>萨</b><b class='flag-5'>RA</b> MCU众测宝典 | OLED<b class='flag-5'>之</b>【<b class='flag-5'>RA-Eco-RA2</b>L1】<b class='flag-5'>I</b>²<b class='flag-5'>C</b>驱动OLED屏幕 BME280传感器