STM32单片机I2C通信详解

news2025/3/12 11:02:07

文章目录

1. I2C通信概述

2. 硬件电路

3. I2C时序基本单元

4. I2C时序

4.1 指定地址写

4.2 当前地址读

4.3 指定地址读

5. I2C外设

6. I2C框图

7. I2C基本结构

8. 主机发送

9. 主机接收

10. 软件和硬件波形对比

11. 代码示例


1. I2C通信概述

I2C(Inter-Integrated Circuit)和和SPI一样,都是实现主控芯片和外挂芯片之间的数据交流。

通信线

  • SCL(Serial Clock):串行时钟线。
  • SDA(Serial Data):串行数据线。

特性

  • 同步:I2C总线是同步通信。
  • 半双工:数据可以在两个方向传输,但不能同时进行。

数据应答:I2C总线支持数据应答机制。

支持多设备

  • 一主多从:一个主设备可以连接多个从设备。
  • 多主多从:多个主设备可以连接多个从设备。

起始条件:在SCL高电平期间,SDA从高电平切换到低电平,表示通信的开始。

终止条件:在SCL高电平期间,SDA从低电平切换到高电平,表示通信的结束。

时序单元:每个时序单元从SCL的低电平开始,并以低电平结束。

从设备限制:从设备不允许产生起始和终止条件。

2. 硬件电路

所有I2C设备的SCL连在一起,SDA连在一起,并且设备的SCL和SDA均要配置成开漏输出模式

SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右

3. I2C时序基本单元

起始条件:SCL高电平期间,SDA从高电平切换到低电平

终止条件:SCL高电平期间,SDA从低电平切换到高电平

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

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

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

  1. 准备数据
    • 主机拉低SCL,将数据放在SDA线上。
  2. 发送数据位
    • SCL低电平期间
      • 若要发送0,主机将SDA拉低到低电平。
      • 若要发送1,主机释放SDA,SDA回弹到高电平。
      • SCL低电平期间允许改变SDA的电平。
    • SCL高电平期间
      • 主机松开SCL,SCL回弹到高电平。
      • 从机在SCL高电平期间读取SDA上的数据位。
      • SCL高电平期间,SDA电平不允许变化。
  3. 完成数据位传输
    • 主机在松开SCL一段时间后,继续拉低SCL,准备传输下一位。
    • 该过程在SCL同步下循环8次,传输完成一个字节(8位数据)。

从机接收数据

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

  1. 准备接收
    • 主机拉低SCL,将数据位依次放到SDA线上。
  2. 读取数据位
    • SCL高电平期间
      • 主机在SCL高电平期间读取SDA上的数据位。
      • SCL高电平期间,SDA电平不允许变化。
  3. 完成数据位接收
    • 从机在SCL低电平期间,将下一位数据放到SDA线上。
    • 该过程在SCL同步下循环8次,从机接收一个字节(8位数据)。

应答机制

在I2C通信中,主机发送一个数据后会立即接收一个位作为应答位,用来判断从机是否正确接收到数据。

从机地址

  1. 发送从机地址
    • 主机在起始条件之后,先发送一个字节(从机地址)。
    • 所有从机会接收该字节,并与自己的地址进行比较。
    • 如果地址匹配,相应的从机会响应主机的读写操作。
  2. 唯一地址
    • 同一条I2C总线上的每个设备地址必须唯一,以防止主机发送一个地址时有多个设备响应。

I2C地址类型

  • 7位地址:常用的I2C地址格式。
  • 10位地址:用于一些特殊情况下的I2C地址格式。

设备地址分配

  • 每个I2C设备在出厂时由厂商分配一个7位地址。例如,MPU6050的地址是1101 000。
  • 不同型号的设备地址不同,相同型号的设备地址相同。

地址可变部分

  • 对于挂在同一条总线上的相同型号设备,可以利用设备地址的可变部分来区分。
  • MPU6050
    • 地址的最后一位由板上的AD0引脚确定。
    • AD0引脚接低电平,地址为1101 000。
    • AD0引脚接高电平,地址为1101 001。

