STMCUBEMX_IIC_LL库_AT24C64分页读取和写入

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


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

二、从多臂老虎机看强化学习

二、从多臂老虎机看强化学习 2.1 多臂老虎机问题2.1.1 问题定义2.2.2 问题建模2.2.3 累积懊悔2.2.4 估计期望奖励 2.2 强化学习中的探索与利用平衡2.3 贪心策略2.4 上置信界算法2.5 汤普森采样算法 2.1 多臂老虎机问题 2.1.1 问题定义 在多臂老虎机(mutil-armed bandit, MAB)问…

专业电脑录歌软件,电脑录音的六大方法【你了解几个】

电脑录音怎么录&#xff1f;大多数电脑都是有自带的录音功能的&#xff0c;但是由于电脑系统自带的录音功能效果没那么好&#xff0c;很多情况下满足不了我们一些“刁钻”的录音需求。 那么电脑怎么录音&#xff1f;还有哪些好用的录音软件推荐&#xff1f;本文整理了多种电脑录…

常规情况与opencv图像中,计算直线与矩形框的交点

文章目录 1、普通方式1.1、普通计算过程1.2、优化方式 2、图像中的情况2.1、常规处理2.2、opencv中的处理2.2.1、cv::clipLine函数2.2.2、测试代码2.2.3、测试结果 1、普通方式 已知矩形框左上(x1,y1)、右下(x2,y2&#xff09;点&#xff0c;直线方程 y kxb&#xff0c;求交点…

桌面保存的Word文件删除怎么找回?超实用的三个方法?

在日常工作和学习中&#xff0c;我们经常会使用Word文档进行文字编辑和文件保存。但是&#xff0c;有时由于操作失误或系统故障&#xff0c;我们会不小心将存放在电脑桌面重要的Word文件删除了。导致无法挽回的损失&#xff0c;但幸运的是&#xff0c;有一些方法可以帮助我们找…

基于SpringBoot的乐校园二手书交易管理系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言 Java 数据库 MySQL 技术 SpringBoot框架 工具 Visual Studio、MySQL数据库开发工具 系统展示 首页 用户注册界面 二手图书界面 个人中心界面 摘要 乐校园…

新港海岸NCS8822 低功耗DP转VGA 分辨率支持1920*1200*60HZ

NCS8822描述&#xff1a; NCS8822是一个低功耗显示端口到vga转换器。NCS8822集成了一个与DP1.2兼容的接收器和一个高速三通道视频DAC。对于DP1.2输入&#xff0c;NCS8822支持1车道/2车道&#xff0c;也支持车道交换功能。对于VGA输出NCS8822&#xff0c;在60Hz帧率下对WUXGA&a…

【HICE】搭建不同的主机名访问web服务

1.首先进入1.conf.d编辑内容&#xff0c;再重启服务&#xff0c;关闭防火墙 2.部署网页haha.html和xixi.html 3.在vim /etc/hosts增加域名 3.在window中进行本地解析的编辑 4.浏览器的验证

自闭症孩子的语言之旅:最晚几岁会说话的探索与思考

作为在自闭症学校工作的教育者&#xff0c;我深知自闭症这一神经发展性障碍给孩子们带来的挑战&#xff0c;尤其是他们在语言发展方面的困难。自闭症孩子的语言发展轨迹各不相同&#xff0c;有的孩子可能早早地展现出语言天赋&#xff0c;而有的孩子则可能迟迟不开口。那么&…

AI文字图片人脸生成原创视频文生图生肖生小程序开发

AI文字图片人脸生成原创视频文生图生肖生小程序开发 无限开 0.12生成 图生视频 AI技术在生成文字、图片、人脸以及视频方面已经取得了显著的进步。以下是一些可能包含在AI文字图片人脸生成原创视频小程序中的功能列表&#xff1a; 文字转视频&#xff1a; 输入文字或文章&…

如何选择TikTok菲律宾直播网络?

为了满足用户对于实时互动的需求&#xff0c;TikTok推出了直播功能&#xff0c;让用户能够与粉丝即时交流。本文将探讨如何选择适合的TikTok菲律宾直播网络&#xff0c;并分析OgLive是否是值得信赖的选择。 TikTok菲律宾直播网络面临的挑战 作为全球领先的短视频平台&#xff…

数据分析和人工智能平台帮助企业创造更好、更安全、更可持续的产品

——Sam Mahalingam | Altair 首席技术官 | 2024.6.24 Altair的数据分析和人工智能&#xff08;AI&#xff09;平台AltairRapidMiner最近被Gartner 魔力象限™评为数据科学和机器学习平台领导者。有些人可能不太熟悉&#xff0c;实际上Gartner 魔力象限™ 报告是严格的、基于事…

【扩散模型(三)】IP-Adapter 源码详解1-输入篇

系列文章目录 【扩散模型&#xff08;一&#xff09;】中介绍了 Stable Diffusion 可以被理解为重建分支&#xff08;reconstruction branch&#xff09;和条件分支&#xff08;condition branch&#xff09;【扩散模型&#xff08;二&#xff09;】IP-Adapter 从条件分支的视…

生产力工具|viso常用常见科学素材包

一、科学插图素材网站 一图胜千言&#xff0c;想要使自己的论文或重要汇报更加引人入胜&#xff1f;不妨考虑利用各类示意图和科学插图来辅助研究工作。特别是对于新手或者繁忙的科研人员而言&#xff0c;利用免费的在线科学插图素材库&#xff0c;能够极大地节省时间和精力。 …

20.5.【C语言】求长度的两种方式

1.sizeof 用于测数据类型的长度的函数&#xff08;详细见第3篇&#xff09; 2.strlen 其计算长度时只有遇到\0才会停止&#xff0c;并且\0不会计算在内 如char arr[]{a,1,b}; printf("%d\n",strlen(arr)); 结果是个随机数&#xff01;strlen读内存中的数据&…

3D生成模型TripoSR完美搭建流程,包含所有问题解决方案!

最近需要使用3D生成模型,无意中看到了TripoSR,觉得效果还行,于是打算在Linux系统上部署一下,结果遇到很多坑,在这里写一下详细的部署流程和部署过程中遇到的问题。 下面是TripoSR的源码地址。 GitHub - VAST-AI-Research/TripoSRContribute to VAST-AI-Research/TripoSR…

已经安装deveco-studio-4.1.3.500的基础上安装deveco-studio-3.1.0.501

目录标题 1、执行exe文件后安装即可2、双击devecostudio64_3.1.0.501.exe2.1、安装Note (注意和4.1的Note放不同目录)2.2、安装ohpm (注意和4.1版本的ohpm放不同目录)2.3、安装SDK (注意和4.1版本的SDK放不同目录) 1、执行exe文件后安装即可 2、双击devecostudio64_3.1.0.501.e…

linux主机(A)通过私钥登录linux主机(B)

1.登录B主机&#xff0c;先在B主机执行 ssh-keygen 2.设置id_rsa的权限 chmod 600 id_rsa 3.将生成的id_rsa.pub导入到authorized_keys ssh-copy-id -i ./id_rsa.pub root127.0.0.1 4.将id_rsa复制到A主机 scp id_rsa_123 root1.1.1.A:/home/ 5.登录到A主机使用私钥登录 因…

C++左值/右值/左值引用/右值引用

1&#xff09;C入门级小知识&#xff0c;分享给将要学习或者正在学习C开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 左值和右值的概念&#xff1a; 早期的c语言中关于左值和右值的定义&a…

使用中国大陆镜像源安装最新版的 docker Deamon

在一个智算项目交付过程中&#xff0c;出现了新建集群中的全部 docker server V19 进程消失、仅剩 docker server 的 unix-socket 存活的现象。 为了验证是否是BD产品研发提供的产品deploy语句缺陷&#xff0c;需要在本地环境上部署一个简单的 docker Deamon 环境。尴尬的是&a…

强化学习后的数学原理:随机近似与梯度下降

概述 这节课的作用&#xff1a; 本节课大纲如下&#xff1a; Motivating examples 先回顾一下 mean estimation &#xff1a; 为什么总数反复提到这个 mean estimation&#xff0c;就是因为 RL 当中有非常多的 expectation&#xff0c;后面就会知道除了 state value 这些定义…