DSP_28002x的SPI代码注释_文3

一、FRAM_wr(Uint16 xaddr,Uint16 wd)

骨架

一句话主线

拉低片选 → 发 WRITE 命令 → 发地址 → 发数据 → 拉高片选。

八行口诀

一拉低,二延时,三发命令,四发地址高,五发地址低,六发数据高,七发数据低,八拉高。

分组表

组 行 干什么 一句话
A 拉低 1~2 拉低片选 + 延时 选中 FM25CL64B,等它识别片选
B 发命令 3~4 赋值 WRITE + 发送 发写数据命令 0x02
C 发地址 5~8 发地址高字节 + 发地址低字节 MSB first,先高后低
D 发数据 9~12 发数据高字节 + 发数据低字节 MSB first,先高后低
E 拉高 13 拉高片选 释放 FM25CL64B,上升沿触发内部写周期并清 WEL

重要前置条件

FRAM_wr() 调用前必须先 wren_cmd(),否则 WEL=0,WRITE 被拒绝。

FRAM_wr 后的行为

  • 片选上升沿触发 FM25CL64B 内部写周期。

  • 片选上升沿清 WEL=0,下次写前要重发 WREN。


自测题

Q1:FRAM_wr 分哪几步?

A:拉低 → 发命令 → 发地址 → 发数据 → 拉高。

Q2:FRAM_wr 发了几次 spisend?分别发什么?

A:5 次 :WRITE 命令码、地址高字节 、地址低字节 、数据高字节 、数据低字节。

Q3:WRITE_INST 为什么是 0x0200?FM25CL64B 的 WRITE 命令码是多少?

A:命令码放高 8 位(左对齐),低 8 位补 0 ,SPI 取高 8 位发送,所以 0x0200 实际发的是 0x02。FM25CL64B 的 WRITE 命令码是 0x02。

Q4:地址和数据为什么都要分两次发?

A:FM25CL64B 的地址是 16 位(实际 13 位,高 3 位补 0),数据是 16 位。C2000 SPI 是 8 位字符 ,每次只能发 8 位,所以要发两次:高字节 + 低字节。

Q5:FRAM_wr 结尾为什么没有 delay(10)?

A:FM25CL64B 是铁电 ,写周期极短(ns 级),结尾不加 delay 是可以接受的。但片选上升沿会清 WEL=0,下次写前要重发 WREN。

Q6:为什么地址高字节用 xaddr,低字节用 xaddr<<8?

A:C2000 SPI 取高 8 位发送。

  • spisend(xaddr) 发 xaddr 的高 8 位(地址高字节)。

  • spisend(xaddr << 8) 发 xaddr 的低 8 位(左移后到了高 8 位)。

Q7:如果写 spisend(xaddr & 0xFF) 会怎样?

A:xaddr & 0xFF 是低 8 位,但 spisend 取高 8 位发送,实际发的是 0x00,发错了。必须用 xaddr << 8。

Q8:地址和数据的字节序是什么?

A:MSB first,高字节先发,低字节后发。FM25CL64B 要求 MSB first。

Q9:片选拉高后 WRITE 才生效吗?

A:WRITE 指令和数据在发送过程中就已经进入 FM25CL64B 的内部缓冲,片选上升沿是"锁定"和"启动内部写周期"的边沿。

Q10:FRAM_wr 和 FRAM_rd 有什么区别?

A:

  • FRAM_wr():发 WRITE(0x02) + 2 字节地址 + 2 字节数据,写操作。

  • FRAM_rd():发 READ(0x03) + 2 字节地址 + 2 字节哑元,读操作。

  • 读不需要 WREN,写必须先 WREN。

Q11:FRAM_wr 为什么不带回读校验?

A:回读校验在 store_para_FRAM() 里做。FRAM_wr() 只负责写,写完就返回。校验是"写完立即读回比较",属于上层逻辑(调用 FRAM_wr() 的上一层代码(store_para_FRAM())。它负责流程控制(写使能 → 写 → 回读 → 比较 → 记录错误),FRAM_wr() 只是它调用的一个下层函数。)。

Q12:如果忘了发 WREN 直接调 FRAM_wr 会怎样?

A:WEL=0,WRITE 被 FM25CL64B 拒绝,数据写不进去。

比喻

整体比喻:FRAM_wr = 去银行保险柜存包裹

  • FRAM 芯片 = 银行的保险柜仓库

  • 仓库里有无数个格子(存储单元),每个格子有一个编号(地址)

  • 你要往某个格子里放东西(写入数据),必须告诉柜员:放哪个格子、放什么东西

