STC15系列单片机通过串口多字节数据读写EEPROM操作
STC15系列单片机通过串口多字节数据读写EEPROM操作
- 📌相关篇《STC15系列单片机EEPROM读写示例》
⛳手册勘误信息注意事项
- ⚡在手册上面描述
STC15F2K60S2
及STC15L2K60S2系列单片机内部EEPROM还可以用MOVC指令读,但此时首地址不再是0000H,而是程序存储空间结束地址的下一个地址。 - 🔰实际上
STC15F2K60S2
型号单片机验证时发现,EEPROM起始扇区首地址:0x0000
-0x0200
2个扇区(1K=512X2),而不是像手册上描述的在CODE
区后面的2个扇区。 - ⚡对于IAP型号的单片机,EEPROM扇区在CODE(程序区)后面。
- 例如上面的程序编译信息,可以得知程序所占用的容量
code=551
,转换为扇区,就是需要占用2个扇区(2 X 512),对于IAP单片机,整个ROM区都可以作为eeprom使用,在不覆盖程序的情况下,从第3扇区作为eeprom的首地址:0x600
。
📝STC15系列单片机通过串口读写EEPROM示例
- ✨这里以
STC15F2K60S2
为烧录对象为例。采用22.1184
MHz,波特率:115200
- 程序代码
/*---------------------------------------------------------------------*/
/* --- STC MCU International Limited ----------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
/* --- Web: www.GXWMCU.com --------------------------------------------*/
/* --- QQ: 800003751 -------------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序 */
/*---------------------------------------------------------------------*//************* 本程序功能说明 **************测试说明通过串口对STC内部自带的EEPROM(FLASH)进行读写测试。对FLASH做扇区擦除、写入、读出的操作,命令指定地址。默认波特率: 115200,8,N,1.
默认主时钟: 22118400HZ.串口命令设置: (命令字母不区分大小写)W 0x8000 1234567890 --> 对0x8000地址写入字符1234567890.R 0x8000 10 --> 对0x8000地址读出10个字节数据. 注意:为了通用,程序不识别地址是否有效,用户自己根据具体的型号来决定。******************************************/#define MAIN_Fosc 22118400L //定义主时钟
#include "STC15Fxxxx.H"#define Baudrate1 115200L
#define Tmp_Length 70 //读写EEPROM缓冲长度#define UART1_BUF_LENGTH (Tmp_Length+9) //串口缓冲长度u8 RX1_TimeOut;
u8 TX1_Cnt; //发送计数
u8 RX1_Cnt; //接收计数
bit B_TX1_Busy; //发送忙标志u8 xdata RX1_Buffer[UART1_BUF_LENGTH]; //接收缓冲
u8 xdata tmp[Tmp_Length]; //EEPROM操作缓冲void UART1_config(u8 brt); // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
void PrintString1(u8 *puts);
void UART1_TxByte(u8 dat);
void delay_ms(u8 ms);
u8 CheckData(u8 dat);
u16 GetAddress(void);
u8 GetDataLength(void);
void EEPROM_SectorErase(u16 EE_address);
void EEPROM_read_n(u16 EE_address,u8 *DataAddress,u8 length);
u8 EEPROM_write_n(u16 EE_address,u8 *DataAddress,u8 length);/********************* 主函数 *************************/
void main(void)
{u8 i,j;u16 addr;u8 status;P0M1 = 0; P0M0 = 0; //设置为准双向口P1M1 = 0; P1M0 = 0; //设置为准双向口P2M1 = 0; P2M0 = 0; //设置为准双向口P3M1 = 0; P3M0 = 0; //设置为准双向口P4M1 = 0; P4M0 = 0; //设置为准双向口P5M1 = 0; P5M0 = 0; //设置为准双向口P6M1 = 0; P6M0 = 0; //设置为准双向口P7M1 = 0; P7M0 = 0; //设置为准双向口UART1_config(1); // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.EA = 1; //允许总中断PrintString1("STC15F2K60S2系列单片机EEPROM测试程序, 串口命令设置如下示例:\r\n"); //SUART1发送一个字符串PrintString1("W 0x8000 1234567890 --> 对0x8000地址写入字符1234567890.\r\n"); //SUART1发送一个字符串PrintString1("R 0x8000 10 --> 对0x8000地址读出10个字节数据.\r\n"); //SUART1发送一个字符串while(1){delay_ms(1);if(RX1_TimeOut > 0) //超时计数{if(--RX1_TimeOut == 0){// for(i=0; i<RX1_Cnt; i++) UART1_TxByte(RX1_Buffer[i]); //把收到的数据原样返回,用于测试status = 0xff; //状态给一个非0值if((RX1_Cnt >= 10) && (RX1_Buffer[1] == ' ') && (RX1_Buffer[8] == ' ')) //最短命令为10个字节{for(i=0; i<8; i++){if((RX1_Buffer[i] >= 'a') && (RX1_Buffer[i] <= 'z')) RX1_Buffer[i] = RX1_Buffer[i] - 'a' + 'A'; //小写转大写}addr = GetAddress();if(addr < 63488) //限制在0~123扇区{if(RX1_Buffer[0] == 'W') //写入N个字节{j = RX1_Cnt - 9;if(j > Tmp_Length) j = Tmp_Length; //越界检测EEPROM_SectorErase(addr); //擦除扇区i = EEPROM_write_n(addr,&RX1_Buffer[9],j); //写N个字节if(i == 0){PrintString1("已写入");if(j >= 100) {UART1_TxByte(j/100+'0'); j = j % 100;}if(j >= 10) {UART1_TxByte(j/10+'0'); j = j % 10;}UART1_TxByte(j%10+'0');PrintString1("字节数据!\r\n");}else PrintString1("写入错误!\r\n");status = 0; //命令正确}else if(RX1_Buffer[0] == 'R') //PC请求返回N字节EEPROM数据{j = GetDataLength();if(j > Tmp_Length) j = Tmp_Length; //越界检测if(j > 0){PrintString1("读出");UART1_TxByte(j/10+'0');UART1_TxByte(j%10+'0');PrintString1("个字节数\xfd据如下:\r\n");EEPROM_read_n(addr,tmp,j);for(i=0; i<j; i++) UART1_TxByte(tmp[i]);UART1_TxByte(0x0d);UART1_TxByte(0x0a);status = 0; //命令正确}}}}if(status != 0) PrintString1("命令错误!\r\n");RX1_Cnt = 0; //清除字节数}}}
}
//========================================================================//========================================================================
// 函数: void delay_ms(unsigned char ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void delay_ms(u8 ms)
{unsigned int i;do{i = MAIN_Fosc / 14000;while(--i) ; //14T per loop}while(--ms);
}//========================================================================
// 函数: u8 CheckData(u8 dat)
// 描述: 将字符"0~9,A~F或a~f"转成十六进制.
// 参数: dat: 要检测的字符.
// 返回: 0x00~0x0F为正确. 0xFF为错误.
// 版本: V1.0, 2012-10-22
//========================================================================
u8 CheckData(u8 dat)
{if((dat >= '0') && (dat <= '9')) return (dat-'0');if((dat >= 'A') && (dat <= 'F')) return (dat-'A'+10);return 0xff;
}//========================================================================
// 函数: u16 GetAddress(void)
// 描述: 计算各种输入方式的地址.
// 参数: 无.
// 返回: 16位EEPROM地址.
// 版本: V1.0, 2013-6-6
//========================================================================
u16 GetAddress(void)
{u16 address;u8 i,j;address = 0;if((RX1_Buffer[2] == '0') && (RX1_Buffer[3] == 'X')){for(i=4; i<8; i++){j = CheckData(RX1_Buffer[i]);if(j >= 0x10) return 65535; //erroraddress = (address << 4) + j;}return (address);}return 65535; //error
}/**************** 获取要读出数据的字节数 ****************************/
u8 GetDataLength(void)
{u8 i;u8 length;length = 0;for(i=9; i<RX1_Cnt; i++){if(CheckData(RX1_Buffer[i]) >= 10) break;length = length * 10 + CheckData(RX1_Buffer[i]);}return (length);
}//========================================================================
// 函数: void PrintString1(u8 *puts)
// 描述: 串口1发送字符串函数。
// 参数: puts: 字符串指针.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注:
//========================================================================
void PrintString1(u8 *puts) //发送一个字符串
{for (; *puts != 0; puts++) UART1_TxByte(*puts); //遇到停止符0结束
}//========================================================================
// 函数: SetTimer2Baudraye(u16 dat)
// 描述: 设置Timer2做波特率发生器。
// 参数: dat: Timer2的重装值.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注:
//========================================================================
void SetTimer2Baudraye(u16 dat) // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
{AUXR &= ~(1<<4); //Timer stopAUXR &= ~(1<<3); //Timer2 set As TimerAUXR |= (1<<2); //Timer2 set as 1T modeTH2 = dat / 256;TL2 = dat % 256;IE2 &= ~(1<<2); //禁止中断AUXR |= (1<<4); //Timer run enable
}//========================================================================
// 函数: void UART1_config(u8 brt)
// 描述: UART1初始化函数。
// 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注:
//========================================================================
void UART1_config(u8 brt) // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
{/*********** 波特率使用定时器2 *****************/if(brt == 2){AUXR |= 0x01; //S1 BRT Use Timer2;SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / Baudrate1);}/*********** 波特率使用定时器1 *****************/else{TR1 = 0;AUXR &= ~0x01; //S1 BRT Use Timer1;AUXR |= (1<<6); //Timer1 set as 1T modeTMOD &= ~(1<<6); //Timer1 set As TimerTMOD &= ~0x30; //Timer1_16bitAutoReload;TH1 = (u8)((65536UL - (MAIN_Fosc / 4) / Baudrate1) / 256);TL1 = (u8)((65536UL - (MAIN_Fosc / 4) / Baudrate1) % 256);ET1 = 0; //禁止中断INT_CLKO &= ~0x02; //不输出时钟TR1 = 1;}/*************************************************/SCON = (SCON & 0x3f) | 0x40; //UART1模式, 0x00: 同步移位输出, 0x40: 8位数据,可变波特率, 0x80: 9位数据,固定波特率, 0xc0: 9位数据,可变波特率
// PS = 1; //高优先级中断ES = 1; //允许中断REN = 1; //允许接收P_SW1 &= 0x3f;P_SW1 |= 0x00; //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7 (必须使用内部时钟)
// PCON2 |= (1<<4); //内部短路RXD与TXD, 做中继, ENABLE,DISABLEB_TX1_Busy = 0;TX1_Cnt = 0;RX1_Cnt = 0;RX1_TimeOut = 0;
}//========================================================================
// 函数: void UART1_TxByte(u8 dat)
// 描述: 发送一个字节.
// 参数: 无.
// 返回: 无.
// 版本: V1.0, 2014-6-30
//========================================================================void UART1_TxByte(u8 dat)
{SBUF = dat;B_TX1_Busy = 1;while(B_TX1_Busy);
}//========================================================================
// 函数: void UART1_int (void) interrupt UART1_VECTOR
// 描述: UART1中断函数。
// 参数: nine.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注:
//========================================================================
void UART1_int (void) interrupt UART1_VECTOR
{if(RI){RI = 0;if(RX1_Cnt >= UART1_BUF_LENGTH) RX1_Cnt = 0;RX1_Buffer[RX1_Cnt] = SBUF;RX1_Cnt++;RX1_TimeOut = 5;}if(TI){TI = 0;B_TX1_Busy = 0;}
}/*
STC15F/L2KxxS2 扇区分配,512字节/扇区,从0x0000开始。型号 大小 扇区数 开始地址 结束地址 MOVC读偏移地址
STC15F/L2K08S2 53K 106扇区 0x0000 ~ 0xD3FF 0x2000
STC15F/L2K16S2 45K 90扇区 0x0000 ~ 0xB3FF 0x4000
STC15F/L2K24S2 37K 74扇区 0x0000 ~ 0x93FF 0x6000
STC15F/L2K32S2 29K 58扇区 0x0000 ~ 0x73FF 0x8000
STC15F/L2K40S2 21K 42扇区 0x0000 ~ 0x53FF 0xA000
STC15F/L2K48S2 13K 26扇区 0x0000 ~ 0x33FF 0xC000
STC15F/L2K56S2 5K 10扇区 0x0000 ~ 0x13FF 0xE000
STC15F/L2K60S2 1K 2扇区 0x0000 ~ 0x03FF 0xF000STC15F/L2K61S2 无EPROM, 整个122扇区的FLASH都可以擦写 地址 0x0000~0xF3ff.
*/#define ISP_ENABLE() ISP_CONTR = (ISP_EN + ISP_WAIT_FREQUENCY)
#define ISP_DISABLE() ISP_CONTR = 0; ISP_CMD = 0; ISP_TRIG = 0; ISP_ADDRH = 0xff; ISP_ADDRL = 0xff//========================================================================
// 函数: void DisableEEPROM(void)
// 描述: 禁止EEPROM.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2014-6-30
//========================================================================
void DisableEEPROM(void) //禁止访问EEPROM
{ISP_CONTR = 0; //禁止ISP/IAP操作ISP_CMD = 0; //去除ISP/IAP命令ISP_TRIG = 0; //防止ISP/IAP命令误触发ISP_ADDRH = 0xff; //指向非EEPROM区,防止误操作ISP_ADDRL = 0xff; //指向非EEPROM区,防止误操作
}//========================================================================
// 函数: void EEPROM_Trig(void)
// 描述: 触发EEPROM操作.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2014-6-30
//========================================================================
void EEPROM_Trig(void)
{F0 = EA; //保存全局中断EA = 0; //禁止中断, 避免触发命令无效ISP_TRIG(); //先送5AH,再送A5H到ISP/IAP触发寄存器,每次都需要如此//送完A5H后,ISP/IAP命令立即被触发启动//CPU等待IAP完成后,才会继续执行程序。_nop_();_nop_();EA = F0; //恢复全局中断
}//========================================================================
// 函数: void EEPROM_SectorErase(u16 EE_address)
// 描述: 擦除一个扇区.
// 参数: EE_address: 要擦除的EEPROM的扇区中的一个字节地址.
// 返回: none.
// 版本: V1.0, 2014-6-30
//========================================================================
void EEPROM_SectorErase(u16 EE_address)
{ISP_ENABLE(); //设置等待时间,允许ISP/IAP操作,送一次就够IAP_CONTR = 0X83;ISP_ERASE(); //宏调用, 送扇区擦除命令,命令不需改变时,不需重新送命令//只有扇区擦除,没有字节擦除,512字节/扇区。//扇区中任意一个字节地址都是扇区地址。ISP_ADDRH = EE_address / 256; //送扇区地址高字节(地址需要改变时才需重新送地址)ISP_ADDRL = EE_address % 256; //送扇区地址低字节EEPROM_Trig(); //触发EEPROM操作DisableEEPROM(); //禁止EEPROM操作
}//========================================================================
// 函数: void EEPROM_read_n(u16 EE_address,u8 *DataAddress,u8 lenth)
// 描述: 读N个字节函数.
// 参数: EE_address: 要读出的EEPROM的首地址.
// DataAddress: 要读出数据的指针.
// length: 要读出的长度
// 返回: 0: 写入正确. 1: 写入长度为0错误. 2: 写入数据错误.
// 版本: V1.0, 2014-6-30
//========================================================================
void EEPROM_read_n(u16 EE_address,u8 *DataAddress,u8 length)
{ISP_ENABLE(); //设置等待时间,允许ISP/IAP操作,送一次就够IAP_CONTR = 0X83;ISP_READ(); //送字节读命令,命令不需改变时,不需重新送命令do{ISP_ADDRH = EE_address / 256; //送地址高字节(地址需要改变时才需重新送地址)ISP_ADDRL = EE_address % 256; //送地址低字节EEPROM_Trig(); //触发EEPROM操作*DataAddress = ISP_DATA; //读出的数据送往EE_address++;DataAddress++;}while(--length);DisableEEPROM();
}//========================================================================
// 函数: u8 EEPROM_write_n(u16 EE_address,u8 *DataAddress,u8 length)
// 描述: 写N个字节函数.
// 参数: EE_address: 要写入的EEPROM的首地址.
// DataAddress: 要写入数据的指针.
// length: 要写入的长度
// 返回: 0: 写入正确. 1: 写入长度为0错误. 2: 写入数据错误.
// 版本: V1.0, 2014-6-30
//========================================================================
u8 EEPROM_write_n(u16 EE_address,u8 *DataAddress,u8 length)
{u8 i;u16 j;u8 *p;if(length == 0) return 1; //长度为0错误ISP_ENABLE(); //设置等待时间,允许ISP/IAP操作,送一次就够i = length;j = EE_address;p = DataAddress;ISP_WRITE(); //宏调用, 送字节写命令do{ISP_ADDRH = EE_address / 256; //送地址高字节(地址需要改变时才需重新送地址)ISP_ADDRL = EE_address % 256; //送地址低字节ISP_DATA = *DataAddress; //送数据到ISP_DATA,只有数据改变时才需重新送EEPROM_Trig(); //触发EEPROM操作EE_address++; //下一个地址DataAddress++; //下一个数据}while(--length); //直到结束EE_address = j;length = i;DataAddress = p;i = 0;ISP_READ(); //读N个字节并比较do{ISP_ADDRH = EE_address / 256; //送地址高字节(地址需要改变时才需重新送地址)ISP_ADDRL = EE_address % 256; //送地址低字节EEPROM_Trig(); //触发EEPROM操作if(*DataAddress != ISP_DATA) //读出的数据与源数据比较{i = 2;break;}EE_address++;DataAddress++;}while(--length);DisableEEPROM();return i;
}
🛠串口写入和读取操作
- 🌿写入操作:
W 0x0200 abcd9527
- 🌿读取操作:
R 0x0200 14
- 🍁在第一个扇区写入数据:
W 0x0000 去年今日此门中,人面桃花相映红。人面不知何处去,桃花依旧笑春风。
- 🍁读取第一个扇区数据:
R 0x0000 70
📚程序源码
- 🔖本案例来源于STC实验箱4中的案例修改而来。
复制这段内容后打开百度网盘手机App,操作更方便哦
链接: https://pan.baidu.com/s/1Q5k8FONsXFhnaDBcE3jiOw
提取码: dhye
相关文章:

STC15系列单片机通过串口多字节数据读写EEPROM操作
STC15系列单片机通过串口多字节数据读写EEPROM操作📌相关篇《STC15系列单片机EEPROM读写示例》 ⛳手册勘误信息注意事项 ⚡在手册上面描述STC15F2K60S2及STC15L2K60S2系列单片机内部EEPROM还可以用MOVC指令读,但此时首地址不再是0000H,而是程…...

计算机网络-ip数据报
在图中,网络层包含了四种协议:ARP、IP、ICMP、IGMP,由上下关系表明,ARP为IP协议服务,IP为ICMP和IGMP服务。 IP数据报格式 此处不区分数据报和分组的概念:当数据部分过长时,将数据部分拆分&…...

从零开始学C
以下是 该如何学习C语言的【思维导图】以及部分重点知识点的【博客链接】。其实C语言并不难,难的是没有人去教,没有耐心去学。不知道从哪下手学习,我将C的知识点做成一个思维导图,以供迷茫的小白参考,哪里不会…...

【云原生】手把手带你从零开始搭建kubernetes最新版本实战
文章目录前言一. 实验环境二. k8s 的介绍三 . k8s的安装3.1 搭建实验环境3.1.1 硬件层面的要求3.1.2 软件层面环境配置3.2 docker的安装3.2.1 搭建docker3.2.2 部署 cri-dockerd3.3 部署k8s3.3.1 配置添加阿里云的yum源3.3.2 安装kubeadm kubelet kubectl3.3.3 k8s-master节点初…...
trivy os软件包扫描原理分析
具体可以基于之前的博客来做 基于trivy获取基础镜像 参数修改一下: cliOpt.ListAllPkgs true 结果中会带有如下格式的结果: "Results":[{"Target":"192.168.1.94:443/test22/centos:7 (centos 7.9.2009)","Clas…...

算法训练营 day48 动态规划 完全背包 零钱兑换 II 组合总和 Ⅳ
算法训练营 day48 动态规划 完全背包 零钱兑换 II 组合总和 Ⅳ 完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物…...
Java 基础(1)—泛型简单使用
一、泛型定义及作用 泛型是一种编程机制,允许在编写代码时使用参数化类型,以在编译时实现类型安全。 以下是泛型作用: 增强代码可读性和可维护性:通过在代码中使用泛型参数,可以使代码更清晰、更具有可读性和可维护性…...
内存卡损坏了怎么恢复?
内存卡损坏了怎么恢复?现在我们身边有不少电子设备都是用存储卡来存储数据的。一旦需要方便我们直接导出使用。但这存储的数据也不是一定安全的,当我们将内存卡连接到电脑时,难免会碰到病毒、格式化等提示,在这些情况下,可能会导…...

Mysql使用规范(纯技术和实战建议)
1、事务隔级别: (强制):Repeatable-Read(重复读),且不能在会话操作时临时开启隔离级别。 注: Repeatable-Read(重复读)隔离级别解决不了幻读。 可用 show variables l…...

Netty源码解读-EventLoop(二)
一、简介 NioEventLoop的重要组成:Selector、线程、任务队列,他既会处理io事件,也会处理普通任务和定时任务. 1.下面是Selector,注意有两个哦后面会讲 2.下面的爷爷类提供的Thread变量,其实下面发excutor用的就是这个…...

OSI模型详解
今天,我们详解OSI(Open System Inter-connection Reference Model)模型,来看看工业物联网的网络互联和数据互通。 OSI模型 1984年,国际标准化组织(International Organization for Standardization&#…...

Share Creators完成500万美元融资,以工具化手段帮助企业从数字资产管理中解放
近日,总部位于旧金山湾区的初创公司Share Creators宣布完成了新一轮500万美元的融资,投资方为五源资本和福昕PDF。本轮融资主要用于扩大客户基础,并加速在美国、欧洲和亚洲的业务发展。近几年,企业内容及数字资产管理全球市场正在…...

几个Base64编码工具,也有蹊跷
起因 需求:对一段内容进行base64加密,然后通过url的get请求进行发送到后台,由于加密的内容比较少,base64串也不是很长,我认为此方案可行。 于是找了三个base64编码的在线工具,分别是: 平台1&…...
Python|每日一练|排序|递归|字符串|数组|动态规划|单选记录:以特殊格式处理连续增加的数字|正则表达式匹配|地下城游戏
1、以特殊格式处理连续增加的数字(排序) 贡献者:EricLao 给出一串数字, 程序要把数字按照这样的格式输出,把连续增加的数字用 [x-y] 的形式表示,只显示这一组顺序数字的首位两个数字,不连续增…...

Spring Cloud微服务网关Gateway组件
目录 网关简介 什么是Spring Cloud Gateway Spring Cloud Gateway 功能特征 核心概念 工作原理 Spring Cloud Gateway快速开始 环境搭建 集成Nacos 路由断言工厂(Route Predicate Factories)配置 自定义路由断言工厂 过滤器工厂( …...
cluster nodes(集群节点)
CLUSTER NODES 复制 自3.0.0起可用。 时间复杂度: O(N)其中N是 Cluster 节点的总数 Redis 集群中的每个节点都有其当前集群配置的视图,由已知节点的集合给出,我们与这些节点的连接状态,它们的标志&…...

【Android学习】下载jar慢和gradle慢的情况
目录 问题出现的原因 解决方法 解决Gradle下载问题:手动安装 解决jar包下载慢问题:更改下载源 问题出现的原因 国内访问谷歌被墙导致访问速度慢或者干脆无法下载 解决方法 解决Gradle下载问题:手动安装 访问官网Gradle | Release Candi…...

下一个排列-力扣31-java
一、题目描述整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。例如,arr [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地&…...
前端面试题
1.HTTP request报文结构是怎样的 1.首行是Request-Line包括:请求方法,请求URI,协议版本,CRLF(换行符) 2.首行之后是若干行请求头,包括general-header,request-header或者entity-hea…...

jsp游戏门户网站系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 jsp 游戏门户网站系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql,使…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
41道Django高频题整理(附答案背诵版)
解释一下 Django 和 Tornado 的关系? Django和Tornado都是Python的web框架,但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。它遵循MVC设计,并强调代码复用。Django有…...

EasyRTC音视频实时通话功能在WebRTC与智能硬件整合中的应用与优势
一、WebRTC与智能硬件整合趋势 随着物联网和实时通信需求的爆发式增长,WebRTC作为开源实时通信技术,为浏览器与移动应用提供免插件的音视频通信能力,在智能硬件领域的融合应用已成必然趋势。智能硬件不再局限于单一功能,对实时…...

ubuntu中安装conda的后遗症
缘由: 在编译rk3588的sdk时,遇到编译buildroot失败,提示如下: 提示缺失expect,但是实测相关工具是在的,如下显示: 然后查找借助各个ai工具,重新安装相关的工具,依然无解。 解决&am…...

EEG-fNIRS联合成像在跨频率耦合研究中的创新应用
摘要 神经影像技术对医学科学产生了深远的影响,推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下,基于神经血管耦合现象的多模态神经影像方法,通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里,本研…...