通过这种方式,可以在同一条I2C总线上挂载多个相同型号的设备,并通过改变引脚电平来分配不同的地址,避免地址冲突。

4. I2C时序

4.1 指定地址写

对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)

对于指定设备(从机地址),在指定地址(寄存器地址)下写入数据。

空闲状态

  • 两条总线(SCL和SDA)都是高电平。

产生起始条件

  1. 主机在SCL高电平期间拉低SDA,产生起始条件。

  2. 在起始条件之后,主机发送一个字节,该字节内容为从机地址和读写位(从机地址是7位,读写位是1位,总共8位)。

发送从机地址和读写位

  1. 发送从机地址:确定通信的对象。

  2. 发送读写位:确认接下来是写入还是读出(0表示写入,1表示读出)。

接收应答位

  1. 主机发送从机地址和读写位后,释放SDA。

  2. 从机响应后会拉低SDA,产生应答位。

  3. 应答位产生后,从机释放SDA的控制权。

发送数据

  1. 主机再次发送第二个字节,通常为寄存器地址或控制字。

  2. 接着发送第三个字节,表示要写入寄存器地址中的数据值。

产生停止条件

  1. 主机拉低SDA,为后续的上升沿做准备。

  2. 然后依次释放SCL和SDA,产生SCL高电平期间的SDA上升沿,表示停止条件。

示例

对于从机地址为1101000的设备,在其内部0x19地址的寄存器中写入0xAA这个数据,数据帧的过程如下:

  1. 起始条件:SCL高电平期间,SDA从高电平拉低。
  2. 发送从机地址和读写位(1101000+0)。
  3. 接收从机应答位。
  4. 发送寄存器地址(0x19)。
  5. 接收从机应答位。
  6. 发送数据值(0xAA)。
  7. 接收从机应答位。
  8. 停止条件:SCL高电平期间,SDA从低电平释放至高电平。

通过这些步骤,主机可以可靠地在从机的指定寄存器地址中写入数据。

4.2 当前地址读

对于指定设备(Slave Address),在当前地址指针指示的地址下,读取从机数据(Data)

产生起始条件

  1. 主机在SCL高电平期间拉低SDA,产生起始条件。

寻址和读写操作

  1. 主机首先发送一个字节,用于从机的寻址和设置读写标志位。

  2. 在本次通信中,主机发送的目标地址是1101000,读写标志位为1,表示主机接下来要读取数据。

接收从机应答位

  1. 主机发送完寻址字节后,接收从机的应答位。

  2. 从机收到第一个字节后,拉低SDA,表示应答,并将SDA的控制权交回主机。

接收数据

  1. 主机调用接收数据的时序,准备接收从机发送的数据。

  2. 从机得到允许后,在SCL低电平期间将数据写入SDA。

  3. 主机在SCL高电平期间读取SDA上的数据。

  4. 主机在SCL高电平期间依次读取8位数据,从而接收到从机发送的一个字节数据(例如:0000 1111,即0x0F)。

指针自动递增

  1. I2C通信中没有指定寄存器地址的环节,默认情况下,从机中的所有寄存器被分配到一个线性区域中。

  2. 从机内部有一个指针变量,指向某个寄存器。上电时,这个指针通常默认指向0地址。

  3. 每次写入或读出一个字节后,这个指针会自动递增,指向下一个寄存器位置。

  4. 主机读取到的数据是当前指针指向的寄存器的值。

4.3 指定地址读

对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)

写入操作

  1. 指定从机地址和读写标志位
    • 从机地址为1101000,读写标志位为0,表示要进行写操作。
  2. 从机应答
    • 从机应答后,主机发送第二个字节(0001 1001),用于指定寄存器地址。
    • 这个数据写入到从机的地址指针中,从机的寄存器指针指向0x19位置。