函数参数:

  • xaddr = 你要存的格子编号(地址)

  • wd = 你要存的东西(16 位数据)


逐行比喻拆解

第一步:拉低片选 → 走到银行门口,拉门把手

复制代码
GpioDataRegs.GPACLEAR.bit.GPIO11 = 1;   // 拉低片选,选中 FM25CL64B

比喻:你走到银行门口,拉低门把手(CS 拉低),银行开门了。

第二步:延时 → 等柜员坐定(tCSS)

复制代码
delay(10);                              // 延时,保证片选建立时间

比喻:门开了,等柜员从后台走到窗口坐定(tCSS),你才能开始说话。

第三步:准备并发送 WRITE 命令码 → 递"存包裹申请单"

复制代码
spixdat = WRITE_INST;                   // spixdat=0x0200:WRITE 写数据命令
spisend(spixdat);                       // 发送 WRITE 命令码给 FM25CL64B

比喻:你对柜员说"我要存东西"(递申请单,命令码 0x02)。

第四步~第五步:发送地址高字节 + 低字节 → 告诉柜员存哪个格子

复制代码
spixdat = xaddr;                        // 地址高字节(xaddr 的高 8 位)
spisend(spixdat);                       // 发送地址高字节

spixdat = (xaddr<<8);                   // 地址低字节(左移后高 8 位 = 原低 8 位)
spisend(spixdat);                       // 发送地址低字节

比喻:柜员问"存哪个格子?"你说"第 xxx 号格子"。因为格子编号是 16 位的(比如 0x1234),你要分两次说:先说高两位"12",再说低两位"34"。

为什么先发高字节再发低字节?

FM25CL64B 规定 MSB first(高位先发),这是器件规定,照做就行。

第六步~第七步:发送数据高字节 + 低字节 → 把东西放进格子

复制代码
spixdat = wd;                           // 数据高字节(wd 的高 8 位)
spisend(spixdat);                       // 发送数据高字节

spixdat = wd<<8;                        // 数据低字节(左移后高 8 位 = 原低 8 位)
spisend(spixdat);                       // 发送数据低字节

比喻:柜员问"存什么东西?"你把要存的东西递过去。因为东西是 16 位的(比如 0xABCD),也要分两次递:先递高字节"AB",再递低字节"CD"。

第八步:拉高片选 → 关上门走人

复制代码
GpioDataRegs.GPASET.bit.GPIO11 = 1;     // 片选拉高,释放 FM25CL64B

比喻:东西存完了,你拉高门把手(CS 拉高),关上门走人。柜员在关门瞬间把东西锁进保险柜(触发内部写周期)。


注意事项的比喻解释

注意①:必须先 wren_cmd() 写使能

比喻:存东西之前,必须先递"写权限申请单"(wren_cmd),否则柜员会拒绝你------"你没授权,我不能让你存"。

注意②:必须先拉低片选,再发命令,最后拉高片选

比喻:必须"开门→办事→关门"的顺序,不能反过来。没开门就递东西,东西掉地上了;办完事不关门,柜员不知道你到底办完了没有。

注意③:地址和数据都分两次发:先高字节,再低字节

比喻:格子编号和东西都是 16 位的,但窗口一次只能递 8 位,所以要分两次。FRAM 规定"高字节先发"(MSB first),照做就行。

注意④:片选拉低后加 delay(),满足建立时间

比喻:开门后等柜员坐定(tCSS),不然你刚开门就说话,柜员没听到,后面全乱了。

注意⑤:代码结尾没有 delay()

比喻:关上门之后,代码里没有等柜员处理完的时间。但 FM25CL64B 是铁电 ,写周期极短(ns 级),通常不会出错。注意片选上升沿会清 WEL=0,下次写前要重发 WREN。


整段注释

