STMCUBEMX_IIC_LL库_AT24C64分页读取和写入

news2024/11/27 23:34:01

STMCUBEMX_IIC_LL库_AT24C64分页读取和写入

前言:
一个项目中构建的软件系统需要存储非常多的用户参数,大约有几千字节,所以牵扯到自己设计跨页写入算法,注意读出也是需要设计跨页读出算法的(手册没强调,但是实际测试结果不分页直接连续读,最多一次性只能读出280个字节,不同厂家的芯片可能有不同)

在这里插入图片描述

1、分页写入算法

//eeprom设备发送多个字节
unsigned char I2CX_DeviceWriteArray_addr16(I2C_TypeDef *I2Cx,unsigned char dev_addr,unsigned short addr,unsigned char *data,unsigned int len,unsigned int overtime)
{
	unsigned int time = timestamp;
	LL_I2C_GenerateStartCondition(I2Cx);//起始信号
	while (!LL_I2C_IsActiveFlag_SB(I2Cx))//起始信号发送完毕
	{
		if(timestamp > time + overtime) return 1;
	}
	
	LL_I2C_TransmitData8(I2Cx, dev_addr);//发送器件地址
	//LL_I2C_TransmitData8(I2Cx, dev_addr);//发送器件地址
	while (!LL_I2C_IsActiveFlag_ADDR(I2Cx))//等待从机回应ACK
	{
		if(timestamp > time + overtime) return 1;
	}
	LL_I2C_ClearFlag_ADDR(I2Cx);
	
	LL_I2C_TransmitData8(I2Cx, addr >> 8);//发送数据
	LL_I2C_TransmitData8(I2Cx, addr);//发送数据
	while (!LL_I2C_IsActiveFlag_TXE(I2Cx))
	{
		if(timestamp > time + overtime) return 1;
	}
	
	while(len--)
	{
		LL_I2C_TransmitData8(I2Cx, *data);//发送数据
		data++;
		while (!LL_I2C_IsActiveFlag_TXE(I2Cx))
		{
			if(timestamp > time + overtime) return 1;
		}
	}
	LL_I2C_GenerateStopCondition(I2Cx);
	
	return 0;
}

//unsigned short addr:写器件的寄存器地址
//unsigned char *data:写数据
//unsigned short len:写数据长度
void eeprom_24c64_write(unsigned short addr,unsigned char *data,unsigned short len)
{
	if(I2CX_DeviceWriteArray_addr16(I2C1,AT24C64_ADDR,addr,data,len,100))
	{
		EEPROM_error("eeprom_24c64_write fail!!!\r\n");
	}
}

//unsigned short address:EEPROM的写起始地址
//unsigned char * data:EEPROM的写数据
//unsigned char * data:EEPROM的写数据的长度
void eepromwriteData(unsigned short address, unsigned char * data, unsigned short size) 
{
	unsigned short pageIndex = address / EEP_MAX_PAGE_SIZE;  // 获取起始页地址
	unsigned short offset = address % EEP_MAX_PAGE_SIZE;     // 获取起始地址在页内的偏移量

	int remainingSize = size;
	unsigned short dataSize;

	while (remainingSize > 0)
	{
		// 当前页的起始地址
		unsigned short currentPageAddress = pageIndex * EEP_MAX_PAGE_SIZE;
		//Debug_debug("currentPageAddress:%d\r\n",currentPageAddress);
		// 计算当前页的剩余空间大小
		unsigned short remainingSpace = EEP_MAX_PAGE_SIZE - offset;
		//Debug_debug("remainingSpace:%d\r\n",remainingSpace);
		// 计算当前要写入的数据块大小
		dataSize = (remainingSize > remainingSpace) ? remainingSpace : remainingSize;
		//Debug_debug("dataSize:%d\r\n",dataSize);
		// 将数据块写入当前页
		unsigned char write_data[EEP_MAX_PAGE_SIZE] = {0};
		memcpy(write_data,&data[size - remainingSize],dataSize);
		//Debug_debug("write_data:%x,%x,%x,%x,%x,%x,%x,%x\r\n",write_data[0],
		//write_data[1],write_data[2],write_data[3],write_data[4],write_data[5],write_data[6],write_data[7]);
		eeprom_24c64_write(currentPageAddress + offset,write_data,dataSize);

		remainingSize -= dataSize;	//计算剩余数据
		offset = 0;  								//偏移量重置为0,从下一页的起始位置开始写入
		pageIndex++;								//准备写下一页
		LL_mDelay(5);								//eeprom器件每次写入时间要有一个安全间隔
	}
}

