I2C协议—读写EEPROM(24Cxx为例)
STM32 I2C协议详解与应用实践-CSDN博客
实际项目中移植IIC协议及读写EEprom代码:
/* AT24C08,写次数达100万次SOC ,2500次充放电次数,需要500万次记录,需存储均衡
每页*/#include "FreeRTOS.h"
#include "task.h"
#include "24C08.h"
#include "CortrolMain.h"//#define OP_READ 0xa1 // ?÷?tμ??·ò??°?áè?2ù×÷,0xa1?′?a1010 0001B
#define EE_ADDR 0xa0 // ?÷?tμ??·ò??°D′è?2ù×÷,0xa1?′?a1010 0000B#include "include.h"
#define EE_SCL_PIN PTB2 //模拟IIC的SCL信号 1.修改引脚即可修改IIC接口
#define EE_SDA_PIN PTC13 //模拟IIC的SDA信号#define EE_SDA_IN() GPIO_PDDR_REG(GPIOX[EE_SDA_PIN>> 5]) &= ~(1 << (EE_SDA_PIN&0x1f)); //GPIO_PinSetDir(EE_SDA_PIN, 0); //输入
#define EE_SDA_OUT() GPIO_PDDR_REG(GPIOX[EE_SDA_PIN>> 5]) |= (1 << (EE_SDA_PIN&0x1f)); //GPIO_PinSetDir(EE_SDA_PIN, 1); //输出#define EE_SCK_OUT() GPIO_PDDR_REG(GPIOX[EE_SCL_PIN>> 5]) |= (1 << (EE_SCL_PIN&0x1f)); //GPIO_PinSetDir(EE_SDA_PIN, 1); //输出#define EE_IIC_SCL PTB2_OUT //SCL 2.修改引脚即可修改IIC接口
#define EE_IIC_SDA PTC13_OUT //SDA
#define EE_READ_SDA PTC13_INT //输入SDA /******************************************************************************
*函 数:void EE_IIC_Delay(void)
*功 能:IIC延时
*参 数:无
*返回值:无
*备 注: 移植时只需要将EE_IIC_Delay()换成自己的延时即可
*******************************************************************************/
void EE_IIC_Delay(uint8_t us)
{for(int i = 0; i < 20; i++) {__asm("NOP");//core bus 160M 情况下大概IIC速率 400K}
}
/******************************************************************************
*函 数:void IIC_Init(void)
*功 能:IIC初始化
*参 数:无
*返回值:无
*备 注:无
*******************************************************************************/void EE_IIC_Init(void)
{ gpio_init(EE_SCL_PIN,GPO,1) ;gpio_init(EE_SDA_PIN,GPO,1) ;EE_SCK_OUT();EE_SDA_OUT();EE_IIC_SCL=1;EE_IIC_SDA=1;
}void EE_IIC_Start(void)
{EE_SDA_OUT(); //sda线输出 EE_IIC_SDA=1; EE_IIC_SCL=1;EE_IIC_Delay(4);EE_IIC_SDA=0; //START:when CLK is high,DATA change form high to low EE_IIC_Delay(4);EE_IIC_SCL=0; //钳住I2C总线,准备发送或接收数据
}void EE_IIC_Stop(void)
{EE_SDA_OUT(); //sda线输出EE_IIC_SCL=0;EE_IIC_SDA=0; //STOP:when CLK is high DATA change form low to highEE_IIC_Delay(4);EE_IIC_SCL=1; EE_IIC_SDA=1; //发送I2C总线结束信号EE_IIC_Delay(4);
}uint8_t EE_IIC_WaitAck(void)
{uint8_t ucErrTime=0;EE_SDA_IN(); //SDA设置为输入 (从机给一个低电平做为应答) EE_IIC_SDA=1;EE_IIC_Delay(1); EE_IIC_SCL=1;EE_IIC_Delay(1);; while(EE_READ_SDA){ucErrTime++;if(ucErrTime>250){EE_IIC_Stop();return 1;}}EE_IIC_SCL=0; //时钟输出0 return 0;
} void EE_IIC_Ack(void)
{EE_IIC_SCL=0;EE_SDA_OUT();EE_IIC_SDA=0;EE_IIC_Delay(1);EE_IIC_SCL=1;EE_IIC_Delay(2);EE_IIC_SCL=0;
}void EE_IIC_NAck(void)
{EE_IIC_SCL=0;EE_SDA_OUT();EE_IIC_SDA=1;EE_IIC_Delay(1);EE_IIC_SCL=1;EE_IIC_Delay(1);EE_IIC_SCL=0;
} void EE_IIC_SendByte(uint8_t data)
{ uint8_t t; EE_SDA_OUT(); EE_IIC_SCL=0; //拉低时钟开始数据传输for(t=0;t<8;t++){ EE_IIC_SDA=(data&0x80)>>7;EE_IIC_Delay(1); EE_IIC_SCL=1;data<<=1;EE_IIC_Delay(1);EE_IIC_SCL=0; }EE_IIC_Delay(1);
} void EE_IIC_PageSendByte(uint16_t data)
{ uint8_t t,DataIn; EE_SDA_OUT(); EE_IIC_SCL=0; //拉低时钟开始数据传输DataIn=data&0xff;for(t=0;t<8;t++){ EE_IIC_SDA=(DataIn&0x80)>>7;EE_IIC_Delay(1); EE_IIC_SCL=1;data<<=1;EE_IIC_Delay(1);EE_IIC_SCL=0; }DataIn=(data>>8)&0xff;for(t=0;t<8;t++){ EE_IIC_SDA=(DataIn&0x80)>>7;EE_IIC_Delay(1); EE_IIC_SCL=1;data<<=1;EE_IIC_Delay(1);EE_IIC_SCL=0; }EE_IIC_Delay(1);
} uint8_t EE_IIC_ReadByte(uint8_t ack)
{uint8_t i,receive=0;EE_SDA_IN(); //SDA设置为输入模式 等待接收从机返回数据for(i=0;i<8;i++ ){EE_IIC_SCL=0; EE_IIC_Delay(1);EE_IIC_SCL=1;receive<<=1;if(EE_READ_SDA)receive++; //从机发送的电平EE_IIC_Delay(1); } if(ack)EE_IIC_Ack(); //发送ACK elseEE_IIC_NAck(); //发送nACK return receive;
}uint8_t EE_IIC_ReadByteFromSlave(uint8_t I2C_Addr,uint8_t reg,uint8_t *buf)
{EE_IIC_Start(); EE_IIC_SendByte(I2C_Addr); //发送从机地址if(EE_IIC_WaitAck()) //如果从机未应答则数据发送失败{EE_IIC_Stop();return 1;}EE_IIC_SendByte(reg); //发送寄存器地址EE_IIC_WaitAck(); EE_IIC_Start();EE_IIC_SendByte(I2C_Addr+1); //进入接收模式 EE_IIC_WaitAck();*buf=EE_IIC_ReadByte(0); EE_IIC_Stop(); //产生一个停止条件return 0;
}uint8_t EE_EE_IIC_SendByteToSlave(uint8_t I2C_Addr,uint8_t reg,uint8_t data)
{EE_IIC_Start();EE_IIC_SendByte(I2C_Addr); //发送从机地址if(EE_IIC_WaitAck()){EE_IIC_Stop();return 1; //从机地址写入失败}EE_IIC_SendByte(reg); //发送寄存器地址EE_IIC_WaitAck(); EE_IIC_SendByte(data); if(EE_IIC_WaitAck()){EE_IIC_Stop(); return 1; //数据写入失败}EE_IIC_Stop(); //产生一个停止条件return 0;
}uint8_t EE_IIC_WriteByteToSlave(uint8_t I2C_Addr,uint8_t reg,uint8_t data)
{EE_IIC_Start();EE_IIC_SendByte(I2C_Addr); //发送从机地址if(EE_IIC_WaitAck()){EE_IIC_Stop();return 1; //从机地址写入失败}EE_IIC_SendByte(reg); //发送寄存器地址EE_IIC_WaitAck(); EE_IIC_SendByte(data); if(EE_IIC_WaitAck()){EE_IIC_Stop(); return 1; //数据写入失败}EE_IIC_Stop(); //产生一个停止条件return 0;
}
uint8_t EE_IIC_ReadMultByteFromSlave(uint8_t dev, uint8_t reg, uint8_t length, uint8_t *data)
{uint8_t count = 0;uint8_t temp;EE_IIC_Start();EE_IIC_SendByte(dev); //发送从机地址if(EE_IIC_WaitAck()){EE_IIC_Stop(); return 1; //从机地址写入失败}EE_IIC_SendByte(reg); //发送寄存器地址EE_IIC_WaitAck(); EE_IIC_Start();EE_IIC_SendByte(dev+1); //进入接收模式 EE_IIC_WaitAck();for(count=0;count<length;count++){if(count!=(length-1))temp = EE_IIC_ReadByte(1); //带ACK的读数据else temp = EE_IIC_ReadByte(0); //最后一个字节NACKdata[count] = temp;}EE_IIC_Stop(); //产生一个停止条件return 0;
}/******************************************************************************
*函 数:uint8_t IICwriteBytes(uint8_t dev, uint8_t reg, uint8_t length, uint8_t* data)
*功 能:将多个字节写入指定设备 指定寄存器
*参 数:dev 目标设备地址
reg 寄存器地址
length 要写的字节数
*data 要写入的数据将要存放的指针
*返回值:1成功 0失败
*备 注:无
*******************************************************************************/
uint8_t EE_IIC_WriteMultByteToSlave(uint8_t dev, uint8_t reg, uint8_t length, uint8_t* data)
{ uint8_t count = 0;EE_IIC_Start();EE_IIC_SendByte(dev); //发送从机地址if(EE_IIC_WaitAck()){EE_IIC_Stop();return 1; //从机地址写入失败}EE_IIC_SendByte(reg&0xff); //发送寄存器地址,就是页地址EE_IIC_WaitAck(); for(count=0;count<length;count++){EE_IIC_SendByte(data[count]); if(EE_IIC_WaitAck()) //每一个字节都要等从机应答{EE_IIC_Stop();return 1; //数据写入失败}}EE_IIC_Stop(); //产生一个停止条件return 0;
}uint8_t EEPROM_PageWrite(uint8 PageNum, uint8_t length, uint8_t* data)
{uint8 Addr,PageAddr,i;uint16 j;//每页16个字节,24c08一共64页,页地址是页号*16/*if(PageNum<16)//0~15{PageAddr=16*PageNum;Addr=0xA0;EE_IIC_WriteMultByteToSlave(Addr,PageAddr,length,data) ;}else if(PageNum>=16 && PageNum<=31){Addr=0xA0+((((PageNum*16)>>8)&0x03)<<1);PageAddr=(PageNum*16)&0xff;EE_IIC_WriteMultByteToSlave(Addr,PageAddr,length,data) ;}else if(PageNum>=32 && PageNum<=47){Addr=0xA0+((((PageNum*16)>>8)&0x03)<<1);PageAddr=(PageNum*16)&0xff;EE_IIC_WriteMultByteToSlave(Addr,PageAddr,length,data) ;}else if(PageNum>=48 && PageNum<=63){Addr=0xA0+((((PageNum*16)>>8)&0x03)<<1);PageAddr=(PageNum*16)&0xff;EE_IIC_WriteMultByteToSlave(Addr,PageAddr,length,data) ;}*///cht- eeprom进行写的时候,MP进行接地处理EEPROMMP(0);
// vTaskDelay( 2/portTICK_RATE_MS );EE_IIC_Delay(20);DisableInterrupts;Addr=0xA0+((((PageNum*16)>>8)&0x07)<<1);PageAddr=(PageNum*16)&0xff;EE_IIC_WriteMultByteToSlave(Addr,PageAddr,length,data) ;EnableInterrupts;for(i=0;i<6;i++){for(j=0;j<500;j++){EE_IIC_Delay(1);}
// vTaskDelay( 1/portTICK_RATE_MS );}EEPROMMP(1);//cht-恢复高电平,可以读return 1;
}uint8_t EEPROM_PageRead(uint8 PageNum, uint8_t length, uint8_t* data)
{uint8 Addr,PageAddr;//每页16个字节,24c08一共64页,页地址是页号*16/*if(PageNum<16)//0~15{PageAddr=16*PageNum;Addr=0xA0;EE_IIC_ReadMultByteFromSlave(Addr,PageAddr,length,data) ;}else if(PageNum>=16 && PageNum<=31){// PageAddr=(16*PageNum)%256;Addr=0xA0+((((PageNum*16)>>8)&0x03)<<1);PageAddr=(PageNum*16)&0xff;EE_IIC_ReadMultByteFromSlave(Addr,PageAddr,length,data) ;}else if(PageNum>=32 && PageNum<=47){Addr=0xA0+((((PageNum*16)>>8)&0x03)<<1);PageAddr=(PageNum*16)&0xff;EE_IIC_ReadMultByteFromSlave(Addr,PageAddr,length,data) ;}else if(PageNum>=48 && PageNum<=63){Addr=0xA0+((((PageNum*16)>>8)&0x03)<<1);PageAddr=(PageNum*16)&0xff;EE_IIC_ReadMultByteFromSlave(Addr,PageAddr,length,data) ;}*/Addr=0xA0+((((PageNum*16)>>8)&0x07)<<1);PageAddr=(PageNum*16)&0xff;EE_IIC_ReadMultByteFromSlave(Addr,PageAddr,length,data) ;return 1; }#define _24C08 4
#define PAGE_SIZE 16
#define PAGE_SIZE_REM 0x0F
#define MEM_SIZE 0x03ff#define MAX_ADDR ( (MEM_SIZE+1)*DEV_24CXX_NUM-1 )
//芯片常量
#define DEV_24CXX_MAIN_ADDR 0xA0
#define DEV_24CXX_READ 0x01
#define DEV_24CXX_WRITE 0x00
#define IIC_SEND_ACK 0x10
#define IIC_SEND_NOACK 0x11#define IIC_STATE_NOACK 0x20
#define IIC_STATE_ACK 0x21uint16 HardAddr;
void _24CXXX_AddrProcess(unsigned int Addr)
{HardAddr = 0x00;
}void _24CXXX_WriteByte(unsigned int Addr,unsigned char Data)
{_24CXXX_AddrProcess(Addr);Addr &= MEM_SIZE; EE_IIC_Start();EE_IIC_SendByte(DEV_24CXX_MAIN_ADDR|(HardAddr<<1)|DEV_24CXX_WRITE);EE_IIC_SendByte( ((unsigned char)(Addr>>8)) );EE_IIC_SendByte( ((unsigned char)Addr) );EE_IIC_SendByte( Data );EE_IIC_Stop();}unsigned char _24CXXX_ReadByte(unsigned int Addr)
{unsigned char temp;_24CXXX_AddrProcess(Addr);Addr &= MEM_SIZE;EE_IIC_Start();EE_IIC_SendByte(DEV_24CXX_MAIN_ADDR|(HardAddr<<1)|DEV_24CXX_WRITE);EE_IIC_SendByte( ((unsigned char)(Addr>>8)) );EE_IIC_SendByte( ((unsigned char)Addr) );EE_IIC_Start();EE_IIC_SendByte(DEV_24CXX_MAIN_ADDR|(HardAddr<<1)|DEV_24CXX_READ);temp = EE_IIC_ReadByte(IIC_SEND_NOACK);EE_IIC_Stop();return temp;
}void _24CXXX_WriteBytes(unsigned int StartAddr,unsigned char *Data,int DataNum)
{unsigned char Num;unsigned int i;unsigned int y;unsigned int yy;_24CXXX_AddrProcess(StartAddr);yy = StartAddr & MEM_SIZE;y = yy&PAGE_SIZE_REM; //=StartAddr/PAGE_SIZEy = PAGE_SIZE - y; //要写的第一页中有多少个数据if( y <= PAGE_SIZE ) //写第一页(可能不到一页,以使页对齐){EE_IIC_Start();EE_IIC_SendByte( DEV_24CXX_MAIN_ADDR|(HardAddr<<1)|DEV_24CXX_WRITE );EE_IIC_SendByte( ((unsigned char)(yy>>8)) );EE_IIC_SendByte( ((unsigned char)yy) );for(i=0;i<y;i++){if( i>=DataNum ){break;}EE_IIC_SendByte( *(Data++) ); }}IIC_Stop();//DelayMs(10);vTaskDelay( 20/portTICK_RATE_MS );DataNum -= y; //还有多少数据未写i = 0;Num = 0; //用于记录已经写了多少页while( DataNum>0 ) //数据未写完{if( i == 0 ){yy = StartAddr+y+Num*PAGE_SIZE;_24CXXX_AddrProcess(yy);yy = yy & MEM_SIZE;EE_IIC_Start();EE_IIC_SendByte( DEV_24CXX_MAIN_ADDR|(HardAddr<<1)|DEV_24CXX_WRITE );EE_IIC_SendByte( ((unsigned char)(yy>>8)) );EE_IIC_SendByte( ((unsigned char)(yy)) );}EE_IIC_SendByte( *(Data++) );i++;if(i>=PAGE_SIZE ) //如果一页写完{i = 0;Num++;IIC_Stop();vTaskDelay( 20/portTICK_RATE_MS );}DataNum--;}if(i!=0x0000) //如果写结束时,并未到达页的最后,则需要补上停止位{EE_IIC_Stop();vTaskDelay( 20/portTICK_RATE_MS );}
}void _24CXXX_ReadBytes(unsigned int StartAddr,unsigned char *Data,int DataNum)
{unsigned char Num;unsigned int i;unsigned int y;unsigned int yy;_24CXXX_AddrProcess(StartAddr);yy = StartAddr & MEM_SIZE;y = yy&PAGE_SIZE_REM; //=StartAddr/PAGE_SIZEy = PAGE_SIZE - y; //要写的第一页中有多少个数据if( y <= PAGE_SIZE ) //写第一页(可能不到一页,以使页对齐){EE_IIC_Start();EE_IIC_SendByte( DEV_24CXX_MAIN_ADDR|(HardAddr<<1)|DEV_24CXX_WRITE );EE_IIC_SendByte( ((unsigned char)(StartAddr>>8)) );EE_IIC_SendByte( ((unsigned char)StartAddr) );EE_IIC_Start();EE_IIC_SendByte(DEV_24CXX_MAIN_ADDR|(HardAddr<<1)|DEV_24CXX_READ);for(i=0;i<y;i++){if( i>=DataNum ){break;}if( (i==DataNum-1)||(i==y-1) ) //如果是该页的最后一个数据,则NOACK*Data = EE_IIC_ReadByte(IIC_SEND_NOACK);else*Data = EE_IIC_ReadByte(IIC_SEND_ACK);Data++; }}EE_IIC_Stop();//DelayUs(20);DataNum -= y; //还有多少数据未写i = 0;Num = 0; //用于记录已经写了多少页while( DataNum>0 ) //数据未写完{if( i == 0 ){yy = StartAddr+y+Num*PAGE_SIZE;_24CXXX_AddrProcess(yy);yy = yy & MEM_SIZE;EE_IIC_Start();EE_IIC_SendByte( DEV_24CXX_MAIN_ADDR|(HardAddr<<1)|DEV_24CXX_WRITE );EE_IIC_SendByte( (unsigned char)(yy>>8) );EE_IIC_SendByte( (unsigned char)(yy) );EE_IIC_Start();EE_IIC_SendByte(DEV_24CXX_MAIN_ADDR|(HardAddr<<1)|DEV_24CXX_READ);}if( (i==PAGE_SIZE-1)||(DataNum==1) ) //如果是该页或要读的最后一个数据,则NOACK*Data = EE_IIC_ReadByte(IIC_SEND_NOACK);else*Data = EE_IIC_ReadByte(IIC_SEND_ACK);Data++;i++;if(i>=PAGE_SIZE ) //如果一页写完{i = 0;Num++;EE_IIC_Stop();//DelayUs(20);}DataNum--;}if(i!=0x0000) //如果写结束时,并未到达页的最后,则需要补上停止位{EE_IIC_Stop();}}
区分硬件IIC与软件IIC
一般使用软件模拟IIC,,可移植性高
一:模拟IIC与硬件IIC定义?
模拟I2C一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信波形。
硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用。
二:优缺点
1.硬件I2C的效率要远高于软件的,而软件I2C由于不受管脚限制,接口比较灵活。
2.模拟I2C 是通过GPIO,软件模拟寄存器的工作方式,而硬件(固件)I2C是直接调用内部寄存器进行配置。如果要从具体硬件上来看,可以去看下芯片手册。因为固件I2C的端口是固定的,所以会有所区别。
三:如何区分它们
可以看底层配置,比如IO口配置,如果配置了IO口的功能(IIC功能)那就是固件IIC,否则就是模拟
可以看IIC写函数,看里面有木有调用现成的函数或者给某个寄存器赋值,如果有,则肯定是固件IIC功能,没有的话肯定是数据一个bit一个bit模拟发生送的,肯定用到了循环,则为模拟。
根据代码量判断,模拟的代码量肯定比固件的要大。
相关文章:
I2C协议—读写EEPROM(24Cxx为例)
STM32 I2C协议详解与应用实践-CSDN博客 实际项目中移植IIC协议及读写EEprom代码: /* AT24C08,写次数达100万次SOC ,2500次充放电次数,需要500万次记录,需存储均衡 每页*/#include "FreeRTOS.h" #include "task.h" #incl…...
示例:JAVA调用deepseek
近日,国产AI DeepSeek在中国、美国的科技圈受到广泛关注,甚至被认为是大模型行业的最大“黑马”。在外网,DeepSeek被不少人称为“神秘的东方力量”。1月27日,DeepSeek应用登顶苹果美国地区应用商店免费APP下载排行榜,在…...
Linux系统命令无法使用(glib库相关问题)
1.背景描述 Yum强制安装了一些软件,安装软件成功无报错,完成后不久突然发现系统出问题了,所有的命令无法使用了,如ls、mv、cat等基本命令报错。 relocation error: /lib64/libpthread.so.0: symbol_libc_dl_error_tsd …...
Java 一键将 Word 文档转为 PDF
嘿,朋友们!在开发中,经常会碰到需要把 Word 文档转换成 PDF 格式的需求,像生成报告、合同啥的。Java 有不少好用的库能实现这个功能,下面就给大家介绍两种常见的方法,分别使用 Apache POI 和 Docx4J 结合 i…...
从基础到进阶:一文掌握排序、查找、动态规划与图算法的全面实现(C++代码实例解析)
引言 算法是计算机科学的核心,也是程序员解决复杂问题的利器。从基础的排序与查找到进阶的动态规划与图论算法,掌握这些技能不仅是提升编程能力的必经之路,更是解决实际问题的根本。本篇文章将通过 C 实现多个经典算法,包括排序、…...
Nginx反代Ollama接口跨域、无法逐字输出问题
场景 本地部署deepseek模型,用的Ollama管理,内网穿透到公网,在通过nginx反代ollama接口。 问题描述 跨域问题 nginx转发时请求头中需要加入origin,并且origin还要和ollama接口同源(协议、ip、端口一致)。…...
电脑黑屏按什么键恢复?电脑黑屏的解决办法
电脑黑屏的原因有很多,可能是硬件、软件、系统或者病毒等方面造成的。那么,当我们遇到电脑黑屏时,应该怎么做呢?有没有什么快捷的方法可以恢复正常呢?本文将为您介绍一些常见的电脑黑屏情况及其解决办法。 一、电脑开机…...
docker启动报错code=exited, status=1/FAILURE——问题排查
问题 在某台centos7机器上,启动docker服务 sudo systemctl start docker报下列错误: ● docker.service - Docker Application Container EngineLoaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)Active: …...
Kong故障转移参数配置
一、Passive Health Check Healthchecks.Passive.Unhealthy.HttpStatuses 含义: 列出了被认为是“不健康”的HTTP状态码。目的: 当健康检查(Healthcheck)返回这些状态码时,系统会认为服务不健康,并可能触…...
使用opencv解析视频,通过图片比对,筛选出每一帧视频的变化
记录瞬间 最近碰到一个问题,在客户端上操作时,存在背景判断的情况,对自动化实现此操作增加难度。 所以考虑到实际的使用,将一些计算机视觉技术加入到实际的使用中,来解决此问题。 import os import cv2 import numpy#…...
思翼遥控器疑问?
1.地面端与遥控端对频,地面端选择数传2为串口,天空端的UART2通过USB转TTL模块连接电脑,通过串口助手观察得有1Hz输出帧(开启遥控器APP时间段为10Hz),共21字节,请问,这个是什么含义&a…...
anaconda中可以import cv2,但是notebook中cv2 module not found
一、问题 anaconda中成功import cv2 但是jupyter notebook中却无法导入cv2 二、排查 anaconda中使用python路径如下: jupyter notebook中使用python路径如下: 可以发现路径不一致。 三、解决 ①查看可用的kernel ②选中想要修改的kernel,打…...
如何解决 Linux 文件系统挂载失败的问题
当遇到Linux文件系统挂载失败的问题时,您可以通过以下步骤来解决问题: 解决方法: 检查挂载点: 确保要挂载的目标文件系统存在,并且挂载点是正确的。检查挂载点是否已经被其他文件系统占用。 检查文件系统状态&#x…...
PHP填表统计预约打卡表单系统小程序
📋 填表统计预约打卡表单系统——专属定制,信息互动新纪元 📊 填表统计预约打卡表单系统,一款专为现代快节奏生活量身打造的多元化自定义表单统计小程序,集信息填表、预约报名、签到打卡、活动通知、报名投票、班级统…...
PAT乙级( 1009 说反话 1010 一元多项式求导)C语言版本超详细解析
1009 说反话 给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过 80的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母&#x…...
LVSNAT服务搭建
LVSNAT实验环境搭建 在虚拟机上,我的NAT模式ip划分为:172.25.254.0 仅主机模式IP为:192.168.0.0 拓补图如下 配置服务:LVS服务端添加两个网卡,分别为NAT模式和仅主机模式 LVS服务端配置: systemctl st…...
websocket自动重连封装
websocket自动重连封装 前端代码封装 import { ref, onUnmounted } from vue;interface WebSocketOptions {url: string;protocols?: string | string[];reconnectTimeout?: number; }class WebSocketService {private ws: WebSocket | null null;private callbacks: { [k…...
2. Mellanox 网卡的参数调优-LINK_TYPE_P1(GPU-AI-大模型,底层调优-测试)
命令详细分析 echo yes | sudo mlxconfig -d $line set LINK_TYPE_P1=1 这个命令用于设置 Mellanox 网卡设备的 LINK_TYPE_P1 参数为 1。以下是该命令的详细解析: 各部分解释 echo yes |: 这个部分通过管道将字符串 yes 传递给后续命令,以自动确认任何需要用户输入确认的…...
apisix网关ip-restriction插件使用说明
ip-restriction插件可以在网关层进行客户端请求ip拦截。 当然了,一般不推荐使用该方法,专业的事专业工具做。建议有条件,还是上防火墙或者waf来做。 官方文档:ip-restriction | Apache APISIX -- Cloud-Native API Gateway whit…...
使用 Docker 和 PM2 构建高并发 Node.js API 网关
在现代 Web 开发中,构建高并发、高可用的 API 网关是一个常见的需求。本文将介绍如何结合 Docker 和 PM2 构建一个高性能的 Node.js API 网关,并深入探讨分布式限流器的原理与实现。 1. 背景与需求 1.1 高并发 API 网关的挑战 在高并发场景下ÿ…...
现代前端工程化实践:高效构建的秘密
一、前端工程化错误监控 这种监控可以帮助开发人员及时发现和解决问题,提高应用程序的稳定性和可靠性。 1. Sentry:Sentry是一款开源的错误监控平台,可以监控前端、后端以及移动端应用程序中的错误和异常。Sentry提供了实时错误报告、错误分…...
react高级面试题
以下是一些React高级面试题: 一、组件相关 React组件的生命周期有哪些(类组件)?在函数组件中如何实现类似功能? 答案: 类组件生命周期: componentDidMount:组件挂载后调用ÿ…...
html 列动态布局
样式说明: /* 列动态布局,列之间以空格填充 */ li {display: flex;/* flex-direction: column; */justify-content: space-between; }...
C++小等于的所有奇数和=最大奇数除2加1的平方。
缘由 三种思路解题:依据算术推导得到一个规律:小等于的所有奇数和等于最大奇数除以2加1的平方。将在后续发布,总计有十种推导出来的实现代码。 int a 0,aa 1,aaa 0;cin >> a; while (aa<a) aaa aa, aa 2;cout << aaa;i…...
政采云业务网关实践:使用 Higress 统一替代 APISIX/Kong/Istio Ingress
作者:政采云基础架构团队技术专家 朱海峰(片风) 业务网关项目背景 由于一些历史的背景,政采云平台在网关建设上遇到一些问题: 容器网关配置较多,配置方式多样,运维压力较大: 配置…...
【嵌入式 Linux 音视频+ AI 实战项目】瑞芯微 Rockchip 系列 RK3588-基于深度学习的人脸门禁+ IPC 智能安防监控系统
前言 本文主要介绍我最近开发的一个个人实战项目,“基于深度学习的人脸门禁 IPC 智能安防监控系统”,全程满帧流畅运行。这个项目我目前全网搜了一圈,还没发现有相关类型的开源项目。这个项目只要稍微改进下,就可以变成市面上目前…...
安卓7以上抓包证书安装
安卓7以上抓包证书安装 fiddler 用户可以直接试试这个文件 前提是要root过了,如果是模拟器就很容易开启 前提:要有openssl工具,在linux一个指令就可以下载了:sudo apt-get install openssl,windons则是在https://www.openssl.org/…...
【C#】任务调度的实现原理与组件应用Quartz.Net
Quartz 是一个流行的开源作业调度库,最初由 Terracotta 开发,现在由 Terracotta 的一部分 Oracle 所有。它主要用于在 Java 应用程序中调度作业的执行。Quartz 使用了一种复杂的底层算法来管理任务调度,其中包括任务触发、执行、持久化以及集…...
C语言:深入了解指针4(超级详细)
看之前必须得掌握有一定指针的知识,不然会看不懂,如果有不懂的可以看我博客 指针1,指针2,指针3 这三个讲了指针全部的基础知识超级详细,这篇只要是讲一些指针练习题也是非常详细 1. sizeof和strlen的对⽐ 1. 基本定义…...
C#+Redis接收数据并定时3秒钟频率异步保存到数据库
要在C#中实现从Redis接收数据,并以每3秒的频率异步保存到数据库,你可以使用System.Threading.Tasks.Task.Delay或System.Timers.Timer来创建一个定时任务。不过,对于更复杂的定时和调度需求,System.Threading.Tasks.Timer或Quartz.NET等库可能更合适。 在这个场景中,由于…...
