FRAM铁电存储器FM25W256 | FM24CL04B | FM24CL16B编程实现读写存取数据

本文主要是介绍FRAM铁电存储器FM25W256 | FM24CL04B | FM24CL16B编程实现读写存取数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


【本文发布于https://blog.csdn.net/Stack_/article/details/116353030,未经许可不得转载,转载须注明出处】


FM25W256


一、电路

在这里插入图片描述



二、配置SPI(GD32F303)

@ CSDN Tyrion.Mon
/*** @brief  初始化SPI1* @note   SPI1_NSS -- PB12*         SPI1_SCK -- PB13*         SPI1_MI  -- PB14*         SPI1_MO  -- PB15* @param  None* @retval None* @author PWH     @ CSDN Tyrion.Mon* @date   2021/3*/
void SPI1_Init(void)
{RCU->RCU_APB1EN.Bits.SPI1EN = 1;			///* SCK复用输出 */Gd32f30x_Gpio_Init(GPIO_PB13, GPIO_MODE_OUT_50MHZ, GPIO_CTL_AF_PP);/* MI上拉输入 */Gd32f30x_Gpio_Init(GPIO_PB14, GPIO_MODE_IN, GPIO_CTL_IPU);/* MO复用输出 */Gd32f30x_Gpio_Init(GPIO_PB15, GPIO_MODE_OUT_50MHZ, GPIO_CTL_AF_PP);/* SPI1 *///1:主机模式SPI1->SPI_CTL0.Bits.MSTMOD = 1;//0: 2 线单向传输模式SPI1->SPI_CTL0.Bits.BDEN = 0;//0:全双工模式(当 BDEN 清零时)SPI1->SPI_CTL0.Bits.RO = 0;//0: 8 位数据帧格式SPI1->SPI_CTL0.Bits.FF16 = 0;//1: NSS 软件模式, NSS 电平取决于 SWNSS 位SPI1->SPI_CTL0.Bits.SWNSSEN = 1;SPI1->SPI_CTL0.Bits.SWNSS = 1;//SPI1时钟来源:APB1   psc=001 : 4分频  FRAM spi最高20MSPI1->SPI_CTL0.Bits.PSC = 1;//0:先发送最高有效位SPI1->SPI_CTL0.Bits.LF = 0;//1: SPI 为空闲状态时, CLK 引脚拉低,此时fram spi工作在mode0SPI1->SPI_CTL0.Bits.CKPL = 0;//0:在第一个时钟跳变沿采集第一个数据SPI1->SPI_CTL0.Bits.CKPH = 0;//1: RBNE 中断使能。当 RBNE 置位时,产生中断。
//	SPI1->SPI_CTL1.Bits.RBNEIE = 1;//1: SPI 设备使能SPI1->SPI_CTL0.Bits.SPIEN = 1;
}



三、命令字

在这里插入图片描述

所有写操作前都必须先发送WREN以使能写操作。

@ CSDN Tyrion.Mon
/*** @brief  使能/使能写操作* @note   * @param  ENABLE 允许;DISABLE 禁止* @retval None* @author PWH @ CSDN Tyrion.Mon* @date   2021/3*/
static void FRAM_WriteEnable(uint8_t EN_DISEN)
{FRAM_Select(CS_ENABLE);if (EN_DISEN == ENABLE)SPIx_SendData(SPI1, WREN);	//使能写操作(WREN操作码使WEL置位,允许写操作)elseSPIx_SendData(SPI1, WRDI);FRAM_Select(CS_DISABLE);
}



四、读写

读写状态寄存器