2、分页读算法

//eeprom设备接收多个字节
unsigned char I2CX_DeviceReadArray_addr16(I2C_TypeDef *I2Cx,unsigned char dev_addr,unsigned short addr,unsigned char *data,unsigned int len,unsigned int overtime)
{
	volatile unsigned int time = timestamp;

	while (LL_I2C_IsActiveFlag_BUSY(I2Cx))
	{
		if(timestamp > time + overtime) return 1;
	}
	
	LL_I2C_GenerateStartCondition(I2Cx);//起始信号
	while (!LL_I2C_IsActiveFlag_SB(I2Cx))//起始信号发送完毕
	{
		if(timestamp > time + overtime)  return 1;
	}
	
	LL_I2C_TransmitData8(I2Cx, dev_addr);//发送器件地址,写模式
//	LL_I2C_TransmitData8(I2Cx, dev_addr | 0x01);//发送器件地址,写模式
	while (!LL_I2C_IsActiveFlag_ADDR(I2Cx))//等待从机回应ACK
	{
			if(timestamp > time + overtime)  return 1;
	}
	LL_I2C_ClearFlag_ADDR(I2Cx);

	LL_I2C_TransmitData8(I2Cx, addr >> 8);//发送寄存器地址
	while (!LL_I2C_IsActiveFlag_TXE(I2Cx))
	{
			if(timestamp > time + overtime)  return 1;
	}
	LL_I2C_TransmitData8(I2Cx, addr);//发送寄存器地址
	while (!LL_I2C_IsActiveFlag_TXE(I2Cx))
	{
			if(timestamp > time + overtime)  return 1;
	}

	LL_I2C_GenerateStartCondition(I2Cx);//起始信号
	while (!LL_I2C_IsActiveFlag_SB(I2Cx))//起始信号发送完毕
	{
			if(timestamp > time + overtime)  return 1;
	}

	LL_I2C_TransmitData8(I2Cx, dev_addr | 0x01);//发送器件地址,读模式
	while (!LL_I2C_IsActiveFlag_ADDR(I2Cx))//等待从机回应ACK
	{
			if(timestamp > time + overtime)  return 1;
	}
	LL_I2C_ClearFlag_ADDR(I2Cx);

	while(len)
	{
		if(len == 1)
		{
			LL_I2C_AcknowledgeNextData(I2Cx, LL_I2C_NACK);
			LL_I2C_GenerateStopCondition(I2Cx);
		}
		while (!LL_I2C_IsActiveFlag_RXNE(I2Cx))
		{
			if(timestamp > time + overtime)  return 1;
		}
		*data = LL_I2C_ReceiveData8(I2Cx);//接收数据
		data++;
		len--;
	}
	LL_I2C_AcknowledgeNextData(I2Cx, LL_I2C_ACK);
	return 0;
}

//unsigned short addr:读器件的寄存器地址
//unsigned char *data:读数据
//unsigned short len:读数据长度
void eeprom_24c64_read(unsigned short addr,unsigned char *data,unsigned short len)
{
	if(I2CX_DeviceReadArray_addr16(I2C1,AT24C64_ADDR,addr,data, len,100))
	{
		EEPROM_error("eeprom_24c64_read fail!!!\r\n");
	}
}

