当前位置: 首页 > news >正文

19:I2C一:程序模拟I2C通信时序

I2C

  • 1、什么是I2C
  • 2、I2C的通信时序
    • 2.1:起始信号
    • 2.2:停止信号
    • 2.3:主机向从机发送一个字节数据
    • 2.4:主机向从机读取一个字节数据
    • 2.5:主机接收应答
    • 2.6:主机发送应答
  • 3、程序模拟I2C的通信时序
    • 3.1:指定地址写一个字节的数据
    • 3.2:指定地址读一个字节的数据

1、什么是I2C

   I2C通信协议和串口通信USART不同,USART是异步,全双工的通信协议。而I2C通信协议是一种同步,半双工,带数据应答,支持总线挂载多设备的通信协议。USART传输数据的时候是先传输数据帧的低位,在传高位。而I2C传输数据的时候是高位先行。

在这里插入图片描述

   由上图所示:有2条总线,数据总线SDA和时钟总线SCL。其中时钟线SCL只能由主机控制,而SDA主机和从机都可以控制。

   当主机向从机发送一个字节数据时:①主机先发送一个起始信号,②然后在发送一个字节的数据(从机地址(7位)+W),然后接收从机的应答信号,③然后在发送一个字节的数据(从机寄存器的地址),然后接收一个应答信号,④然后开始发送需要发送给从机的数据,然后接收应答信号,⑤发送一个停止信号。 如下图所示:
在这里插入图片描述

   当主机读取从机一个字节的数据时:①主机先发送一个起始信号,②然后在发送一个字节的数据(从机地址(7位)+W),然后接收从机的应答信号,③然后在发送一个字节的数据(从机寄存器的地址)④然后主机在发送一个起始信号,⑤然后在发送一个字节的数据(从机地址(7位)+R),然后接收从机的应答信号,⑥然后开始读取SDA上面的数据,读取到一个字节后,给从机发送一个应答信号,如下图所示:
在这里插入图片描述

2、I2C的通信时序

2.1:起始信号

   起始信号和停止信号都是由主机进行发送,主机需要发送起始信号时:SCL高电平期间,SDA从高电平切换到低电平
在这里插入图片描述
使用程序模拟此时序代码如下:

void I2C_W_SCL(uint8_t BitValue)//拉低SCL或者释放SCL(拉高)
{GPIO_WriteBit(GPIOB,GPIO_Pin_10,(BitAction)BitValue);Delay_us(10);
}void I2C_W_SDA(uint8_t BitValue)//给SDA写数据(拉低SDA/释放SDA(拉高))
{GPIO_WriteBit(GPIOB,GPIO_Pin_11,(BitAction)BitValue);Delay_us(10);
}void MyI2C_Start(void)//起始信号
{
//	SCL(1);//释放SCLI2C_W_SDA(1);//释放SDAI2C_W_SCL(1);//释放SCLI2C_W_SDA(0);//拉低SDAI2C_W_SCL(0);//拉低SCL
}

2.2:停止信号

   主机需要发送停止信号时:SCL高电平期间,SDA从低电平切换到高电平
在这里插入图片描述

使用程序模拟此时序代码如下:

void MyI2C_Stop(void)
{I2C_W_SCL(0);I2C_W_SDA(0);I2C_W_SCL(1);I2C_W_SDA(1);
}