重新开始读操作

  1. 产生新的起始条件
    • 主机再次产生一个起始条件。
  2. 重新寻址并指定读写标志位
    • 主机重新发送从机地址(1101000)和读写标志位(此时读写标志位为1,表示读操作)。
  3. 主机接收数据
    • 从机应答后,主机开始接收一个字节的数据。
    • 这个字节的数据是从机0x19地址下的内容。

5. I2C外设

硬件资源

  • I2C外设:STM32内部集成的I2C外设,通过通信协议在时序上,驱动根据协议的规范去翻转通信引脚的高低电平。

  • I2C控制器:STM32的I2C外设包括I2C1和I2C2控制器,能够自动进行时钟生成、起始条件生成、应答位发送和接收,减轻了CPU负担。

特性

  • 多主机模式:支持多个主机设备,可变多主机模式。

  • 地址模式:支持7位和10位地址模式。

  • 通信速度:支持不同的通信速率,标准模式最高100kHz,快速模式最高400kHz。

  • DMA支持:支持DMA,在多字节传输时提高传输效率。

  • 兼容SMBus协议:SMBus协议用于电源管理系统(System Management Bus)。

10位地址模式

  • 标志位:10位地址模式下,起始后的前两个字节都用于寻址,前5位为标志位,表示这是一个10位地址模式。

  • 数据格式

    • 第一个字节:前5位标志位为11110,第6位到第8位为高3位地址。

    • 第二个字节:包含剩下的7位地址位。

  • 寻址过程

    • 第一个字节发送特定数据作为10位寻址模式的标志,即11110。

    • 如果第二个字节也是寻址,则第一个字节的前5位必须是11110。

示例说明

  • I2C地址转换

    • 二进制地址1101000转换为十六进制为0x68。

    • I2C通信时,需要发送7位地址和1位读写位。

    • 从机地址0x68左移1位再加上读写位:

      • 0x68左移1位为11010000(0xD0),加上读写位为0xD1。

    • 读写操作

      • 写操作:从机地址为0xD0。

      • 读操作:从机地址为0xD1。

I2C在STM32中的实现

  • STM32F103C8T6集成了I2C1和I2C2两个I2C外设,支持多种功能和特性,适用于各种嵌入式应用。
  • 通过配置I2C寄存器,可以实现从机地址设置、通信速度调整、DMA传输等功能,满足不同应用需求。

6. I2C框图

数据发送

  1. 写入数据寄存器:当需要发送数据时,将一个字节数据写入数据寄存器(DR)。
  2. 移位寄存器:如果移位寄存器(SR)没有数据在移位,数据寄存器中的值会转移到移位寄存器中。
  3. 连续发送:在移位过程中,可以将下一个数据字节放入数据寄存器,准备发送。一旦前一个数据移位完成,下一个数据就可以无缝衔接继续发送。
  4. 状态标志:当数据从数据寄存器转移到移位寄存器时,状态标志寄存器的TXE位会置1,表示发送寄存器为空,可以继续写入新的数据。

数据接收

  1. 接收数据:输入的数据一位一位从引脚移入移位寄存器。
  2. 移入数据寄存器:当一个字节的数据接收完整后,数据整体从移位寄存器转移到数据寄存器(DR)。
  3. 状态标志:同时,状态标志寄存器的RXNE位会置1,表示接收寄存器非空,此时可以从数据寄存器读取数据。

7. I2C基本结构

数据发送

  1. 移位寄存器与DR配合:I2C协议规定数据高位先行,因此移位寄存器的数据是向左移位的。

  2. 移位过程

    • 在发送时,最高位首先移出,接着是次高位,依次类推。

    • 每个SCL时钟周期,移位寄存器移位一次。

    • 经过8次移位后,一个字节的数据由高位到低位依次放到SDA线上。

数据接收

  1. 移位过程

    • 接收时,数据通过GPIO口从右边依次移入移位寄存器。

    • 经过8次移位后,一个字节的数据接收完成。