//unsigned short address:EEPROM的读起始地址
//unsigned char * data:EEPROM的读数据
//unsigned char * data:EEPROM的读数据的长度
void eepromreadData(unsigned short address, unsigned char * data, unsigned short size) 
{
	unsigned short pageIndex = address / EEP_MAX_PAGE_SIZE;  // 获取起始页地址
	unsigned short offset = address % EEP_MAX_PAGE_SIZE;     // 获取起始地址在页内的偏移量

	int remainingSize = size;
	unsigned short dataSize;

	while (remainingSize > 0)
	{
		// 当前页的起始地址
		unsigned short currentPageAddress = pageIndex * EEP_MAX_PAGE_SIZE;
		//Debug_debug("currentPageAddress:%d\r\n",currentPageAddress);
		// 计算当前页的剩余空间大小
		unsigned short remainingSpace = EEP_MAX_PAGE_SIZE - offset;
		//Debug_debug("remainingSpace:%d\r\n",remainingSpace);
		// 计算当前要写入的数据块大小
		dataSize = (remainingSize > remainingSpace) ? remainingSpace : remainingSize;
		//Debug_debug("dataSize:%d\r\n",dataSize);
		// 将数据块写入当前页
		unsigned char write_data[EEP_MAX_PAGE_SIZE] = {0};
		//Debug_debug("write_data:%x,%x,%x,%x,%x,%x,%x,%x\r\n",write_data[0],
		//write_data[1],write_data[2],write_data[3],write_data[4],write_data[5],write_data[6],write_data[7]);
		eeprom_24c64_read(currentPageAddress + offset,write_data,dataSize);
		memcpy(&data[size - remainingSize],write_data,dataSize);
		remainingSize -= dataSize;	//计算剩余数据
		offset = 0;  								//偏移量重置为0,从下一页的起始位置开始写入
		pageIndex++;								//准备写下一页
		LL_mDelay(5);								//eeprom器件每次读出时间要有一个安全间隔
	}
}

3、完整代码
eeprom.c

#include "eeprom.h"

eepromMessageData_t eepromMessageData = {0};
eepromMessageData_t eepromMessageData_old = {0};

void eepromInit(void)
{
	eepromreadData(0x00,(unsigned char *)&eepromMessageData,sizeof(eepromMessageData));
	
	/********************避免新生产的机器中EEPROM中读出的都是0xff*********************/
	if(eepromMessageData.eeprom_flow_target == 0xffff) eepromMessageData.eeprom_flow_target = 20;
	if(eepromMessageData.eeprom_pressure_target == 0xff) eepromMessageData.eeprom_pressure_target = 10;
	if(eepromMessageData.eeprom_pressure_mode == 0xff) eepromMessageData.eeprom_pressure_mode = 0;
	if(eepromMessageData.eeprom_buzzer_sound == 0xff) eepromMessageData.eeprom_buzzer_sound = 0;
	if(eepromMessageData.eeprom_flow_all == 0xffff) eepromMessageData.eeprom_flow_all = 0;
	
	memcpy(&eepromMessageData_old,&eepromMessageData,sizeof(eepromMessageData));
}

void eepromEndInit(void)
{
	
}

void eepromTask(void)
{
	if(memcmp(&eepromMessageData,&eepromMessageData_old,sizeof(eepromMessageData)) != 0)
	{
		eepromwriteData(0x00, (unsigned char *)&eepromMessageData, sizeof(eepromMessageData));
		memcpy(&eepromMessageData_old,&eepromMessageData,sizeof(eepromMessageData));
	}
}

void eeprom_24c64_write(unsigned short addr,unsigned char *data,unsigned short len)
{
	if(I2CX_DeviceWriteArray_addr16(I2C1,AT24C64_ADDR,addr,data,len,100))
	{
		EEPROM_error("eeprom_24c64_write fail!!!\r\n");
	}
}

void eeprom_24c64_read(unsigned short addr,unsigned char *data,unsigned short len)
{
	if(I2CX_DeviceReadArray_addr16(I2C1,AT24C64_ADDR,addr,data, len,100))
	{
		EEPROM_error("eeprom_24c64_read fail!!!\r\n");
	}
}