2.3:主机向从机发送一个字节数据

   SCL低电平期间,主机将数据位依次给SDA写入数据(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节,从机读取到一个字节,会有一个应答信号。

在这里插入图片描述
使用程序模拟此时序代码如下:

/*发送数据前,主机会发送一个起始信号,由上面的程序可知:起始信号发送完后SCL和SDA都被拉低。所以函数里面不用在拉低,直接向SDA写入数据即可。
*/
void MyI2C_SendByte(uint8_t Byte)//主机向从机发送一个字节,高位先行
{I2C_W_SDA(Byte & 0x80);//给SDA写入数据,只要Byte不是0,那么写入的就是1。因为BitActionI2C_W_SCL(1);//释放SCL,从机读取数据I2C_W_SCL(0);//拉低SCL,主机准备给SDA写入字节的次高位数据I2C_W_SDA(Byte & 0x40);//给SDA写入数据,I2C_W_SCL(1);//释放SCL,从机读取数据I2C_W_SCL(0);//拉低SCL,主机准备给SDA写入字节的次次高位数据...
}

代码优化如下:

/*发送数据前,主机会发送一个起始信号,由上面的程序可知:起始信号发送完后SCL和SDA都被拉低。所以函数里面不用在拉低,直接向SDA写入数据即可。
*/
void MyI2C_SendByte(uint8_t Byte)//主机向从机发送一个字节,高位先行
{for(uint8_t i = 0;i<8;i++){I2C_W_SDA(Byte & (0x80 >> i));//给SDA写入数据,只要Byte不是0,那么写入的就是1。因为BitActionI2C_W_SCL(1);//释放SCL,从机读取数据I2C_W_SCL(0);//拉低SCL,主机准备给SDA写入字节的次高位数据}
}

2.4:主机向从机读取一个字节数据

   接收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA,即SDA拉高

在这里插入图片描述
使用程序模拟此时序代码如下:

uint8_t I2C_R_SDA(void)//主机读SDA数据,即判断引脚的电平
{uint8_t BitValue;BitValue = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11);Delay_us(10);return BitValue;
}/*主机接收数据之前,主机会给从机发送一个字节,由上面的代码得发送完数据后此时SCL为低电平。之后释放SDA总线让从机拥有SDA总线的控制权。
*/
uint8_t MyI2C_ReceiveByte(void)
{uint8_t Byte = 0x00;//接收数据的变量I2C_W_SDA(1);//主机释放SDA,让控制权给从机,而SCL也是低电平,释放的一瞬间,从机就给SDA写入了数据I2C_W_SCL(1);if(I2C_R_SDA() == 1)//读取第一位数据{Byte |= 0x80;}I2C_W_SCL(0);//主机拉低SCL,让从机给SDA写入数据	I2C_W_SCL(1);//主机拉高SCL,准备开始读取SDA上面的数据if(I2C_R_SDA() == 1){Byte |= 0x40;}I2C_W_SCL(0);//主机拉低SCL,让从机给SDA写入数据	...return Byte;
}

代码优化如下:

uint8_t MyI2C_ReceiveByte(void)
{uint8_t Byte = 0x00;//接收数据的变量I2C_W_SDA(1);//主机释放SDA,让控制权给从机for(uint8_t i =0; i<8;i++){I2C_W_SCL(1);//主机拉高SCL,准备开始读取SDA上面的数据if(I2C_R_SDA() == 1){Byte |= (0x80 >> i);}	I2C_W_SCL(0);//主机拉低SCL,准备让从机给SDA写入数据	}return Byte;
}

2.5:主机接收应答

   接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0(SDA被从机拉低)表示应答,数据1(SDA没有被从机拉低)表示非应答(主机在接收之前,需要释放SDA,即SDA拉高

在这里插入图片描述

使用程序模拟此时序代码如下:

uint8_t I2C_R_SDA(void)//主机读SDA数据,即判断引脚的电平
{uint8_t BitValue;BitValue = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11);Delay_us(10);return BitValue;
}uint8_t MyI2C_ReceiveACK(void)//主机接收应答
{
/*主机发送完一个字节后,SCL为低电平,等待从机给SDA上面写入数据,如果拉低则代表接收成功
*/uint8_t ACKBit;I2C_W_SDA(1);//主机释放SDA,让控制权给从机I2C_W_SCL(1);//主机释放SCL,准备开始读取SDA上面的数据ACKBit = I2C_R_SDA();I2C_W_SCL(0);//主机拉低SCL,进入下一个时序单元,主机准备给SDA写入字节的数据return ACKBit;
}

2.6:主机发送应答

   主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答。

void MyI2C_SendACK(uint8_t ACKBit)//主机发送应答
{
/*从机发送完一个字节后,SCL为低电平,等待主机给SDA上面写数据,如果拉低代表接收成功。
*/I2C_W_SDA(ACKBit);//主机给SDA写入应答信号,0为应答,1为非应答I2C_W_SCL(1);//主机拉高SCL,让从机读取应答信号I2C_W_SCL(0);//主机拉低SCL,准备写入数据
}

3、程序模拟I2C的通信时序

3.1:指定地址写一个字节的数据

在这里插入图片描述
用程序模拟I2C时序实现如上图的波形:
①I2C.c文件使用程序模拟I2C时序程序如下:

#include "stm32f10x.h"                 
#include "Delay.h"                 //#define SCL(x)          GPIO_WriteBit(GPIOB,GPIO_Pin_10,(BitAction)(x))
//#define SDA(x)          GPIO_WriteBit(GPIOB,GPIO_Pin_11,(BitAction)(x))void I2C_W_SCL(uint8_t BitValue)//拉低SCL/释放SCL(拉高)
{GPIO_WriteBit(GPIOB,GPIO_Pin_10,(BitAction)BitValue);Delay_us(10);
}void I2C_W_SDA(uint8_t BitValue)//给SDA写数据(拉低SDA/释放SDA(拉高))
{GPIO_WriteBit(GPIOB,GPIO_Pin_11,(BitAction)BitValue);Delay_us(10);
}uint8_t I2C_R_SDA(void)//主机读SDA数据,即判断引脚的电平
{uint8_t BitValue;BitValue = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11);Delay_us(10);return BitValue;
}void MyI2C_Init(void)
{//1. 使能挂载在APB2总线上面的片上外设时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//2. 对GPIO_PA10/PA11进行配置GPIO_InitTypeDef GPIOInitStruct;GPIOInitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//输出开漏模式,0才有驱动能力,开漏模式没有输出低电平时,也可以作为输入GPIOInitStruct.GPIO_Speed = GPIO_Speed_50MHz;//最大输出速度GPIO_Init(GPIOB,&GPIOInitStruct);GPIO_SetBits(GPIOB,GPIO_Pin_10 | GPIO_Pin_11);//先给输出高电平,释放总线//PB10连接SCL。PB11连接SDA
}void MyI2C_Start(void)//起始信号
{I2C_W_SDA(1);//释放SDAI2C_W_SCL(1);//释放SCLI2C_W_SDA(0);//拉低SDAI2C_W_SCL(0);//拉低SDA
}void MyI2C_Stop(void)
{I2C_W_SCL(0);I2C_W_SDA(0);I2C_W_SCL(1);I2C_W_SDA(1);
}void MyI2C_SendByte(uint8_t Byte)//主机向从机发送一个字节,高位先行
{for(uint8_t i = 0;i<8;i++){I2C_W_SDA(Byte & (0x80 >> i));//给SDA写入数据,只要Byte不是0,那么写入的就是1。因为BitActionI2C_W_SCL(1);//释放SCL,从机读取数据I2C_W_SCL(0);//拉低SCL,主机准备给SDA写入字节的次高位数据}
}uint8_t MyI2C_ReceiveByte(void)
{uint8_t Byte = 0x00;//接收数据的变量I2C_W_SDA(1);//主机释放SDA,让控制权给从机for(uint8_t i =0; i<8;i++){I2C_W_SCL(1);//主机释放SCL,准备开始读取SDA上面的数据if(I2C_R_SDA() == 1){Byte |= (0x80 >> i);}	I2C_W_SCL(0);//主机拉低SCL,让从机给SDA写入数据	}return Byte;
}void MyI2C_SendACK(uint8_t ACKBit)//主机发送应答
{
/*从机发送完一个字节后,SCL为低电平,等待主机给SDA上面写数据,如果拉低代表接收成功。
*/I2C_W_SDA(ACKBit);I2C_W_SCL(1);I2C_W_SCL(0);
}uint8_t MyI2C_ReceiveACK(void)//主机接收应答
{
/*主机发送完一个字节后,SCL为低电平,等待从机给SDA上面写入数据,如果拉低则代表接收成功
*/uint8_t ACKBit;I2C_W_SDA(1);//主机释放SDA,让控制权给从机I2C_W_SCL(1);//主机释放SCL,准备开始读取SDA上面的数据ACKBit = I2C_R_SDA();I2C_W_SCL(0);//主机拉低SCL,进入下一个时序单元,主机准备给SDA写入字节的数据return ACKBit;
}

②主函数文件模拟波形的程序如下:

#include "stm32f10x.h"   
#include "MyI2C.h"
int main(void)
{MyI2C_Init();MyI2C_Start();//发送一个起始信号MyI2C_SendByte(0xD0);//发送一个字节的数据(从机地址7位+W),0表示写,1表示读MyI2C_ReceiveACK();//接收从机应答信号MyI2C_SendByte(0x19);//发送一个字节的数据(从机中的寄存器地址)MyI2C_ReceiveACK();//接收从机应答信号MyI2C_SendByte(0xAA);//发送一个字节的数据(需要发送给从机的数据)MyI2C_ReceiveACK();//接收从机应答信号MyI2C_Stop();//发送一个停止信号
}

3.2:指定地址读一个字节的数据

在这里插入图片描述

#include "stm32f10x.h"   
#include "MyI2C.h"
int main(void)
{uint8_t Data;MyI2C_Init();MyI2C_Start();//发送一个起始信号MyI2C_SendByte(0xD0);//发送一个字节的数据(从机地址7位+W),0表示写,1表示读MyI2C_ReceiveACK();//接收从机应答信号MyI2C_SendByte(0x19);//发送一个字节的数据(从机中的寄存器地址)MyI2C_ReceiveACK();//接收从机应答信号MyI2C_Start();//发送一个起始信号MyI2C_SendByte(0xD1);//发送一个字节的数据(从机地址7位+R),0表示写,1表示读MyI2C_ReceiveACK();//接收从机应答信号Data = MyI2C_ReceiveByte();//主机接收一个字节的数据MyI2C_SendACK(1);//主机发送非应答信号MyI2C_Stop();//发送一个停止信号
}

相关文章:

19:I2C一:程序模拟I2C通信时序

I2C 1、什么是I2C2、I2C的通信时序2.1&#xff1a;起始信号2.2&#xff1a;停止信号2.3&#xff1a;主机向从机发送一个字节数据2.4&#xff1a;主机向从机读取一个字节数据2.5&#xff1a;主机接收应答2.6&#xff1a;主机发送应答 3、程序模拟I2C的通信时序3.1&#xff1a;指…...

最佳实践 · MySQL 分区表实战指南

引言 在数据量急剧增长的今天&#xff0c;传统的数据库管理方式可能无法有效处理海量数据的存储和查询需求。MySQL 提供了分区表功能&#xff0c;这不仅能够帮助优化性能&#xff0c;还能简化数据管理过程。分区表允许将数据表拆分成多个逻辑上的分区&#xff0c;每个分区可以…...

详细介绍 Redis 列表的应用场景

Redis 的列表&#xff08;List&#xff09;数据类型有以下一些主要应用场景&#xff1a; 一、消息队列 生产者-消费者模式 生产者可以使用LPUSH命令将消息从列表的左端&#xff08;头部&#xff09;插入到 Redis 列表中。消费者则使用BRPOP或RPOP命令从列表的右端&#xff08;…...

游戏如何检测加速外挂

在游戏面临的众多外挂风险中&#xff0c;除了常见的内存修改挂、注入挂等作弊手段&#xff0c;黑灰产还常用「加速」手段实现作弊。 游戏安全风险分布占比图 「加速」顾名思义是指改变游戏内的速度。游戏在运行中需要以帧为单位播放画面&#xff0c;而计算每帧动画播放所需时间…...

【STM32 HAL库】OLED显示模块

【STM32 HAL库】OLED显示模块 前言理论OLED基本参数OLED基本驱动原理OLED坐标轴 应用CubeMx配置底层函数代码高层封装函数printf显示函数 前言 本文为笔者学习 OLED 的总结&#xff0c;基于keysking的视频内容&#xff0c;如有错误&#xff0c;欢迎指正 理论 OLED基本参数 …...

Redis---卸载Redis

简介 在Linux系统或者Mac系统卸载Redis。 步骤 1、停止Redis服务 #查看Redis服务进行 ps -ef | grep redis #停止Redis服务 redis-cli -a 111111 -p 6370 shutdown #再次查看Redis服务进程 ps -ef | grep redis2、删除/usr/local/bin目录下与Redis相关的文件 #查找Redis相…...

《C++模板元编程实战》阅读记录

目录 写在前面基本介绍第一部分 元编程基础技术第1章 基本技巧1.1元函数与type_traits1.1.1 元函数介绍 写在前面 这本书之前是在一片公众号里面介绍的&#xff0c;我觉的不错&#xff0c;想着提高一下自己C的水平&#xff0c;就买了一本&#xff0c;大概是2022年下半年买的&a…...

pybind11 学习笔记

pybind11 学习笔记 0. 一个例子1. 官方文档1.1 Installing the Library1.1.1 Include as A Submodule1.1.2 Include with PyPI1.1.3 Include with Conda-forge 1.2 First Steps1.2.1 Separate Files1.2.2 PYBIND11_MODULE() 宏1.2.3 example.cpython-38-x86_64-linux-gnu.so 的…...

36.贪心算法3

1.坏了的计算器&#xff08;medium&#xff09; . - 力扣&#xff08;LeetCode&#xff09; 题目解析 算法原理 代码 class Solution {public int brokenCalc(int startValue, int target) {// 正难则反 贪⼼int ret 0;while (target > startValue) {if (target % 2 0…...

htop(1) command

文章目录 1.简介2.格式3.选项4.交互式命令5.示例6.小结参考文献 1.简介 htop 是一种交互式、跨平台的基于 ncurses 的进程查看器。 类似于 top&#xff0c;但 htop 允许您垂直和水平滚动&#xff0c;并使用指向设备(鼠标)进行交互。您可以观察系统上运行的所有进程&#xff0…...

ODrive学习——添加485编码器支持

系列文章目录 文章目录 系列文章目录前言一、端口处理二、在Encoder中引入新的类型1.增加485类型2.增加串口的初始化操作3.数据处理 总结 前言 尝试在ODrive中添加485型的编码器的支持 一、端口处理 计划使用PA2及PA3作为485通信的端口。这样首先要把外部温度传感器的I/O口给…...

在OSX上: 使用brew安装nginx 后,在通过编译安装第三方模块

1. 下载nginx安装包nginx: download 2. mac环境编译源码需要安装pcre、openssl等第三方依赖&#xff0c;可参考在OSX上: 使用brew安装nginx 后&#xff0c;在通过编译安装第三方模块 - ZhYQ_note - 博客园 3. nginx可支持的配置参考Building nginx from Sources 4. 执行 ./…...

C++初阶学习第六弹------标准库中的string类

目录 一.标准库中的string类 二.string的常用接口函数 2.1string类对象的构造 2.2 string的容量操作 2.3 string类的访问与遍历 2.4 string类对象的修改 2.5 string类常用的非成员函数 三、总结 一.标准库中的string类 可以简单理解成把string类理解为变长的字符数组&#x…...

Linux基础-Makefile的编写、以及编写第一个Linux程序:进度条(模拟在 方便下载的同时,更新图形化界面)

目录 一、Linux项目自动化构建工具-make/Makefile ​编辑 背景&#xff1a; makefile小技巧&#xff1a; 二、Linux第一个小程序&#xff0d;进度条 先导&#xff1a; 1.如何利用/r,fflush(stdout)来实现我们想要的效果&#xff1b; 2.写一个倒计时&#xff1a; 进度条…...

华为云DevSecOps和DevOps

目录 1.华为云DevSecOps和DevOps 1.1 DevSecOps 1.1.1 核心功能 1.1.2 优势 1.2 DevOps 1.2.1 核心功能 1.2.2 优势 1.3 DevOps和DevSecOps的区别 1.3.1 安全性集成 1.3.2 自动化的安全工具 1.3.3 团队协作 1.3.4 质量与合规性 1.3.5 成本与风险管理 1.3.5 总结 …...

RESTful API设计中的GET与POST:何时及为何成为首选?

RESTful API设计中的GET与POST&#xff1a;何时及为何成为首选&#xff1f; 在RESTful API的设计过程中&#xff0c;HTTP方法&#xff08;GET、POST、PUT、DELETE等&#xff09;作为资源的操作标识&#xff0c;扮演着至关重要的角色。然而&#xff0c;在实际开发中&#xff0c…...

秋招自我介绍

1min 尊敬的面试官您好&#xff0c;感谢您百忙之中参加我的面试。我是来自北京大学的王峰。 在实习经历方面&#xff0c;我曾在美团和小米公司实习。在美团主要负责核身、质检、词云项目。 在核身项目中&#xff0c;完整的经历从0-1的项目上线过程 在质检项目中&#xff0c;进…...

html加载页面

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>算数模一体化</title> </head><b…...

【数据可视化】Arcgis api4.x 热力图、时间动态热力图、timeSlider时间滑块控件应用 (超详细、附免费教学数据、收藏!)

1.效果 目录 1.效果 2.安装配置 3.热力图 4.TimeSlider滑块应用 4.1 时间滑块控件 4.2 添加控件 5.时间动态热力图 2.安装配置 这里不教大家如何在前端框架使用arcgis api。不过npm安装、css如何引入、教学数据存放与图层加载的教程&#xff0c;可以浏览我之前发的一篇文…...

WEB攻防-JavaWweb项目JWT身份攻击组件安全访问控制

知识点&#xff1a; 1、JavaWeb常见安全及代码逻辑&#xff1b; 2、目录遍历&身份验证&逻辑&JWT&#xff1b; 3、访问控制&安全组件&越权&三方组件&#xff1b; 演示案例&#xff1a; JavaWeb-WebGoat8靶场搭建使用 安全问题-目录遍历&身份认…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...