GPIO配置

  1. 复用开漏输出模式

    • 使用硬件I2C时,GPIO口需配置为复用开漏输出模式。
    • 复用:将GPIO的控制权交给片上硬件外设。
    • 开漏输出:I2C协议要求的端口配置,即便是开漏输出模式,GPIO也能进行输入操作。
  2. 时钟与数据传输

    • 时钟控制器通过GPIO控制时钟线(SCL)。
    • 数据通过GPIO输出到SDA端口。
    • 接收数据时,数据通过GPIO输入移位寄存器。

8. 主机发送

初始化与起始条件

  1. 总线空闲状态:在初始化后,总线默认处于空闲状态,STM32默认设置为从模式。

  2. 产生起始条件:为了开始通信,STM32需要在控制寄存器中写入相应的值以产生起始条件。

    • 查看手册中的I2C接口寄存器描述,确定起始条件的写入方法。

  3. 切换到主模式:产生起始条件后,STM32从从模式切换到主模式。在多主机模型下,STM32有数据要发送时会主动跳出来。

控制与检查标志位

  1. 控制硬件电路:在控制完硬件电路后,需要检查标志位,以确认硬件是否达到了预期状态。

  2. 发送从机地址:将从机地址写入数据寄存器(DR)。硬件电路会自动将这个字节转移到移位寄存器,并将其放到I2C总线上。

应答与事件处理

  1. 应答判断:硬件自动接收应答并进行判断。如果没有应答,硬件会置应答失败标志位,并可能触发中断来提醒。

  2. 事件EV6:寻址完成后,会触发EV6事件。

  3. 事件EV8_1:TXE标志位=1,表示数据寄存器和移位寄存器均为空,此时需要向数据寄存器写入数据以进行发送。

数据发送

  1. 写入数据寄存器:将数据写入数据寄存器(DR)。如果移位寄存器为空,数据会立即转移到移位寄存器并开始发送。

  2. 事件EV8:检测到EV8事件,表示数据寄存器为空,可以写入下一个数据。

数据发送完成

  1. 事件EV8_2:当移位寄存器和数据寄存器都为空(TXE=1),会触发EV8_2事件。

  2. 字节发送结束标志位(BTF):EV8_2后,BTF标志位表示字节传输完成。

终止条件

  1. 产生终止条件:在控制寄存器中写入相应的值以产生终止条件,结束数据传输。

9. 主机接收

 10位地址读操作流程

  1. 起始条件:产生起始条件
  2. 发送帧头:发送帧头,帧头中的读写位应为写(0),因为后面还需要发送第二个字节的地址。
  3. 发送第二个字节地址:继续发送第二个字节的8位地址,这样才能完成寻址。
  4. 重复起始条件:为了转入读的时序,必须再发送一个重复起始条件。
  5. 再次发送帧头:这次帧头中的读写位应为读(1),发送读的指令后,直接转入接收数据的程序,不再发送第二个字节的地址。

7位地址读操作流程

  1. 起始条件:在控制寄存器中写入START位,产生起始条件。
  2. 等待EV5事件:EV5事件表示起始条件已发送。
  3. 寻址与应答:发送从机地址,接收应答,结束后产生EV6事件,表示寻址完成。
  4. 数据输入:数据通过移位寄存器输入,产生EV6_1事件,表示数据正在移位。
  5. 发送应答位:根据配置,硬件自动发送应答位。
  6. 移入数据寄存器:当移位寄存器成功移入一个字节数据后,这个字节整体转移到数据寄存器,同时置RXNE标志位,表示数据寄存器非空。
  7. EV7事件:RXNE=1,表示数据寄存器非空,读取数据寄存器(DR)清除EV7事件,表示已收到数据。
  8. 持续接收数据:当数据1还未读走时,数据2可以直接移入移位寄存器,产生EV7事件,读走数据2后EV7事件消失。按照此流程,继续接收数据。
  9. 结束接收
    • 当不再需要继续接收数据时,在最后一个时序单元发生时,提前将ACK位置0,并设置终止条件请求,这就是EV7_1事件。
    • 在最后一个时序单元完成后,因ACK=0,发送非应答位。
    • 设置STOP位,产生终止条件,完成接收一个字节的时序。