void eepromwriteData(unsigned short address, unsigned char * data, unsigned short size) 
{
	unsigned short pageIndex = address / EEP_MAX_PAGE_SIZE;  // 获取起始页地址
	unsigned short offset = address % EEP_MAX_PAGE_SIZE;     // 获取起始地址在页内的偏移量

	int remainingSize = size;
	unsigned short dataSize;

	while (remainingSize > 0)
	{
		// 当前页的起始地址
		unsigned short currentPageAddress = pageIndex * EEP_MAX_PAGE_SIZE;
		//Debug_debug("currentPageAddress:%d\r\n",currentPageAddress);
		// 计算当前页的剩余空间大小
		unsigned short remainingSpace = EEP_MAX_PAGE_SIZE - offset;
		//Debug_debug("remainingSpace:%d\r\n",remainingSpace);
		// 计算当前要写入的数据块大小
		dataSize = (remainingSize > remainingSpace) ? remainingSpace : remainingSize;
		//Debug_debug("dataSize:%d\r\n",dataSize);
		// 将数据块写入当前页
		unsigned char write_data[EEP_MAX_PAGE_SIZE] = {0};
		memcpy(write_data,&data[size - remainingSize],dataSize);
		//Debug_debug("write_data:%x,%x,%x,%x,%x,%x,%x,%x\r\n",write_data[0],
		//write_data[1],write_data[2],write_data[3],write_data[4],write_data[5],write_data[6],write_data[7]);
		eeprom_24c64_write(currentPageAddress + offset,write_data,dataSize);

		remainingSize -= dataSize;	//计算剩余数据
		offset = 0;  								//偏移量重置为0,从下一页的起始位置开始写入
		pageIndex++;								//准备写下一页
		LL_mDelay(5);								//eeprom器件每次写入时间要有一个安全间隔
	}
}

void eepromreadData(unsigned short address, unsigned char * data, unsigned short size) 
{
	unsigned short pageIndex = address / EEP_MAX_PAGE_SIZE;  // 获取起始页地址
	unsigned short offset = address % EEP_MAX_PAGE_SIZE;     // 获取起始地址在页内的偏移量

	int remainingSize = size;
	unsigned short dataSize;

	while (remainingSize > 0)
	{
		// 当前页的起始地址
		unsigned short currentPageAddress = pageIndex * EEP_MAX_PAGE_SIZE;
		//Debug_debug("currentPageAddress:%d\r\n",currentPageAddress);
		// 计算当前页的剩余空间大小
		unsigned short remainingSpace = EEP_MAX_PAGE_SIZE - offset;
		//Debug_debug("remainingSpace:%d\r\n",remainingSpace);
		// 计算当前要写入的数据块大小
		dataSize = (remainingSize > remainingSpace) ? remainingSpace : remainingSize;
		//Debug_debug("dataSize:%d\r\n",dataSize);
		// 将数据块写入当前页
		unsigned char write_data[EEP_MAX_PAGE_SIZE] = {0};
		//Debug_debug("write_data:%x,%x,%x,%x,%x,%x,%x,%x\r\n",write_data[0],
		//write_data[1],write_data[2],write_data[3],write_data[4],write_data[5],write_data[6],write_data[7]);
		eeprom_24c64_read(currentPageAddress + offset,write_data,dataSize);
		memcpy(&data[size - remainingSize],write_data,dataSize);
		remainingSize -= dataSize;	//计算剩余数据
		offset = 0;  								//偏移量重置为0,从下一页的起始位置开始写入
		pageIndex++;								//准备写下一页
		LL_mDelay(5);								//eeprom器件每次读出时间要有一个安全间隔
	}
}

eeprom.h

#ifndef __EEPROM_H
#define __EEPROM_H
#include "main.h"
#include "log.h"
#include "my_i2c.h"
#include <string.h>

#define EEPROM_LOG_EN 1
#if EEPROM_LOG_EN
	#define EEPROM_printf(format, ...) 		printf(RTT_CTRL_TEXT_WHITE format , ##__VA_ARGS__)//"\r\n"
	#define EEPROM_info(format, ...)   		printf(RTT_CTRL_TEXT_GREEN"[eeprom]info:" format , ##__VA_ARGS__)
	#define EEPROM_debug(format, ...)  		printf(RTT_CTRL_TEXT_WHITE"[eeprom]debug:" format , ##__VA_ARGS__)
	#define EEPROM_warning(format, ...)  	printf(RTT_CTRL_TEXT_YELLOW"[eeprom]warning:" format , ##__VA_ARGS__)
	#define EEPROM_error(format, ...)  		printf(RTT_CTRL_TEXT_RED"[eeprom]error:" format ,##__VA_ARGS__)
#else
	#define EEPROM_printf(format, ...)
	#define EEPROM_info(format, ...)
	#define EEPROM_debug(format, ...)
	#define EEPROM_warning(format, ...)
	#define EEPROM_error(format, ...)
#endif

#define AT24C64_ADDR 				0xA0
#define AT24C64_ADDR_WRITE 	0xA0
#define AT24C64_ADDR_READ 	0xA1

