手撕I2C和SPI协议实现
手撕I2C和SPI协议实现
目录
- I2C协议原理
- I2C位操作实现
- I2C驱动代码编写
- SPI协议原理
- SPI位操作实现
- SPI驱动代码编写
I2C协议原理
I2C(Inter-Integrated Circuit)是一种串行通信总线,使用两根线:SCL(时钟线)和SDA(数据线)。
基本特性
- 主从架构
- 双向半双工通信
- 每个设备都有唯一地址
- 支持多主设备
- 通信速率通常为100kHz(标准模式)、400kHz(快速模式)或1MHz以上(高速模式)
信号状态
- 空闲状态:SCL和SDA均为高电平
- 起始信号(START):SCL高电平时,SDA从高变低
- 停止信号(STOP):SCL高电平时,SDA从低变高
- 数据位:SCL低电平时,准备数据;SCL高电平时,采样数据
- 应答信号(ACK):接收方在第9个时钟周期将SDA拉低表示接收成功
通信流程
- 主设备发送起始信号(START)
- 发送从设备地址(7位)和读/写位(1位)
- 从设备发送应答(ACK)
- 数据传输(8位一组),每组后跟应答位
- 主设备发送停止信号(STOP)
I2C位操作实现
首先需要实现基本的I2C底层函数:
GPIO配置
// 配置GPIO为开漏输出模式
void I2C_GPIO_Config(void) {// 使能GPIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // SCL: PB6, SDA: PB7GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 开漏输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);// 空闲状态,均为高电平GPIO_SetBits(GPIOB, GPIO_Pin_6 | GPIO_Pin_7);
}
I2C基本操作函数
// SCL和SDA控制函数
#define SCL_H GPIO_SetBits(GPIOB, GPIO_Pin_6)
#define SCL_L GPIO_ResetBits(GPIOB, GPIO_Pin_6)
#define SDA_H GPIO_SetBits(GPIOB, GPIO_Pin_7)
#define SDA_L GPIO_ResetBits(GPIOB, GPIO_Pin_7)
#define SDA_READ GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7)// 延迟函数
void I2C_Delay(void) {uint8_t i = 10; // 可根据时钟频率调整while(i--);
}// 起始信号
void I2C_Start(void) {SDA_H;SCL_H;I2C_Delay();SDA_L; // SDA从高到低,产生起始信号I2C_Delay();SCL_L; // 钳住I2C总线,准备发送或接收数据
}// 停止信号
void I2C_Stop(void) {SDA_L;SCL_H;I2C_Delay();SDA_H; // SDA从低到高,产生停止信号I2C_Delay();
}// 等待应答
uint8_t I2C_WaitAck(void) {uint8_t ack;SDA_H; // 释放SDAI2C_Delay();SCL_H; // 产生时钟脉冲I2C_Delay();ack = SDA_READ; // 读取SDA状态SCL_L;return ack; // 返回0表示有应答
}// 发送应答
void I2C_Ack(void) {SDA_L; // SDA拉低,表示ACKI2C_Delay();SCL_H;I2C_Delay();SCL_L;SDA_H; // 释放SDA
}// 发送非应答
void I2C_NAck(void) {SDA_H; // SDA保持高电平,表示NACKI2C_Delay();SCL_H;I2C_Delay();SCL_L;
}// 发送一个字节
void I2C_SendByte(uint8_t byte) {uint8_t i = 8;while(i--) {SCL_L;I2C_Delay();if(byte & 0x80)SDA_H;elseSDA_L;byte <<= 1;I2C_Delay();SCL_H;I2C_Delay();}SCL_L;
}// 读取一个字节
uint8_t I2C_ReadByte(uint8_t ack) {uint8_t i = 8;uint8_t byte = 0;SDA_H; // 释放SDA,准备读取数据while(i--) {byte <<= 1;SCL_L;I2C_Delay();SCL_H;I2C_Delay();if(SDA_READ)byte |= 0x01;}SCL_L;if(ack)I2C_Ack(); // 发送应答elseI2C_NAck(); // 发送非应答return byte;
}
I2C驱动代码编写
基于上面的底层函数,实现设备读写操作:
// 写入一个字节到指定设备的指定寄存器
uint8_t I2C_WriteReg(uint8_t DevAddr, uint8_t RegAddr, uint8_t data) {I2C_Start();I2C_SendByte(DevAddr << 1); // 设备地址 + 写位(0)if(I2C_WaitAck()) {I2C_Stop();return 1; // 无应答,失败}I2C_SendByte(RegAddr); // 寄存器地址if(I2C_WaitAck()) {I2C_Stop();return 1;}I2C_SendByte(data); // 写入数据if(I2C_WaitAck()) {I2C_Stop();return 1;}I2C_Stop();return 0; // 成功
}// 从指定设备的指定寄存器读取一个字节
uint8_t I2C_ReadReg(uint8_t DevAddr, uint8_t RegAddr) {uint8_t data;I2C_Start();I2C_SendByte(DevAddr << 1); // 设备地址 + 写位(0)if(I2C_WaitAck()) {I2C_Stop();return 0xFF; // 无应答,失败}I2C_SendByte(RegAddr); // 寄存器地址if(I2C_WaitAck()) {I2C_Stop();return 0xFF;}I2C_Start(); // 重复起始I2C_SendByte((DevAddr << 1) | 0x01); // 设备地址 + 读位(1)if(I2C_WaitAck()) {I2C_Stop();return 0xFF;}data = I2C_ReadByte(0); // 读取数据,发送非应答I2C_Stop();return data;
}
实际应用示例:MPU6050读取数据
#define MPU6050_ADDR 0x68 // MPU6050设备地址void MPU6050_Init() {I2C_WriteReg(MPU6050_ADDR, 0x6B, 0x00); // 唤醒MPU6050I2C_WriteReg(MPU6050_ADDR, 0x19, 0x07); // 采样率设置I2C_WriteReg(MPU6050_ADDR, 0x1A, 0x06); // 配置数字低通滤波器I2C_WriteReg(MPU6050_ADDR, 0x1B, 0x18); // 陀螺仪量程:±2000dpsI2C_WriteReg(MPU6050_ADDR, 0x1C, 0x01); // 加速度计量程:±2g
}void MPU6050_GetAcceleration(int16_t *ax, int16_t *ay, int16_t *az) {uint8_t buf[6];// 读取加速度计数据buf[0] = I2C_ReadReg(MPU6050_ADDR, 0x3B);buf[1] = I2C_ReadReg(MPU6050_ADDR, 0x3C);buf[2] = I2C_ReadReg(MPU6050_ADDR, 0x3D);buf[3] = I2C_ReadReg(MPU6050_ADDR, 0x3E);buf[4] = I2C_ReadReg(MPU6050_ADDR, 0x3F);buf[5] = I2C_ReadReg(MPU6050_ADDR, 0x40);*ax = (buf[0] << 8) | buf[1];*ay = (buf[2] << 8) | buf[3];*az = (buf[4] << 8) | buf[5];
}
SPI协议原理
SPI(Serial Peripheral Interface)是一种同步串行通信接口,使用四根线:
基本特性
- MOSI (Master Out Slave In):主设备发送,从设备接收
- MISO (Master In Slave Out):主设备接收,从设备发送
- SCK (Serial Clock):时钟信号,由主设备产生
- SS/CS (Slave Select/Chip Select):片选信号,用于选择从设备
工作模式
SPI有四种工作模式,由CPOL(时钟极性)和CPHA(时钟相位)决定:
- 模式0:CPOL=0, CPHA=0,空闲时SCK低电平,第一个边沿采样
- 模式1:CPOL=0, CPHA=1,空闲时SCK低电平,第二个边沿采样
- 模式2:CPOL=1, CPHA=0,空闲时SCK高电平,第一个边沿采样
- 模式3:CPOL=1, CPHA=1,空闲时SCK高电平,第二个边沿采样
通信流程
- 主设备将对应从设备的CS线拉低(激活)
- 主设备通过SCK产生时钟信号
- 数据通过MOSI和MISO线同时双向传输
- 传输完成后,主设备将CS线拉高(释放)
SPI位操作实现
GPIO配置
// 配置SPI GPIO
void SPI_GPIO_Config(void) {// 使能GPIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;// 配置SCK、MOSI为推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7; // SCK: PA5, MOSI: PA7GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置MISO为浮空输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; // MISO: PA6GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置CS为推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // CS: PA4GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);// 初始状态:CS高,SCK低GPIO_SetBits(GPIOA, GPIO_Pin_4); // CS高电平,不选中从设备GPIO_ResetBits(GPIOA, GPIO_Pin_5); // SCK低电平,模式0初始状态
}
SPI基本操作函数
// SPI引脚定义
#define SPI_CS_H GPIO_SetBits(GPIOA, GPIO_Pin_4)
#define SPI_CS_L GPIO_ResetBits(GPIOA, GPIO_Pin_4)
#define SPI_SCK_H GPIO_SetBits(GPIOA, GPIO_Pin_5)
#define SPI_SCK_L GPIO_ResetBits(GPIOA, GPIO_Pin_5)
#define SPI_MOSI_H GPIO_SetBits(GPIOA, GPIO_Pin_7)
#define SPI_MOSI_L GPIO_ResetBits(GPIOA, GPIO_Pin_7)
#define SPI_MISO GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)// 延迟函数
void SPI_Delay(void) {uint8_t i = 2;while(i--);
}// SPI发送并接收一个字节(模式0)
uint8_t SPI_ReadWriteByte(uint8_t data) {uint8_t i;uint8_t temp = 0;for(i = 0; i < 8; i++) {// 准备发送数据if(data & 0x80)SPI_MOSI_H;elseSPI_MOSI_L;data <<= 1; // 左移一位,准备下一位SPI_Delay();SPI_SCK_H; // 时钟上升沿,从设备采样MOSISPI_Delay();temp <<= 1; // 左移一位,为接收新的数据位腾出空间if(SPI_MISO)temp++; // 如果MISO为高,则置1SPI_SCK_L; // 时钟下降沿,主设备采样MISOSPI_Delay();}return temp; // 返回接收到的数据
}
SPI驱动代码编写
基于上面的底层函数,实现设备读写操作:
// 向指定寄存器写入一个字节
void SPI_WriteReg(uint8_t reg, uint8_t value) {SPI_CS_L; // 使能片选SPI_ReadWriteByte(reg); // 发送寄存器地址SPI_ReadWriteByte(value); // 发送数据SPI_CS_H; // 禁用片选
}// 从指定寄存器读取一个字节
uint8_t SPI_ReadReg(uint8_t reg) {uint8_t value;SPI_CS_L; // 使能片选SPI_ReadWriteByte(reg | 0x80); // 发送寄存器地址(最高位置1表示读操作)value = SPI_ReadWriteByte(0xFF); // 发送任意值,读取结果SPI_CS_H; // 禁用片选return value;
}// 从指定寄存器读取多个字节
void SPI_ReadMulti(uint8_t reg, uint8_t *buf, uint8_t len) {SPI_CS_L; // 使能片选SPI_ReadWriteByte(reg | 0x80); // 发送寄存器地址(最高位置1表示读操作)while(len--) {*buf = SPI_ReadWriteByte(0xFF);buf++;}SPI_CS_H; // 禁用片选
}
实际应用示例:读取W25Q64闪存
// W25Q64命令定义
#define W25Q64_READ_ID 0x90
#define W25Q64_READ_DATA 0x03
#define W25Q64_WRITE_ENABLE 0x06
#define W25Q64_PAGE_PROGRAM 0x02
#define W25Q64_ERASE_SECTOR 0x20
#define W25Q64_READ_STATUS 0x05// 读取W25Q64芯片ID
uint16_t W25Q64_ReadID(void) {uint16_t id = 0;SPI_CS_L;SPI_ReadWriteByte(W25Q64_READ_ID); // 发送读取ID命令SPI_ReadWriteByte(0x00); // 发送3个虚拟地址SPI_ReadWriteByte(0x00);SPI_ReadWriteByte(0x00);id |= SPI_ReadWriteByte(0xFF) << 8; // 读取厂商IDid |= SPI_ReadWriteByte(0xFF); // 读取设备IDSPI_CS_H;return id;
}// 读取W25Q64状态寄存器
uint8_t W25Q64_ReadStatus(void) {uint8_t status;SPI_CS_L;SPI_ReadWriteByte(W25Q64_READ_STATUS);status = SPI_ReadWriteByte(0xFF);SPI_CS_H;return status;
}// 等待W25Q64操作完成
void W25Q64_WaitBusy(void) {while((W25Q64_ReadStatus() & 0x01) == 0x01);
}// 读取W25Q64数据
void W25Q64_ReadData(uint32_t addr, uint8_t *buf, uint16_t len) {SPI_CS_L;SPI_ReadWriteByte(W25Q64_READ_DATA); // 发送读取命令SPI_ReadWriteByte((addr >> 16) & 0xFF); // 发送地址SPI_ReadWriteByte((addr >> 8) & 0xFF);SPI_ReadWriteByte(addr & 0xFF);while(len--) {*buf = SPI_ReadWriteByte(0xFF);buf++;}SPI_CS_H;
}
总结
I2C协议实现要点
- 使用开漏输出模式配置GPIO
- 实现起始、停止、发送、接收、应答等基本信号操作
- 按照协议时序编写读写函数
- 注意时钟速率控制和时序延迟
SPI协议实现要点
- 配置MOSI、SCK为输出,MISO为输入
- 确定使用的SPI模式(时钟极性和相位)
- 实现基本的读写字节函数
- 根据具体设备实现寄存器读写操作
注意事项
- 时序要严格遵循协议规范
- 延时函数需根据实际系统时钟频率调整
- 注意不同设备可能有特殊的地址或命令要求
- 调试时可以使用示波器观察信号波形
- 加入错误处理和超时机制提高鲁棒性
通过以上步骤,您可以实现对I2C和SPI协议的"手撕",即从底层位操作实现完整的通信协议,而不依赖于硬件外设。这种方式虽然占用CPU资源较多,但灵活性高,适用于不需要高速通信的场景或硬件外设不足的情况。
相关文章:
手撕I2C和SPI协议实现
手撕I2C和SPI协议实现 目录 I2C协议原理I2C位操作实现I2C驱动代码编写SPI协议原理SPI位操作实现SPI驱动代码编写 I2C协议原理 I2C(Inter-Integrated Circuit)是一种串行通信总线,使用两根线:SCL(时钟线)…...
452. Minimum Number of Arrows to Burst Balloons
题目描述 这道题用leetcode官方的解答反而搞复杂了。本题其实就是求重叠区间的交集。先按照区间左端点从小到大排序。然后拿出第一个区间作为【当前区间交集】的初始值。遍历后面的区间看那个区间和【当前交集】是否有重叠。如果有重叠则将【当前交集】和【当前区间】求交集并更…...
React 中,闭包陷阱
文章目录 前言1. 经典闭包陷阱示例过期状态问题 2. 解决方案2.1 正确声明依赖数组2.2 使用 useRef 捕获最新值**2.3 使用函数式更新(针对状态更新)****2.4 使用 useCallback 冻结闭包** **3. 异步操作中的闭包陷阱****事件监听示例** **4. 自定义 Hooks …...
代码复现5——VLMaps
项目地址 1 Setup # 拉取VLMaps仓库,成功运行后会在主目录生成文件夹vlmapsgit clone https://github.com/vlmaps/vlmaps.git#通过 conda 创建虚拟环境conda create -n vlmaps python=3.8 -yconda activate vlmaps #激活环境cd vlmaps # 切换到项目文件下bash install.ba…...
qt6 c++操作qtableview和yaml
保存qtableview数据到yaml文件从yaml文件读取数据到qtableview qtableview在UI界面拖放。 代码是问chat百度的深度探索。 - name: a1address: db1.dbw10type: int - name: a2address: db1.dbx1.0type: bool写到yaml,写前检查 bool plot1::isRowValid(const QStan…...
使用UniApi调用百度地图API的需要注意的地方
目录 前言 一、百度开放平台 1、功能简介 2、地点搜索服务 3、按行政区划检索API 二、Uniapi集成百度API 1、API集成流程 2、访问接口的定义 3、业务调用集成 三、可能遇到的问题 1、指定输出格式无效 2、返回数据的总数 四、总结 前言 在之前的系列博客中…...
(9)python开发经验
文章目录 1 os.path.join()拼接路径2 条件变量3 添加临时环境变量 更多精彩内容👉内容导航 👈👉Qt开发 👈👉python开发 👈 1 os.path.join()拼接路径 os.path.join() 是 Python 中处理文件路径拼接的核心函…...
windows 10 做服务器 其他电脑无法访问,怎么回事?
一般我们会先打开win10自己的防火墙策略,但是容易忽略 电脑之间 路由器上的防火墙,此时也需要查看一下,可以尝试先关闭路由器防火墙,如果可以了,再 设置路由器上的防火墙规则。 将路由器的上网设置 改成 路由模式 &a…...
mysql中limit深度分页详细剖析【爽文】
目录 一 mysql中limit深度分页 1.1 背景描述 1.2 mysql深度分页很慢原因 1.2.1 mysql的sql执行流程 1.2.2 mysql的深度分页很慢原因 1.3 解决办法 1.3.1 覆盖索引 1.3.2 子查询 1.3.3 标签查询 1.3.4 分区表 一 mysql中limit深度分页 1.1 背景描述 Limit深度分页造…...
【C++ Qt】布局管理器
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 🤔绪论: 在Qt开发中,界面布局的合理设计是提升用户体验的关键。早期,开发者常采用绝对定位的方式摆放控件,即通…...
Windows系统永久暂停更新操作步骤
目录 Windows系统永久暂停更新操作步骤 打开运行窗口进入注册表编辑器 导航路径图示 新建并配置DWORD值 新建值操作图示数值设置图示 在系统设置中应用暂停 暂停选项图示 注意事项 打开运行窗口 按下键盘上的 Win键 R 组合键,调出“运行”对话框。 进入组策略编…...
Java IO流进阶实战详解(含文件读写、拷贝、加密、字符集)
本文基于 Java 原生 IO 流,从最基础的字节流到字符流,再到实战案例(如文件夹拷贝、文件加密等)进行逐步深入讲解。适合有一定 Java 基础、希望掌握文件读写操作的。 一、前言 Java IO(输入输出)是我们日常…...
JavaScript【7】BOM模型
1.概述: BOM(Browser Object Model,浏览器对象模型)是 JavaScript 中的一个重要概念,它提供了一系列对象来访问和操作浏览器的功能和信息。与 DOM(Document Object Model)主要关注文档结构不同&…...
STM32F10xx 参考手册
6. 什么是寄存器 本章参考资料:《STM32F10xx 参考手册》、《STM32F10xx数据手册》、 学习本章时,配合《STM32F10xx 参考手册》“存储器和总线架构”及“通用I/O(GPIO)”章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。…...
使用instance着色
本节我们学习使用instance着色器进行着色 //拾取var handler new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);handler.setInputAction(function(movement){console.log(movement);var pickedObject viewer.scene.pick(movement.position);if(Cesium.defined(picke…...
MySQL——4、表的约束
表的约束 1、空属性2、默认值3、列描述4、zerofill5、主键6、自增长7、唯一键8、外键9、综合案例 真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性…...
Datawhale PyPOTS时间序列5月第3次笔记
下游任务的两阶段(two-stage) 处理 下载数据并预处理的程序: # ------------------------------- # 导入必要的库 # ------------------------------- import numpy as np import torch from benchpots.datasets import preprocess_physionet2012 from pypots.imp…...
初探Reforcement Learning强化学习【QLearning/Sarsa/DQN】
文章目录 一、Q-learning现实理解:举例:回顾: 二、Sarsa和Q-learning的区别 三、Deep Q-NetworkDeep Q-Network是如何工作的?前处理:Convolution NetworksExperience Replay 一、Q-learning 是RL中model-free、value-…...
计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 12.曲面细分
1. 曲面细分 曲面细分着色器(Tessellation Shader)是OpenGL 4.0及以上版本引入的一种可编程着色器阶段,用于在GPU上对几何体进行细分,将粗糙的多边形网格自动细分为更平滑、更精细的曲面。它主要用于实现高质量的曲面渲染&#x…...
8天Python从入门到精通【itheima】-14~16
目录 第二章学习内容总体预览: 14节-字面量: 1.学习目标:编辑 2.Python中6大常用数据类型: 3.实现:整数、浮点数、字符串类型的数据输出 4.字面量的定义: 5.小节总结 15节-注释: 1.le…...
Spring Boot 项目的计算机专业论文参考文献
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...
linux线程基础
1. 什么是线程 进程是承担系统资源分配的基本实体,而线程(Thread)是进程内的一个执行单元,是CPU调度的基本单位。一个进程可以包含多个线程,这些线程共享进程的地址空间和资源(如文件描述符、全局变量等&a…...
进阶-数据结构部分:3、常用查找算法
飞书文档https://x509p6c8to.feishu.cn/wiki/LRdnwfhNgihKeXka7DfcGuRPnZt 顺序查找 查找算法是指:从一些数据之中,找到一个特殊的数据的实现方法。查找算法与遍历有极高的相似性,唯一的不同就是查找算法可能并不一定会将每一个数据都进行访…...
JavaScript 中的 for...in 和 for...of 循环详解
在 JavaScript 中,for...in 和 for...of 是两种常用的循环结构,但它们有着不同的用途和行为。很多初学者容易混淆这两者,本文将详细解析它们的区别、适用场景以及注意事项。 目录 for…in 循环 基本用法遍历对象属性注意事项 for…of 循环 …...
【汇总】影视仓接口地址,影视仓最新配置接口【2025.5】
📦 TVBOX接口分类与制作加载指南 结合参考资料,整理TVBOX接口的核心分类、制作方法及加载技巧,助你快速上手! 🌐 一、接口分类 🌍 网络接口(远程URL) 特点:动态加载在线J…...
vue引用cesium,解决“Not allowed to load local resource”报错
vue引用cesium,解决“Not allowed to load local resource”报错TOC 工具 vscode node :v22.14.0npm :10.9.2vue:vue/cli 5.0.8 一、创建一个 Vue 3 项目 1.创建名为cesium_test的项目: vue create cesium_test2.…...
阿里云服务器跑模型教程
首先打开阿里云官网点击免费试用 选择250工时/月的免费仨月新人试用套餐 点击右上角主账号 选择人工智能平台PAI 然后选择交互式建模(DSW) 选择新建实例 起个名字 然后点击确定 点击打开 进入到命令行工具 下载MINIConda和对应的pytorch还有相关依赖库文件即可 然后上传…...
JavaScript入门【2】语法基础
1.JavaScript的引⼊⽅式(使用): 1.方式1:行内引用: 此种方式是将<font style"color:rgb(38,38,38);">JavaScript代码作为HTML标签的属性值使⽤,示例如下:</font><html lang"en"> <head><meta charset"UTF-8"><…...
调用DeepSeek系列模型问答时,输出只有</think>标签,而没有<think>标签
问题:调用DeepSeek系列模型问答时,输出结果缺少只有标签,而没有标签? DeepSeek官方有关说明 这里设置成这样是为了保证让模型的生成是以"<think>\n"开头的,然后开始思考过程,避免模型没…...
python:gimp 与 blender 两个软件如何协作?
GIMP(GNU Image Manipulation Program)和 Blender 是两个不同领域的开源工具,但它们在数字创作流程中常协同使用,以下是它们的主要联系和互补性: 1. 功能互补:2D 与 3D 的结合 GIMP 是专业的 2D 图像处理工…...
MMDetection环境安装配置
MMDetection 支持在 Linux,Windows 和 macOS 上运行。它需要 Python 3.7 以上,CUDA 9.2 以上和 PyTorch 1.8 及其以上。 MMDetection 至今也一直更新很多个版本了,但是对于最新的pytorch版本仍然不支持,我安装的时候仍然多次遇到m…...
【springboot+vue3的前后端分离项目实现支付宝的沙箱支付】
【springbootvue3的前后端分离项目实现支付宝的沙箱支付】 以下是基于SpringBoot Vue前后端分离项目实现支付宝沙箱支付的完整解决方案,包含关键代码和调试技巧 一、项目架构设计 二、后端实现(SpringBoot) 1. 添加依赖 <!-- pom.xml…...
基于Llama3的开发应用(二):大语言模型的工业部署
大语言模型的工业部署 0 前言1 ollama部署大模型1.1 ollama简介1.2 ollama的安装1.3 启动ollama服务1.4 下载模型1.5 通过API调用模型 2 vllm部署大模型2.1 vllm简介2.2 vllm的安装2.3 启动vllm模型服务2.4 API调用 3 LMDeploy部署大模型3.1 LMDeploy简介3.2 LMDeploy的安装3.3…...
MySQL只操作同一条记录也会死锁吗?
大家好,我是锋哥。今天分享关于【MySQL只操作同一条记录也会死锁吗?】面试题。希望对大家有帮助; MySQL里where条件的顺序影响索引使用吗? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在MySQL中,死锁通常发生在多…...
Linux的静态库 共享库 进程 主函数的参数
1、库文件 库文件 库是一组预先编译好的方法的集合; Linux系统储存的位置一般在/lib和/usr/lib中 库的头文件放在/usr/include 库分类:静态库(libxxx.a)共享库(libxxx.so) 静态库 (1&#…...
软件设计师考试结构型设计模式考点全解析
结构型设计模式考点全解析 一、分值占比与考察趋势分析(75分制) 设计模式近5年平均分值考察频率趋势分析适配器模式3-5分高频保持稳定桥接模式2-3分中频略有上升组合模式4-6分高频持续重点装饰器模式3-4分高频稳定考察代理模式5-7分高频逐年增加外观模…...
Java-Objects类高效应用的全面指南
Java_Objects类高效应用的全面指南 前言一、Objects 类概述二、Objects 类的核心方法解析2.1 requireNonNull系列方法:空指针检查的利器2.2 equals方法:安全的对象比较2.3 hashCode方法:统一的哈希值生成2.4 toString方法:灵活的对…...
PostGIS实现栅格数据入库-raster2pgsql
raster2pgsql使用与最佳实践 一、工具概述 raster2pgsql是PostGIS提供的命令行工具,用于将GDAL支持的栅格格式(如GeoTIFF、JPEG、PNG等)导入PostgreSQL数据库,支持批量加载、分块切片、创建空间索引及金字塔概览,是栅格数据入库的核心工具。 二、核心功能与典型用法 1…...
专题四:综合练习(组合问题的决策树与回溯算法)
以leetode77题为例 题目分析: 给一个数字n,你可以在1到n中选k个数字进行组合,注意包括1和n,而且通过观察实例 1,2和2,1是一样的,所以我们画决策树的时候,只需要从当前位置往后列举…...
从神经架构到万物自动化的 AI 革命:解码深度学习驱动的智能自动化新范式
目录 一、深度学习与 AI 自动化概述 二、深度学习核心技术解析 2.1 常见深度学习架构 2.2 关键算法 三、AI 自动化实践案例 3.1 图像分类自动化 3.2 自然语言处理自动化 —— 文本情感分析 编辑 五、自动化系统设计与实现 5.1 端到端自动化框架 5.2 自动化测试框架…...
3.5/Q1,GBD数据库最新文章解读
文章题目:Burden, trends, projections, and spatial patterns of lip and oral cavity cancer in Iran: a time-series analysis from 1990 to 2040 DOI:10.1186/s12889-025-22202-8 中文标题:伊朗唇癌和口腔癌的负担、趋势、预测和空间模式…...
智慧校园(含实验室)智能化专项汇报方案
该方案聚焦智慧校园(含实验室)智能化建设,针对传统实验室在运营监管、环境监测、安全管控、排课考勤等方面的问题,依据《智慧校园总体框架》等标准,设计数字孪生平台、实验室综合管理平台、消安电一体化平台三大核心平台,涵盖通信、安防、建筑设备管理等设施,涉及 395 个…...
玩转 AI · 思考过程可视化
玩转 AI 思考过程可视化 我们在开发 AI 的思维链 / 处理流时,难免遇到耗时较长的流程,如果遇到处理过慢的,用户什么也看不到可能丧失使用兴趣,对于这种情况,一个巧妙的产品思维就是呈现处理进度。 示例 其实完成这个页…...
hysAnalyser 从MPEG-TS导出ES功能说明
摘要 hysAnalyser 是一款特色的 MPEG-TS 数据分析工具。本文主要介绍了 hysAnalyser 从MPEG-TS 中导出选定的 ES 或 PES 功能(版本v1.0.003),以便用户知悉和掌握这些功能,帮助分析和解决各种遇到ES或PES相关的实际问题。hysAnalyser 支持主流的MP1/MP2/…...
[YOLO模型](4)YOLO V3的介绍
文章目录 YOLO V3一、模型思想二、模型性能三、改进的地方1. 三种scale2. scale变换经典方法3. 残差连接4. 核心网络架构(1) 结构(2) 输出与先验框关系 5. Logistic分类器替代Softmax 四、总结 YOLO V3 一、模型思想 作者 Redmon 又在 YOLOv2 的基础上做了一些改进:…...
期望是什么:(无数次的均值,结合概率)21/6=3.5
https://seeing-theory.brown.edu/basic-probability/cn.html 期望是什么:(无数次的均值,结合概率)21/6=3.5 一、期望(数学概念) 在概率论和统计学中,**期望(Expectation)**是一个核心概念,用于描述随机变量的长期平均取值,反映随机变量取值的集中趋势。 (一…...
Stacking(堆叠):集成学习中的“超级英雄团队”
在机器学习的世界里,如果要找一个类似漫威“复仇者联盟”的存在,那么**Stacking(堆叠)**无疑是最佳候选人。就像钢铁侠、美国队长和雷神各自拥有独特的能力,但只有当他们组队时才能发挥出惊人的战斗力,Stac…...
手写tomcat:基本功能实现(3)
TomcatRoute类 TomcatRoute类是Servlet容器,是Tomcat中最核心的部分,其本身是一个HashMap,其功能为:将路径和对象写入Servlet容器中。 package com.qcby.config;import com.qcby.Util.SearchClassUtil; import com.qcby.servlet…...
nt!MiRemovePageByColor函数分析之脱链和刷新颜色表
第0部分:背景 PFN_NUMBER FASTCALL MiRemoveZeroPage ( IN ULONG Color ) { ASSERT (Color < MmSecondaryColors); Page FreePagesByColor[Color].Flink; if (Page ! MM_EMPTY_LIST) { // // Remove the first entry on the zeroe…...
时间筛掉了不够坚定的东西
2025年5月17日,16~25℃,还好 待办: 《高等数学1》重修考试 《高等数学2》备课 《物理[2]》备课 《高等数学2》取消考试资格学生名单 《物理[2]》取消考试资格名单 职称申报材料 2024年税务申报 5月24日、25日监考报名 遇见:敲了一…...