10. 软件和硬件波形对比

软件I2C实现

  1. 波形特点:软件I2C的波形较为不规整,每个时钟周期和空闲时间都不一致。
  2. 操作特点:软件I2C时的引脚操作会有一定的延时,因此各个时钟周期的间隔和占空比都不均匀。

硬件I2C实现

  1. 波形特点:硬件I2C的波形更加规整,时钟周期和占空比非常一致。
  2. 操作特点:每个时钟周期后都有严格的延时,保证每个周期的时间相同。

11. 代码示例

STM32通过I2C软件读写MPU6050

STM32通过I2C软件读写MPU6050-CSDN博客

STM32通过I2C硬件读写MPU6050

STM32通过I2C硬件读写MPU6050-CSDN博客

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1841161.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

定制汽车霍尔传感器

磁电效应霍尔传感器、饱和霍尔传感器、非线性霍尔传感器 霍尔传感器原理 霍尔传感器的工作原理基于霍尔效应,即当一块通有电流的金属或半导体薄片垂直地放在磁场中时,薄片的两端会产生电位差。这种现象称为霍尔效应,两端具有的电位差值称为…

YoloV8改进策略:Block篇|即插即用|StarNet,重写星操作,使用Block改进YoloV8(全网首发)

摘要 本文主要集中在介绍和分析一种新兴的学习范式——星操作(Star Operation),这是一种通过元素级乘法融合不同子空间特征的方法,通过元素级乘法(类似于“星”形符号的乘法操作)将不同子空间的特征进行融…

(0撸)Nillion空投教程,现在开启激励测试网

Nillion 是一个去中心化的公共网络,通过启用去中心化信用评分、去中心化可信执行环境、私有 NFT、去中心化安全存储服务等用例来解锁 Web3 中重要的新实用程序 Nillion已经完成2000万美元融资、由Distributed Global领投、同时还有HashKey Capital、GSR等多家机构参…

opencascade AIS_InteractiveContext源码学习1 object display management 对象显示管理

AIS_InteractiveContext 前言 交互上下文(Interactive Context)允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是,对于已经被交互上下文识别的交互对象,必须使用上下文方法进行…

visual studio error MSB8008:

新项目编译的时候,可能由于编译器的版本不一致导致的问题。 你的电脑上有两个不同版本的VS,或者你的程序拷贝到别人的电脑上去运行,或者你是从别人那里拷贝来的项目,而你们俩用的VS版本不一样,就会在运行的时候出现这…

代码随想录算法训练营第四十三天|518. 零钱兑换 II ,LCR 103. 零钱兑换,377. 组合总和 Ⅳ