cpp 复制代码
/*******************************************************************************
 * 函数名   : FRAM_wr()
 * 简述     : 向 FM25CL64B 写一个 16 位数据
 *
 * 功能     : 拉低片选,依次发送 WRITE 指令 (0x02)、2 字节地址、2 字节数据,
 *            拉高片选触发内部写周期。具体分 6 步:
 *            1. 拉低 GPIO 片选,选中 FM25CL64B;
 *            2. 发送 WRITE 指令 (0x02);
 *            3. 发送地址高字节;
 *            4. 发送地址低字节;
 *            5. 发送数据高字节;
 *            6. 发送数据低字节,拉高片选,触发内部写周期。
 *
 * 参数     : xaddr ------ 铁电字节地址(16 位,实际只用低 13 位)
 *            wd    ------ 要写入的 16 位数据
 * 返回值   : 无
 * 调用关系 : 被 store_para_FRAM() 调用;内部调用 spisend()
 *
 * 公式计算 : 无(本函数为纯数据写入)
 *
 * 片选     : GPIO11,低有效
 *
 * 注意事项 : 1. 调用本函数前必须先发 WREN(0x06),否则 WEL=0 被拒绝;
 *            2. 片选在整个操作期间必须保持低,操作结束才拉高;
 *            3. 片选上升沿触发 FM25CL64B 内部写周期,同时清 WEL;
 *            4. 本函数不带回读校验,校验在 store_para_FRAM() 中做。
 ******************************************************************************/
void FRAM_wr(Uint16 xaddr, Uint16 wd)
{
    // 第 1 步:拉低片选,选中 FM25CL64B
    // GPACLEAR 写 1 表示对应位清零,GPIO11 输出低电平,片选有效
    GpioDataRegs.GPACLEAR.bit.GPIO11 = 1;    // 片选拉低(GPIO11=0,低有效)

    // 片选建立时间:等 GPIO 电平稳定后再发指令
    delay(10);                                // 延时 10 个单位,保证建立时间

    // 第 2 步:发送 WRITE 指令 (0x02)
    // spixdat 赋值为 WRITE_INST(0x0200,左对齐)
    spixdat = WRITE_INST;                    // 准备 WRITE 指令值
    spisend(spixdat);                        // 发送 WRITE 指令,内部等待收发完成

    // 第 3 步:发送地址高字节
    // xaddr 高 8 位左对齐后发送(C2000 SPI 只取高 8 位)
    spixdat = xaddr;                         // 准备地址高字节
    spisend(spixdat);                        // 发送地址高字节

    // 第 4 步:发送地址低字节
    // xaddr 左移 8 位后,低 8 位移到高 8 位,SPI 取高 8 位发送
    spixdat = (xaddr << 8);                  // 准备地址低字节(左移后高 8 位 = 原低 8 位)
    spisend(spixdat);                        // 发送地址低字节

    // 第 5 步:发送数据高字节
    // wd 高 8 位左对齐后发送
    spixdat = wd;                            // 准备数据高字节
    spisend(spixdat);                        // 发送数据高字节

    // 第 6 步:发送数据低字节
    // wd 左移 8 位后,低 8 位移到高 8 位,SPI 取高 8 位发送
    spixdat = (wd << 8);                     // 准备数据低字节(左移后高 8 位 = 原低 8 位)
    spisend(spixdat);                        // 发送数据低字节

    // 第 6 步(续):拉高片选,触发 FM25CL64B 内部写周期
    // GPASET 写 1 表示对应位置 1,GPIO11 输出高电平,操作结束
    GpioDataRegs.GPASET.bit.GPIO11 = 1;      // 片选拉高(GPIO11=1,写周期开始)
}

逐行逐位分析

第 1 行:GpioDataRegs.GPACLEAR.bit.GPIO11 = 1

复制代码
GpioDataRegs.GPACLEAR.bit.GPIO11 = 1;    // 片选拉低(GPIO11=0,低有效)

位含义

位 名称 值 含义
GPIO11 GPACLEAR 对应位 1 GPIO 清零寄存器。写 1 将该位清零 (输出低电平);写 0 不影响。GPIO11 作为 FM25CL64B 的片选,低有效。

为什么用 GPACLEAR

原子操作,写 1 只清零 GPIO11,不影响其他位,避免读-改-写竞态。

Q&A

  • Q:片选拉低后要 delay 吗?

    A:要。delay(10) 保证 FM25CL64B 检测到片选有效(tCSS)。

  • Q:GPACLEAR 和 GPADAT 有什么区别?

    A:GPACLEAR 是"写 1 清零"寄存器,原子操作;GPADAT 读写整个端口,有竞态风险。


第 2 行:delay(10)

复制代码
delay(10);                                // 延时 10 个单位,保证建立时间

作用

保证 FM25CL64B 在第一个时钟沿之前检测到片选有效(tCSS)。