#define EEP_MAX_PAGE_SIZE  32			// 最大页写字节数
#define EEP_MAX_ROM_SIZE   8192		// EEROM容量字节数

typedef struct
{
	int eeprom_pressure_target;			//预设压力值
	int eeprom_pressure_mode;				//压力模式
	int eeprom_buzzer_sound;				//蜂鸣器声音大小
	int eeprom_flow_target;				//预设流量值
	int eeprom_flow_all[1500];						//统计流量
}eepromMessageData_t;

extern eepromMessageData_t eepromMessageData;

void eepromInit(void);
void eepromEndInit(void);
void eepromTask(void);

void eeprom_24c64_write(unsigned short addr,unsigned char *data,unsigned short len);
void eeprom_24c64_read(unsigned short addr,unsigned char *data,unsigned short len);
void eepromwriteData(unsigned short address, unsigned char * data, unsigned short size);
void eepromreadData(unsigned short address, unsigned char * data, unsigned short size);
#endif


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1897164.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

App Store迎来了重磅更新,ASO冲榜优化或将成为不可或缺的一部分

近日App Store搜索页面迎来了重磅更新&#xff0c;苹果应用商店中搜索页面原有的热搜关键词消失了取而代之的是直接将排行榜放在了搜索顶部&#xff0c;分别是APP排行和游戏排行两部分。如下图&#xff1a; 很多人应该都是参考排行榜来下载APP的&#xff0c;这次更新之后用户在…

创维汽车开展年中总结会:创新创造·勇开拓 智慧经营·攀高峰

2024年7月3日&#xff0c;回顾上半年的工作成果&#xff0c;总结经验教训&#xff0c;明确下半年的发展方向和重点任务&#xff0c;创维汽车于山西省晋中市榆次区山西联合创维体验中心开展年中总结会。 创维集团、创维汽车创始人黄宏生&#xff1b;开沃集团联合创始人、首席执…

160行代码实现代码雨效果

效果 序言 很喜欢黑客帝国里面那种代码雨的效果&#xff0c;为了锻炼自己的特效编写能力就尝试了一下&#xff0c;花了一下午写出来了。有需要的小伙伴拿去参考. 代码 package com.zgh.myapplication;import android.content.Context; import android.graphics.Canvas; impo…

PLM系统:PLM系统如何重塑产品生命周期管理

PLM系统&#xff1a;重塑产品生命周期管理的未来 在当今快速变化的商业环境中&#xff0c;产品生命周期管理&#xff08;PLM&#xff09;系统正逐渐成为企业提升竞争力、加速创新并优化运营流程的关键工具。随着技术的不断进步和市场需求的日益复杂化&#xff0c;传统的手动或…

视创云展线上虚拟展厅的优势与特点

一、线上虚拟展厅的无限魅力 1、沉浸式体验&#xff0c;跨越时空界限 视创云展线上虚拟展厅借助前沿的虚拟现实技术&#xff0c;为参观者打造了一场跨越物理界限的奇妙之旅。无论身处世界的哪个角落&#xff0c;只需轻点鼠标&#xff0c;即可瞬间“穿越”至展览现场&#xff…

“免费”的可视化大屏案例分享-智慧园区综合管理平台

一.智慧园区是什么&#xff1f; 智慧园区是一种融合了新一代信息与通信技术的先进园区发展理念。它通过迅捷信息采集、高速信息传输、高度集中计算、智能事务处理和无所不在的服务提供能力&#xff0c;实现了园区内及时、互动、整合的信息感知、传递和处理。这样的园区旨在提高…

Python爬虫康复训练——笔趣阁《神魂至尊》

还是话不多说&#xff0c;很久没写爬虫了&#xff0c;来个bs4康复训练爬虫&#xff0c;正好我最近在看《神魂至尊》&#xff0c;爬个txt文件下来看看 直接上代码 """ 神魂至尊网址-https://www.bqgui.cc/book/1519/ """ import requests from b…

Contact Form 7表单获取提交用户IP及URL等信息

有时候&#xff0c;您可能需要了解Contact Form 7表单提交后的更多的信息&#xff0c;而不仅仅是通过联系人表单字段获取用户的联系信息。例如&#xff0c;需要知道用户是哪个国家&#xff08;通过获取IP&#xff09;&#xff0c;了解用户使用的设备&#xff08;手机还是电脑&a…