@ CSDN Tyrion.Mon
/*** @brief  读状态寄存器数据* @note   * @param  NONE* @retval 状态寄存器值 * @author PWH@ CSDN Tyrion.Mon* @date   2021/3*/
static uint8_t FRAM_ReadSR(void)
{uint8_t ret;FRAM_Select(CS_ENABLE);SPIx_SendData(SPI1, RDSR);ret = SPIx_SendData(SPI1, 0x00);FRAM_Select(CS_DISABLE);return ret;
}/*** @brief  写状态寄存器* @note   * @param  状态寄存器值* @retval NONE* @author PWH @ CSDN Tyrion.Mon* @date   2021/3*/
static void FRAM_WriteSR(uint8_t val)
{FRAM_WriteEnable(ENABLE);	//写SR前需要使能写操作FRAM_Select(CS_ENABLE);SPIx_SendData(SPI1, WRSR);SPIx_SendData(SPI1, val);FRAM_Select(CS_DISABLE);
}

读写存储块

/*** @brief  FRAM* @note   * @param  None* @retval None* @author PWH@ CSDN Tyrion.Mon* @date   2021/3*/
uint16_t FRAM_Write(uint16_t AddrOffset, uint8_t *Data, uint16_t DataLen)
{if ((!DataLen) || (AddrOffset > FRAM_ADDR_MAX) || ((AddrOffset + DataLen - 1) > FRAM_ADDR_MAX))return 0;FRAM_WriteSR(0x80);			//写SR寄存器,所有存储块取消写保护FRAM_WriteEnable(ENABLE);	//写存储块前需要使能写操作FRAM_Select(CS_ENABLE);SPIx_SendData(SPI1, WRITE);								//写指令SPIx_SendData(SPI1, (AddrOffset >> 8) & 0x00ff);		//写入起始地址高字节SPIx_SendData(SPI1, AddrOffset & 0x00ff);				//写入起始地址低字节do {SPIx_SendData(SPI1, *Data++);} while (--DataLen);FRAM_Select(CS_DISABLE);FRAM_WriteSR(0x8C);			//写SR寄存器,所有存储块使能写保护return 1;
}/*** @brief  FRAM* @note   * @param  None* @retval Noned* @author PWH @ CSDN Tyrion.Mon* @date   2021/3*/
uint16_t FRAM_Read(uint16_t AddrOffset, uint8_t *Data, uint16_t DataLen)
{if ((!DataLen) || (AddrOffset > FRAM_ADDR_MAX) || ((AddrOffset + DataLen - 1) > FRAM_ADDR_MAX))return 0;FRAM_Select(CS_ENABLE);SPIx_SendData(SPI1, READ);								//读指令SPIx_SendData(SPI1, (AddrOffset >> 8) & 0x00ff);		//写入起始地址高字节SPIx_SendData(SPI1, AddrOffset & 0x00ff);				//写入起始地址低字节do {*Data++ = SPIx_SendData(SPI1, 0x00);} while (--DataLen);FRAM_Select(CS_DISABLE);return 1;
}




FM24CL04B/FM24CL16B


一、电路


在这里插入图片描述

/** FM24CL04B* 1    0    1    0    A2    A1    A0    R/W** A2 A1 已硬件拉低, A0作页选择** FM24CL16B* 1    0    1    0    A2    A1    A0    R/W** 外部无地址选择引脚,A2 A1 A0作页选择**/

二、I2C驱动 (软 – ESP8266)