Q&A

  • Q:delay(10) 是多久?

    A:纯软件空循环,delay(10) 表示循环 10 次,F28002x 100MHz 下约几百纳秒。对 FM25CL64B 的 ns 级 tCSS 足够。


第 3 行:spixdat = WRITE_INST

复制代码
spixdat = WRITE_INST;                    // 准备 WRITE 指令值

位含义

位 名称 值 含义
WRITE_INST 宏定义 0x0200 WRITE 指令。左对齐:高 8 位 = 0x02,低 8 位 = 0x00。

FM25CL64B 的 WRITE 指令

项目 值
指令名 WRITE
编码 0000_0010b (0x02)
作用 写数据到指定地址
前置条件 必须先 WREN
后续字节 2 字节地址 + N 字节数据

Q&A

  • Q:WRITE 指令需要先 WREN 吗?

    A:需要。WEL=0 时 WRITE 被拒绝。store_para_FRAM() 里先调 wren_cmd() 再调 FRAM_wr()。

  • Q:WRITE_INST 为什么是 0x0200 而不是 0x02?

    A:C2000 SPI 8 位模式下数据必须左对齐。0x0200 高 8 位是 0x02,SPI 取高 8 位发送,正确。


第 4 行:spisend(spixdat)

复制代码
spisend(spixdat);                        // 发送 WRITE 指令,内部等待收发完成

执行过程

步骤 操作
1 写 SPITXBUF = 0x0200
2 SPI 硬件取高 8 位 0x02,移位输出
3 spisend 内部 while(INT_FLAG==0) 等待
4 读 SPIRXBUF,清 INT_FLAG

Q&A

  • Q:WRITE 指令发送后,FM25CL64B 会返回数据吗?

    A:不会。WRITE 是写指令,FM25CL64B 在 SOMI 上不返回有效数据。spiimg 里是无意义值。


第 5 行:spixdat = xaddr

复制代码
spixdat = xaddr;                         // 准备地址高字节
spisend(spixdat);                        // 发送地址高字节

位含义

位 名称 值 含义
xaddr 参数 16 位地址 铁电字节地址。高 8 位 是地址的高字节,低 8 位是地址的低字节。

地址发送分析

  • xaddr 高 8 位 = 地址高字节。

  • spisend(xaddr) 左对齐后发送的是 xaddr 的高 8 位,即地址高字节。

FM25CL64B 地址要求

项目 值
地址宽度 13 位(8KByte)
地址字节数 2 字节
字节序 MSB first(高字节先发)
高位补 0 高 3 位补 0

Q&A

  • Q:为什么先发地址高字节?

    A:FM25CL64B 要求 MSB first,地址高字节先发,低字节后发。

  • Q:xaddr = 0x0010 时,实际发的是什么?

    A:spisend(0x0010) 左对齐后发 0x00(高字节),spisend(0x1000) 左对齐后发 0x10(低字节)。


第 6 行:spixdat = (xaddr << 8)

复制代码
spixdat = (xaddr << 8);                  // 准备地址低字节(左移后高 8 位 = 原低 8 位)
spisend(spixdat);                        // 发送地址低字节

位含义

位 名称 值 含义
xaddr << 8 移位操作 16 位 把 xaddr 的低 8 位移到高 8 位。SPI 取高 8 位发送,即发送原 xaddr 的低 8 位。

移位分析

  • xaddr = 0x0010

  • xaddr << 8 = 0x1000

  • spisend(0x1000) 左对齐后发高 8 位 0x10,即原 xaddr 的低 8 位。

Q&A

  • Q:为什么用 xaddr << 8 而不是 xaddr & 0xFF?

    A:因为 C2000 SPI 取高 8 位发送。要发低 8 位,必须把它移到高 8 位。xaddr << 8 正好做到。

  • Q:如果写 spisend(xaddr & 0xFF) 会怎样?

    A:xaddr & 0xFF = 0x10,spisend(0x0010) 左对齐后发高 8 位 0x00,发错了。


第 7 行:spixdat = wd

复制代码
spixdat = wd;                            // 准备数据高字节
spisend(spixdat);                        // 发送数据高字节

位含义

位 名称 值 含义
wd 参数 16 位数据 要写入的数据。高 8 位 是数据高字节,低 8 位是数据低字节。

数据发送分析

  • spisend(wd) 左对齐后发送 wd 的高 8 位,即数据高字节。