518. 零钱兑换 II - 力扣(LeetCode) class Solution {public int change(int amount, int[] coins) {// 创建dp数组,dp[i][j] 表示使用前i个硬币(下标为0的硬币是前1个)凑成总金额j的硬币组合数int[][] dp new int[coins.length …

AI在创造还是毁掉音乐

目录 1.概述 2.整体介绍 3.人机合作 3.1. AI作为助手 3.2. AI作为创意源泉 3.3. 交互式合作 3.4. AI独立创作与音乐人后期制作 3.5.试点和挑战 4.伦理道德 4.1.AI替代人类的可能性 4.2.伦理道德问题 4.3.平衡技术与创造力 4.4.小结 1.概述 近期音乐大模型的兴起&…

Python Textract库:文本提取

更多Python学习内容:ipengtao.com Textract是一个强大的Python库,用于从各种文件格式中提取文本。无论是PDF、Word文档、Excel电子表格、HTML页面还是图像,Textract都能有效地提取其中的文本内容。Textract通过集成多种开源工具和库&#xff…

Spark Core内核调度机制详解(第5天)

系列文章目录 如何构建DAG执行流程图 (掌握)如何划分Stage阶段 (掌握)Driver底层是如何运转 (掌握)确定需要构建多少分区(线程) (掌握) 文章目录 系列文章目录引言一、Spark内核调度(掌握)1.1、内容概述1.2、RDD的依赖1.3、DAG和Stage1.4、Spark Shuffl…

前端根据环境变量配置网页的title和favicon

前端根据环境变量配置网页的title和favicon 前言流程步骤一、设置environment文件二、在入口文件中配置三、删除index.html中的title和 icon link四、使用对应的打包命令进行部署 注意事项一、angular中,需要在angular.json添加favicon.ico额外的构建 前言 有些项目…

C++ | Leetcode C++题解之第167题两数之和II-输入有序数组

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> twoSum(vector<int>& numbers, int target) {int low 0, high numbers.size() - 1;while (low < high) {int sum numbers[low] numbers[high];if (sum target) {return {low …

STM32通过I2C软件读写MPU6050

文章目录​​​​​​​ 1. MPU6050 1.1 运动学概念 1.2 工作原理 2. 参数 2.1 量程选择 2.2 I2C从机地址配置 3. 硬件电路 4. 框架图 5. 软件和硬件波形对比 6. 软件I2C读写MPU6050 6.1 程序整体构架 6.2 一些需要注意的点&#xff1a; 6.3 MPU6050初始化配置 6…

Vue--》从零开始打造交互体验一流的电商平台(三)

今天开始使用 vue3 + ts 搭建一个电商项目平台,因为文章会将项目的每处代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的github上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关注本专栏,学习更多…

【2024】kafka streams的详细使用与案例练习(2)

目录 前言使用1、整体结构1.1、序列化 2、 Kafka Streams 常用的 API2.1、 StreamsBuilder2.2、 KStream 和 KTable2.3、 filter和 filterNot2.4、 map 和 mapValues2.5、 flatMap 和 flatMapValues2.6、 groupByKey 和 groupBy2.7、 count、reduce 和 aggregate2.8、 join 和 …

DSP28335:定时器

1.定时器介绍 1.1 定时器工作原理 TMS320F28335的CPU Time有三个&#xff0c;分别为Timer0&#xff0c;Timer1&#xff0c;Timer2&#xff0c;其中Timer2是为操作系统DSP/BIOS保留的&#xff0c;当未移植操作系统时&#xff0c;可用来做普通的定时器。这三个定时器的中断信号分…

RX8900/INS5A8900实时时钟-国产兼容RS4TC8900

该模块是一个符合I2C总线接口的实时时钟&#xff0c;包括一个32.768 kHz的DTCXO。 除了提供日历&#xff08;年、月、日、日、时、分、秒&#xff09;功能和时钟计数器功能外&#xff0c;该模块还提供了大量其他功能&#xff0c;包括报警功能、唤醒定时器功能、时间更新中断功能…

反激开关电源变压器设计1

特别注意&#xff1a;变压器计算出来的结果没有绝对的对与错 只要再全域范围内工作变压器不饱和就不能说变压器计算不对&#xff0c;&#xff08;输入全范围&#xff0c;输出全范围&#xff0c;温度度全范围&#xff09; 在变压器不饱和的情况下&#xff0c;只有优劣之分&…

数学建模基础:数学建模概述

目录 前言 一、数学建模的步骤 二、模型的分类 三、模型评价指标 四、常见的数学建模方法 实际案例&#xff1a;线性回归建模 步骤 1&#xff1a;导入数据 步骤 2&#xff1a;数据预处理 步骤 3&#xff1a;建立线性回归模型 步骤 4&#xff1a;模型验证 步骤 5&…

每日一练:攻防世界:简单的图片

这道题巨抽象&#xff01;巨抽象&#xff01;巨抽象&#xff01; 拿到图片&#xff0c;根据题目&#xff0c;尝试各种隐写方法。 这里就没思路了。查看WP。 根据题目的主办方&#xff1a;XSCTF。猜测XSCTF对应的是数字0&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;…

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第44课-骨骼动画

【WEB前端2024】3D智体编程&#xff1a;乔布斯3D纪念馆-第44课-骨骼动画 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎&…