什么是空气电容器?

空气电容器是使用空气作为电介质的电容器。简单的空气电容器由两个导电板组成&#xff0c;中间有一个气隙。空气电容器可以制成可变或固定电容形式。固定电容空气电容器很少使用&#xff0c;因为还有许多其他具有优异特性的类型。可变空气电容器由于其结构简单而更常用。它们通…

利用联合概率分布筛选2个维度、三个维度数据

目录 1. 整体分析步骤1:联合分布可视化步骤2:定义筛选条件步骤3:应用筛选条件实例演示第一步:联合分布可视化第二步:定义筛选条件第三步:应用筛选条件数据检查与清洗步骤数据清洗步骤下一步2. 定义筛选条件方法一:基于分位数的筛选方法二:基于高密度区域的筛选进一步分…

Leetcode.342 4的幂

给定一个整数&#xff0c;写一个函数来判断它是否是 4 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 整数 n 是 4 的幂次方需满足&#xff1a;存在整数 x 使得 n 4x 示例 1&#xff1a; 输入&#xff1a;n 16 输出&#xff1a;true示…

第20章 Mac+VSCode配置C++环境

1. 下载VSCode VSCode下载地址在mac终端里输入xcode- select --install命令,根据提示安装xcode工具。2. 安装插件(4个) 打开VScode,点击应用右侧菜单栏 C/C++(必装) Code Runner(必装) CodeLLDB(代码调试),不安装这个插件程序调试时,无法在vscode自带的终端里输入参…

智慧办公楼宇可视化:智能管理与优化

通过图扑可视化技术集成多种数据源&#xff0c;实时展示智慧办公楼宇的运行状态和管理信息&#xff0c;助力高效运营和工作环境优化。

荣耀电脑误删U盘文件?别慌,这里有找回方法

荣耀电脑误删U盘文件怎么找回&#xff1f;在日常工作和生活中&#xff0c;U盘是我们存储和传输数据的重要工具之一。然而&#xff0c;在使用荣耀电脑时&#xff0c;如果不小心误删了U盘中的文件&#xff0c;可能会给我们带来不小的困扰。但是&#xff0c;别慌&#xff01;本文将…

4面体空间5点结构种类与占比

在30个点的4面体中取5个点&#xff0c;有30*29*28*27*26/(5*4*3*2)142506种取法&#xff0c; 这里要求5个点必须是直链或支链。共有496个组合符合要求&#xff0c;按平移对称性可分成181个不同的结构 结构 数量 结构 数量 结构 数量 结构 数量 结构 数量 结构 数量 …

四川赤橙宏海商务信息咨询有限公司引领抖音电商浪潮

在数字时代的浪潮下&#xff0c;电商行业飞速发展&#xff0c;抖音电商作为新兴的电商模式&#xff0c;凭借其独特的社交属性和短视频形式&#xff0c;迅速吸引了众多消费者和商家的目光。四川赤橙宏海商务信息咨询有限公司&#xff0c;作为抖音电商服务的佼佼者&#xff0c;凭…

Go堆内存管理

内存管理单元 内存管理单元有如下 page: x64下大小为8k。go与OS内存申请与释放都是以page为单位 span: 多个连续page组成&#xff0c;是内存管理的基本单元 mcache: 每个P所有的cache&#xff0c;包含多个空闲内存块链表&#xff0c;不同的链表上的内存块大小可能是不相同的…

出海拓圈! 环保企业走出去之马来西亚水环境项目考察

中办、国办印发《关于构建现代环境治理体系的指导意见》&#xff0c;其中明确提出“鼓励企业参与绿色‘一带一路’建设&#xff0c;带动先进的环保技术、装备、产能走出去”。近年来中国积极参与全球生态环境治理&#xff0c;在环境资源综合管理、水旱灾害防御、固危废无害化处…

Resilience4j之RateLimiter和常见限流算法总结

官网地址&#xff1a;https://resilience4j.readme.io/docs/ratelimiter 中文文档&#xff1a;https://resilience4j.readme.io/docs/ratelimiter 【1】概述 Resilience4j提供了一个限流器&#xff0c;它将从epoch开始的所有纳秒划分为多个周期。每个周期的持续时间RateLimi…