Q&A

  • Q:为什么先发数据高字节?

    A:FM25CL64B 要求 MSB first,数据高字节先发。

  • Q:wd = 0x1234 时,实际发的是什么?

    A:spisend(0x1234) 左对齐后发 0x12(高字节),spisend(0x3400) 左对齐后发 0x34(低字节)。


第 8 行:spixdat = (wd << 8)

复制代码
spixdat = (wd << 8);                     // 准备数据低字节(左移后高 8 位 = 原低 8 位)
spisend(spixdat);                        // 发送数据低字节

位含义

位 名称 值 含义
wd << 8 移位操作 16 位 把 wd 的低 8 位移到高 8 位。SPI 取高 8 位发送,即发送原 wd 的低 8 位。

移位分析

  • wd = 0x1234

  • wd << 8 = 0x3400

  • spisend(0x3400) 左对齐后发高 8 位 0x34,即原 wd 的低 8 位。

Q&A

  • Q:数据和地址的发送方式一样吗?

    A:一样。都是"高字节用原值,低字节用左移 8 位",因为 C2000 SPI 取高 8 位发送。


第 9 行:GpioDataRegs.GPASET.bit.GPIO11 = 1

复制代码
GpioDataRegs.GPASET.bit.GPIO11 = 1;      // 片选拉高(GPIO11=1,写周期开始)

位含义

位 名称 值 含义
GPIO11 GPASET 对应位 1 GPIO 置位寄存器。写 1 将该位置 1 (输出高电平);写 0 不影响。FM25CL64B 片选高有效表示操作结束。

FM25CL64B 的 WRITE 时序

阶段 片选 数据
操作前 高 ---
发送 WRITE 指令 低 0x02
发送地址高字节 低 xaddr 高 8 位
发送地址低字节 低 xaddr 低 8 位
发送数据高字节 低 wd 高 8 位
发送数据低字节 低 wd 低 8 位
操作后 高 ---

片选上升沿的作用:

  1. 触发 FM25CL64B 内部写周期:数据被写入铁电存储单元。

  2. 清 WEL 位:WEL 自动清 0,下次写前要重发 WREN。

Q&A

  • Q:片选拉高后 WRITE 才生效吗?

    A:WRITE 指令和数据在发送过程中就已经进入 FM25CL64B 的内部缓冲,片选上升沿是"锁定"和"启动内部写周期"的边沿。

  • Q:片选拉高后 WEL 会怎样?

    A:WEL 自动清 0。下次写前要重发 WREN。

  • Q:片选拉高后要 delay 吗?

    A:FM25CL64B 是铁电,写周期极短(ns 级),通常不需要。但严格来说可以加一个短 delay。


四、逐位分析总结表

序 代码 寄存器/位 值 中文含义 面试要点
1 GPACLEAR.GPIO11 = 1 GPACLEAR.bit.GPIO11 1 片选拉低 原子操作,写 1 清零;低有效
2 delay(10) --- --- 片选建立时间 保证 FM25CL64B 检测到片选
3 spixdat = WRITE_INST 全局变量 0x0200 WRITE 指令值 左对齐,高 8 位 = 0x02
4 spisend(spixdat) SPITXBUF 0x0200 发送 WRITE 指令 8 位模式只发高 8 位
5 spixdat = xaddr 全局变量 xaddr 地址高字节 高 8 位 = 地址高字节
6 spisend(spixdat) SPITXBUF xaddr 发送地址高字节 MSB first
7 spixdat = xaddr << 8 全局变量 xaddr<<8 地址低字节 左移后高 8 位 = 原低 8 位
8 spisend(spixdat) SPITXBUF xaddr<<8 发送地址低字节 MSB first
9 spixdat = wd 全局变量 wd 数据高字节 高 8 位 = 数据高字节
10 spisend(spixdat) SPITXBUF wd 发送数据高字节 MSB first
11 spixdat = wd << 8 全局变量 wd<<8 数据低字节 左移后高 8 位 = 原低 8 位
12 spisend(spixdat) SPITXBUF wd<<8 发送数据低字节 MSB first
13 GPASET.GPIO11 = 1 GPASET.bit.GPIO11 1 片选拉高 触发内部写周期,清 WEL

五、提问与答案解析

Q1:FRAM_wr() 的作用是什么?

答:向 FM25CL64B 写一个 16 位数据。流程为:拉低片选 → 发 WRITE 指令 (0x02) → 发 2 字节地址 → 发 2 字节数据 → 拉高片选触发内部写周期。

Q2:FRAM_wr() 前为什么必须先 WREN?