@ CSDN Tyrion.Mon#define I2C_MASTER_SCL_PIN			GPIO_Pin_5
#define I2C_MASTER_SCL_NUM			GPIO_NUM_5
#define I2C_MASTER_SCL_MODE			GPIO_MODE_OUTPUT_OD#define I2C_MASTER_SDA_PIN			GPIO_Pin_4
#define I2C_MASTER_SDA_NUM			GPIO_NUM_4
#define I2C_MASTER_SDA_MODE			GPIO_MODE_OUTPUT_OD#define I2C_MASTER_SCL_CLR() 		gpio_set_level(I2C_MASTER_SCL_NUM, 0)//i2c scl
#define I2C_MASTER_SCL_SET() 		gpio_set_level(I2C_MASTER_SCL_NUM, 1)#define I2C_MASTER_SDA_CLR() 		gpio_set_level(I2C_MASTER_SDA_NUM, 0)//i2c sda
#define I2C_MASTER_SDA_SET() 		gpio_set_level(I2C_MASTER_SDA_NUM, 1)//延时
void I2C_Master_delay(void)
{uint8_t t = 1;while (t--);
}
//SDA配置为输出
void I2C_Master_SDA_PIN_OUTPUT(void)
{
#if 0gpio_config_t gpio_cfg = {.pin_bit_mask = I2C_MASTER_SDA_PIN,.mode = GPIO_MODE_OUTPUT_OD,.pull_up_en = 0,.pull_down_en = 0,.intr_type = GPIO_INTR_DISABLE,};gpio_config(&gpio_cfg);
#elsegpio_set_direction(I2C_MASTER_SDA_NUM, GPIO_MODE_OUTPUT_OD);
#endif
}
//SDA配置为输入
void I2C_Master_SDA_PIN_INPUT(void)
{
#if 0gpio_config_t gpio_cfg = {.pin_bit_mask = I2C_MASTER_SDA_PIN,.mode = GPIO_MODE_INPUT,.pull_up_en = 0,.pull_down_en = 0,.intr_type = GPIO_INTR_DISABLE,};gpio_config(&gpio_cfg);
#elsegpio_set_direction(I2C_MASTER_SDA_NUM, GPIO_MODE_INPUT);
#endif
}
//读取SDA输入电平
uint8_t I2C_Master_SDA_PIN_GET(void)
{return gpio_get_level(I2C_MASTER_SDA_NUM);
}
//起始信号
void I2C_Master_Start(void)
{I2C_Master_SDA_PIN_OUTPUT();I2C_MASTER_SDA_SET();I2C_MASTER_SCL_SET();I2C_Master_delay();I2C_MASTER_SDA_CLR();I2C_Master_delay();I2C_MASTER_SCL_CLR();I2C_Master_delay();
}
//结束信号
void I2C_Master_Stop(void)
{I2C_Master_SDA_PIN_OUTPUT();I2C_MASTER_SDA_CLR();I2C_MASTER_SCL_SET();I2C_Master_delay();I2C_MASTER_SDA_SET();
}
//发送ack
void I2C_Master_Ack(void)
{I2C_Master_SDA_PIN_OUTPUT();I2C_MASTER_SDA_CLR();I2C_MASTER_SCL_SET();I2C_Master_delay();I2C_MASTER_SCL_CLR();I2C_Master_delay();
}
//发送nack
void I2C_Master_NAck(void)
{I2C_Master_SDA_PIN_OUTPUT();I2C_MASTER_SDA_SET();I2C_MASTER_SCL_SET();I2C_Master_delay();I2C_MASTER_SCL_CLR();I2C_Master_delay();
}
//等待信号响应
uint8_t I2C_Master_WaitAck(void) //测数据信号的电平
{uint8_t ack;I2C_Master_SDA_PIN_INPUT();//I2C_MASTER_SDA_SET();//I2C_Master_delay();I2C_MASTER_SCL_SET();ack = I2C_Master_SDA_PIN_GET();I2C_Master_delay();I2C_MASTER_SCL_CLR();I2C_Master_delay();return ack;
}
//写入一个字节
void I2C_Master_Send_Byte(uint8_t dat)
{uint8_t i;I2C_Master_SDA_PIN_OUTPUT();for(i = 0; i < 8; i++){if(dat & 0x80)//将dat的8位从最高位依次写入{I2C_MASTER_SDA_SET();}else{I2C_MASTER_SDA_CLR();}I2C_Master_delay();I2C_MASTER_SCL_SET();I2C_Master_delay();I2C_MASTER_SCL_CLR();//将时钟信号设置为低电平dat <<= 1;}
}
//写入一个字节
void I2C_Master_Send_1Byte(uint8_t slave_addr, uint8_t reg_address, uint8_t dat)
{I2C_Master_Start();I2C_Master_Send_Byte(slave_addr);I2C_Master_WaitAck();I2C_Master_Send_Byte(reg_address);I2C_Master_WaitAck();I2C_Master_Send_Byte(dat);I2C_Master_WaitAck();I2C_Master_Stop();
}
//写入n个字节
void I2C_Master_Send_Bytes(uint8_t slave_addr, uint8_t reg_address, uint8_t *dat, uint16_t len)
{uint16_t i = 0;I2C_Master_Start();I2C_Master_Send_Byte(slave_addr);I2C_Master_WaitAck();I2C_Master_Send_Byte(reg_address);I2C_Master_WaitAck();for (i = 0; i < len; i++){I2C_Master_Send_Byte(dat[i++]);I2C_Master_WaitAck();}I2C_Master_Stop();
}
//读一个字节
void I2C_Master_Read_Byte(uint8_t *dat)
{uint8_t i;*dat = 0;I2C_Master_SDA_PIN_INPUT();for(i = 0; i < 8; i++){I2C_MASTER_SCL_SET();I2C_Master_delay();*dat <<= 1;if (I2C_Master_SDA_PIN_GET())*dat |= 0x01;I2C_MASTER_SCL_CLR();I2C_Master_delay();}
}
void I2C_Master_Init(void)
{gpio_config_t gpio_cfg;gpio_cfg.pin_bit_mask = I2C_MASTER_SCL_PIN | I2C_MASTER_SDA_PIN;gpio_cfg.mode = I2C_MASTER_SCL_MODE;gpio_cfg.pull_up_en = 0;gpio_cfg.pull_down_en = 0;gpio_cfg.intr_type = GPIO_INTR_DISABLE;gpio_config(&gpio_cfg);I2C_MASTER_SCL_SET();I2C_MASTER_SDA_SET();
}
#define FRAM_FM24CL04B						0	//4K bit / 512字节
#define FRAM_FM24CL16B						1	//16K bit / 2K字节#define FRAM_FM24CLxx						FRAM_FM24CL16B#define FRAM_I2C_ADDR						0xA0
#if (FRAM_FM24CLxx == FRAM_FM24CL04B)	//2pages x 256bytes#define FRAM_PAGE_MAX						2#define FRAM_PAGE_BYTES_MAX					256#define FRAM_DATA_ADDR_END					0x1FF
#elif (FRAM_FM24CLxx == FRAM_FM24CL16B)	//8pages x 256bytes#define FRAM_PAGE_MAX						8#define FRAM_PAGE_BYTES_MAX					256#define FRAM_DATA_ADDR_END					0x7FF
#endif/*** @名称: FRAM_WriteBytes* @描述: FM24CL04B 同一页写入多个字节	256字节x2页* @参数:* @参数:* @日期:2023* @返回: bool**/
bool FRAM_WriteBytes(uint8_t *pBytes, uint32_t framStartAddress, uint32_t dataLenght)
{uint8_t page;if (framStartAddress > FRAM_DATA_ADDR_END) return false;page = framStartAddress >> 8;if ((page + 1) > FRAM_PAGE_MAX) return false;I2C_Master_Start();I2C_Master_Send_Byte(FRAM_I2C_ADDR | ((page << 1) & 0x0E) | 0x00);I2C_Master_WaitAck();I2C_Master_Send_Byte(0xFF & framStartAddress);I2C_Master_WaitAck();for (uint32_t i = 0; i < dataLenght; i++){I2C_Master_Send_Byte(pBytes[i]);I2C_Master_WaitAck();}I2C_Master_Stop();return true;
}/*** @名称: FRAM_ReadBytes* @描述: FM24CL04B 同一页读多个字节	256字节x2页* @参数:* @参数:* @日期:2023* @返回: bool**/
bool FRAM_ReadBytes(uint8_t *pBytes, uint32_t framStartAddress, uint32_t dataLenght)
{uint8_t page;if (framStartAddress > FRAM_DATA_ADDR_END) return false;page = framStartAddress >> 8;if ((page + 1) > FRAM_PAGE_MAX) return false;I2C_Master_Start();I2C_Master_Send_Byte(FRAM_I2C_ADDR | ((page << 1) & 0x0E) | 0x00);I2C_Master_WaitAck();I2C_Master_Send_Byte(framStartAddress & 0xFF);I2C_Master_WaitAck();I2C_Master_Start();I2C_Master_Send_Byte(FRAM_I2C_ADDR | ((page << 1) & 0x0E) | 0x01);I2C_Master_WaitAck();do{I2C_Master_Read_Byte(pBytes);pBytes++;if (dataLenght == 1) {I2C_Master_NAck();}else {I2C_Master_Ack();}}while(--dataLenght);I2C_Master_Stop();return true;
}读写示例:
uint8_t datArray[10];
FRAM_WriteBytes(datArray, 0, sizeof(datArray));		//写page0第0-9
FRAM_WriteBytes(datArray, 256, sizeof(datArray));	//写page1第0-9
FRAM_WriteBytes(datArray, 512, sizeof(datArray));	//写page2第0-9FRAM_ReadBytes(datArray, 0, sizeof(datArray));		//读page0第0-9
FRAM_ReadBytes(datArray, 256, sizeof(datArray));	//读page1第0-9
FRAM_ReadBytes(datArray, 512, sizeof(datArray));	//读page2第0-9

三、I2C驱动 (硬 – STM32F103)


@ CSDN Tyrion.Mon
/*** @名称: FRAM_Init* @描述: FRAM IO初始化  i2c配置* @参数: * @参数: * @日期:2019* @返回: bool**/
bool FRAM_Init(void)
{I2C_InitTypeDef   I2C_InitStruct;GPIO_InitTypeDef  GPIO_InitStruct;RCC_APB2PeriphClockCmd(FRAM_GPIO_CLK,ENABLE);RCC_APB1PeriphClockCmd(FRAM_I2C_CLK, ENABLE);I2C_InitStruct.I2C_ClockSpeed = 100000;	I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;	//该参数只有在 I2C 工作在快速模式(时钟工作频率高于 100KHz)下才有意义。I2C_InitStruct.I2C_OwnAddress1 = 0x75;I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_Init(I2C1, &I2C_InitStruct);I2C_Cmd(FRAM_I2C, ENABLE);GPIO_InitStruct.GPIO_Pin =  FRAM_SCL_PIN | FRAM_SDA_PIN;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;               GPIO_Init(FRAM_GPIO, &GPIO_InitStruct);GPIO_SetBits(FRAM_GPIO, FRAM_SCL_PIN);GPIO_SetBits(FRAM_GPIO, FRAM_SDA_PIN);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;               //先把GPIO设为推挽输出并拉倒高电平再转设为复用开漏输出,这样可以有效解决I2C设备死锁的问题???GPIO_Init(FRAM_GPIO, &GPIO_InitStruct);return true;
}
/*** @名称: FRAM_WriteBytes* @描述: FM24CL04B 同一页写入多个字节	256字节x2页* @参数: * @参数: * @日期:2019* @返回: bool**/
bool FRAM_WriteBytes(uint8_t framPage, uint8_t *pBytes, uint8_t framStartAddress, uint8_t dataLenght)
{if(framPage > 1 || !dataLenght) return false;if(framStartAddress + dataLenght > 256) return false;/* Send START condition */I2C_GenerateSTART(FRAM_I2C, ENABLE);/* Test on EV5 and clear it */while(I2C_CheckEvent(FRAM_I2C, I2C_EVENT_MASTER_MODE_SELECT) == ERROR);//EV5事件被检测到,发送设备地址I2C_Send7bitAddress(FRAM_I2C, 0xA0 | (FRAM_ADDRESS << 2) | (framPage << 1), I2C_Direction_Transmitter);/* Test on EV6 and clear it */while(I2C_CheckEvent(FRAM_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) == ERROR);//EV6事件被检测到,发送要操作的存储单元地址I2C_SendData (FRAM_I2C, framStartAddress);/* Test on EV8 and clear it */while(I2C_CheckEvent(FRAM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) == ERROR);do{//EV8事件被检测到,发送要存储的数据I2C_SendData (FRAM_I2C, *pBytes++);/* Test on EV8 and clear it */while(I2C_CheckEvent(FRAM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) == ERROR);}while(--dataLenght);/* Send STOP condition */I2C_GenerateSTOP(FRAM_I2C, ENABLE);return true;
}/*** @名称: FRAM_ReadBytes* @描述: FM24CL04B 同一页读多个字节	256字节x2页* @参数: * @参数: * @返回: bool**/
bool FRAM_ReadBytes(uint8_t framPage, uint8_t *pBytes, uint8_t framStartAddress, uint8_t dataLenght)
{if(framPage > 1 || !dataLenght) return false;if(framStartAddress + dataLenght > 256) return false;/* Send START condition */I2C_GenerateSTART(FRAM_I2C, ENABLE);/* Test on EV5 and clear it */while(I2C_CheckEvent(FRAM_I2C, I2C_EVENT_MASTER_MODE_SELECT) == ERROR);//EV5事件被检测到,发送设备地址I2C_Send7bitAddress(FRAM_I2C, 0xA0 | (FRAM_ADDRESS << 2) | (framPage << 1), I2C_Direction_Transmitter);/* Test on EV6 and clear it */while(I2C_CheckEvent(FRAM_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) == ERROR);//EV6事件被检测到,发送要操作的存储单元地址I2C_SendData (FRAM_I2C, framStartAddress);/* Test on EV8 and clear it */while(I2C_CheckEvent(FRAM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) == ERROR);/* Send START condition */I2C_GenerateSTART(FRAM_I2C, ENABLE);/* Test on EV5 and clear it */while(I2C_CheckEvent(FRAM_I2C, I2C_EVENT_MASTER_MODE_SELECT) == ERROR);//EV5事件被检测到,发送设备地址I2C_Send7bitAddress(FRAM_I2C, 0xA0 | (FRAM_ADDRESS << 2) | (framPage << 1), I2C_Direction_Receiver);/* Test on EV6 and clear it */while(I2C_CheckEvent(FRAM_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) == ERROR);do{if(dataLenght == 1){I2C_AcknowledgeConfig (FRAM_I2C, DISABLE);}//EV7事件被检测到	while(I2C_CheckEvent(FRAM_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED ) == ERROR);//EV8事件被检测到,发送要存储的数据*pBytes++ = I2C_ReceiveData (FRAM_I2C);}while(--dataLenght);/* Send STOP condition */I2C_GenerateSTOP(FRAM_I2C, ENABLE);I2C_AcknowledgeConfig (FRAM_I2C, ENABLE);return true;
}读写示例:
uint8_t FRAM_ENERGY_BANK[10];
FRAM_ReadBytes(0, FRAM_ENERGY_BANK, 0x00, 10);	//读page0第0-9个数据
FRAM_ReadBytes(1, FRAM_ENERGY_BANK, 0x00, 10);	//读page1第0-9个数据FRAM_WriteBytes(0, FRAM_ENERGY_BANK, 0x00, 10);	//写page0第0-9个数据
FRAM_WriteBytes(1, FRAM_ENERGY_BANK, 0x00, 10);	//写page1第0-9个数据

这篇关于FRAM铁电存储器FM25W256 | FM24CL04B | FM24CL16B编程实现读写存取数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/191932

相关文章

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Java easyExcel实现导入多sheet的Excel

《JavaeasyExcel实现导入多sheet的Excel》这篇文章主要为大家详细介绍了如何使用JavaeasyExcel实现导入多sheet的Excel,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录1.官网2.Excel样式3.代码1.官网easyExcel官网2.Excel样式3.代码

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Golang如何用gorm实现分页的功能

《Golang如何用gorm实现分页的功能》:本文主要介绍Golang如何用gorm实现分页的功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景go库下载初始化数据【1】建表【2】插入数据【3】查看数据4、代码示例【1】gorm结构体定义【2】分页结构体