答 :FM25CL64B 的 WEL 位必须为 1 才能写数据。WEL 只有 WREN 指令能置 1。所以 store_para_FRAM() 里先调 wren_cmd() 再调 FRAM_wr()。

Q3:WRITE_INST 为什么是 0x0200 而不是 0x02?

答:C2000 SPI 8 位模式下数据必须左对齐。0x0200 高 8 位是 0x02,SPI 取高 8 位发送,正确。

Q4:为什么地址和数据都要发两次?

答:FM25CL64B 的地址是 16 位(实际 13 位,高 3 位补 0),数据是 16 位。C2000 SPI 是 8 位字符,每次只能发 8 位,所以要发两次:高字节 + 低字节。

Q5:为什么地址高字节用 xaddr,低字节用 xaddr<<8?

答:C2000 SPI 取高 8 位发送。

  • spisend(xaddr) 发 xaddr 的高 8 位(地址高字节)。

  • spisend(xaddr << 8) 发 xaddr 的低 8 位(左移后到了高 8 位)。

Q6:如果写 spisend(xaddr & 0xFF) 会怎样?

答 :xaddr & 0xFF 是低 8 位,但 spisend 取高 8 位发送,实际发的是 0x00,发错了。必须用 xaddr << 8。

Q7:地址和数据的字节序是什么?

答 :MSB first,高字节先发,低字节后发。FM25CL64B 要求 MSB first。

Q8:片选拉高后 WRITE 才生效吗?

答:WRITE 指令和数据在发送过程中就已经进入 FM25CL64B 的内部缓冲,片选上升沿是"锁定"和"启动内部写周期"的边沿。

Q9:片选拉高后 WEL 会怎样?

答:WEL 自动清 0。下次写前要重发 WREN。

Q10:FRAM_wr() 为什么不带回读校验?

答 :回读校验在 store_para_FRAM() 里做。FRAM_wr() 只负责写,写完就返回。校验是"写完立即读回比较",属于上层逻辑。

Q11:如果忘了拉高片选会怎样?

答:FM25CL64B 一直选中,下一条指令被当作本次操作的后续字节,命令错位。

Q12:FRAM_wr() 和 FRAM_rd() 有什么区别?

答:

  • FRAM_wr():发 WRITE(0x02) + 2 字节地址 + 2 字节数据,写操作。

  • FRAM_rd():发 READ(0x03) + 2 字节地址 + 2 字节哑元,读操作。

  • 读不需要 WREN,写必须先 WREN。


六、一句话总结

FRAM_wr() 就干六件事:拉低片选 → 发 WRITE(0x0200) → 发地址高字节 → 发地址低字节 → 发数据高字节 → 发数据低字节 → 拉高片选。

核心点:WRITE 前必须先 WREN ;WRITE 指令是 0x0200(左对齐) ;地址和数据都是 MSB first,高字节先发 ;低字节用 << 8 左移到高 8 位 ;片选上升沿触发内部写周期并清 WEL。

面试重点:WRITE 前必须 WREN、左对齐原因、地址/数据字节序、低字节左移、片选上升沿作用。

相关推荐
海绵宝宝转agent1 小时前
Leetcode100+面经
java·笔记·学习·算法·leetcode·深度优先
前进的李工1 小时前
Agent 学习笔记 01:从工具调用到 ReAct 循环
笔记·学习·llm·agent·react·工具调用
海绵宝宝转agent1 小时前
LeetCode100个人题解+java面经总结
java·开发语言·笔记·学习·算法
zhangrelay10 小时前
新版|-|单片机原理与接口技术-2026持续改进优化-从MEGA2560-ESP32与Wokwi到ROS2-Lyrical与具身智能栈
笔记·单片机·嵌入式硬件·学习
Jimmy11 小时前
深夜突袭:我们的午夜战场
笔记·产品·电子书
志尊宝12 小时前
AI原生前端开发(025):端侧AI实战项目:智能笔记助手
人工智能·笔记·ai-native
lll235269177913 小时前
线下多人发言对比与录音操作
笔记·智能手机
叼烟扛炮14 小时前
Linux 学习笔记(三十三):线程互斥——互斥锁(Mutex)与死锁
linux·运维·服务器·笔记·学习·1024程序员节
深圳老胡16 小时前
STM32C5A3ZG 网络调试总结:从启动失败到连续 Ping 稳定
笔记·stm32·单片机·代码规范