CAN 通信协议详解:从硬件接线、帧格式到仲裁机制、Bus-Off 与工程调试

CAN 通信协议详解:从硬件接线、帧格式到仲裁机制、Bus-Off 与工程调试

在嵌入式开发中,CAN 通信广泛用于汽车电子、工业控制、电机驱动和设备之间的数据交换。

很多初学者第一次接触 CAN 时,会把它理解为"另一种串口":

配置波特率,发送几个字节,另一端接收即可。

但真正进入项目后,往往会遇到这些问题:

  • 为什么 CAN_TX 和 CAN_RX 不能直接连接其他设备?
  • 为什么总线两端需要 120Ω 电阻?
  • 多个节点同时发送,为什么不会把数据撞坏?
  • 为什么一块开发板发送 CAN 报文可能一直失败?
  • 收到了 ACK,是否代表对方已经执行命令?
  • 为什么设备运行一段时间后进入 Bus-Off?
  • 为什么低负载时正常,高负载时却开始丢消息?

本文以经典 CAN 和高速双线 CAN 总线为主要对象,结合实际开发场景,详细介绍协议原理、硬件连接和工程注意事项,并补充 CAN FD 的主要区别。


一、CAN 是什么?

CAN 的全称是 Controller Area Network,即控制器局域网。

它是一种支持多个节点共享总线的通信机制,具有以下特点:

  • 多主通信。
  • 广播式报文传输。
  • 基于标识符的优先级仲裁。
  • 差分信号传输。
  • 错误检测与故障隔离。
  • 适合多个嵌入式设备之间交换控制和状态信息。

CAN 不要求存在一个固定的主机。只要满足总线访问条件,多个节点都可以主动发送报文。

典型网络如下:

text 复制代码
控制器节点 ──────── CAN 总线 ──────── 电机节点
                        │
                        ├────────── 传感器节点
                        │
                        └────────── 显示节点

需要注意:上图只表示节点关系。实际高速 CAN 接线通常采用线型主干,支线应尽量短。

1.1 CAN 是广播通信,不是固定地址通信

一个节点发送报文时,总线上的其他节点都能观察到这份报文。

接收节点再根据报文标识符和过滤配置,决定是否把它交给软件处理。

例如,应用协议约定:

text 复制代码
ID 0x100:电机控制命令
ID 0x200:电机状态
ID 0x300:温度数据

这里的 ID 表示消息含义及其仲裁优先级,不天然等同于某个设备的地址。

上层协议可以把源地址、目的地址编码进 ID,但那属于应用协议的设计,而不是 CAN 的固定规定。

CAN 的广播和标识符机制可参考 Kvaser CAN 协议介绍。


二、CAN 控制器与 CAN 收发器有什么区别?

理解 CAN 硬件时,首先要区分两个模块:

text 复制代码
MCU / 软件
    ↓
CAN 控制器
    ↓ CAN_TX / CAN_RX
CAN 收发器
    ↓ CAN_H / CAN_L
CAN 总线

2.1 CAN 控制器:处理协议

CAN 控制器负责:

  • 组织发送帧。
  • 接收和检查报文。
  • 参与仲裁。
  • 处理 CRC、ACK 和错误检测。
  • 管理发送邮箱、接收 FIFO。
  • 提供过滤器和错误状态。

很多 MCU 已经内置 CAN 控制器,因此不需要额外的外部控制器。

2.2 CAN 收发器:处理电气信号

CAN 收发器负责在两种信号之间转换:

text 复制代码
控制器侧:TXD / RXD 逻辑电平
总线侧:CAN_H / CAN_L 差分信号

因此:

MCU 的 CAN_TX 和 CAN_RX 不能直接当作 CAN_H 和 CAN_L 使用。

还应检查收发器的:

  • 供电电压。
  • IO 电平兼容性。
  • 工作模式。
  • 待机或使能引脚。
  • 共模范围。
  • 总线保护能力。
  • 是否支持目标 CAN FD 数据速率。

典型节点连接和物理层要求可参考 TI:CAN 物理层要求。


三、CAN_H、CAN_L、显性和隐性怎么理解?

3.1 差分传输

高速 CAN 主要根据 CAN_H 和 CAN_L 之间的电压差判断总线状态:

text 复制代码
差分电压 = CAN_H 电压 − CAN_L 电压

差分传输有利于抑制同时耦合到两根线上的共模干扰,但这不代表总线对任何干扰和地电位差都免疫。

线缆、接地、隔离和保护设计仍然重要。

3.2 显性与隐性

CAN 中的逻辑位通常对应:

逻辑值 总线状态
0 显性,Dominant
1 隐性,Recessive

最关键的规则是:

显性可以覆盖隐性。

如果一个节点发送显性 0,另一个节点发送隐性 1,总线显示显性 0。

这一特性是 CAN 仲裁机制的基础。

3.3 电压值不能机械套用

常见 5V 高速 CAN 收发器在正常条件下,显性状态可能表现为 CAN_H 上升、CAN_L 下降;隐性时两线电位接近。

但实际电压会受器件、负载和工作条件影响。

工程中应以收发器数据手册中的:

  • 输出范围。
  • 接收阈值。
  • 共模范围。
  • 测试条件。

作为判断依据,而不是把某一组典型电压当作所有器件的绝对标准。


四、为什么需要两个 120Ω 终端电阻?

4.1 终端电阻用于抑制反射

当信号沿线缆传播时,如果线缆末端阻抗不匹配,会产生反射,影响波形和采样。

高速 CAN 通常采用特性阻抗约为 120Ω 的双绞线,并在主干两端分别进行终端匹配。

典型连接如下:

text 复制代码
120Ω                                            120Ω
 │                                                │
CAN_H ───────────────────────────────────────── CAN_H
CAN_L ───────────────────────────────────────── CAN_L
          │                 │
        节点 A            节点 B

两个终端电阻都跨接在 CAN_H 与 CAN_L 之间。

4.2 不是每个节点都加终端电阻

正确理解是:

终端匹配取决于总线物理端点,不取决于节点数量。

若每个节点都增加一个 120Ω 电阻,总线等效负载会过重,可能影响正常驱动。

4.3 为什么断电测量通常约为 60Ω?

两个 120Ω 电阻并联:

text 复制代码
R = 120Ω ∥ 120Ω = 60Ω

在整网断电、测量点正确且没有其他电路影响时,CAN_H 与 CAN_L 之间通常能测得约 60Ω。

可作初步判断:

测量现象 可能原因
约 60Ω 两个 120Ω 终端可能均已接入
约 120Ω 可能只接入一个终端
明显小于 60Ω 可能存在多余终端或其他负载
很大或开路 可能缺少终端、线缆断开

不过,电阻值正常并不能证明整个网络一定正常。仍需检查接线、波形和工作状态。

4.4 支线为什么要短?

较长支线会引入传播延迟和反射。

因此,高速 CAN 一般建议:

  • 使用线型主干。
  • 支线尽量短。
  • 避免随意采用长支线星形连接。
  • 结合波特率、线缆和节点数量评估拓扑。

终端匹配及传播延迟设计可参考 TI 物理层应用报告。


五、经典 CAN 报文包含哪些字段?

经典 CAN 数据帧可以概括为:

text 复制代码
SOF → 仲裁字段 → 控制字段 → 数据字段 → CRC → ACK → EOF
字段 主要作用
SOF 帧开始
仲裁字段 包含标识符及相关仲裁位
控制字段 包含数据长度等控制信息
数据字段 应用数据
CRC 检测传输错误
ACK 接收节点确认
EOF 帧结束

这是简化结构。具体字段组成还要区分标准帧和扩展帧。

5.1 标准帧

标准帧使用 11 位标识符:

text 复制代码
0x000 ~ 0x7FF

5.2 扩展帧

扩展帧使用 29 位标识符:

text 复制代码
0x00000000 ~ 0x1FFFFFFF

扩展帧提供更大的 ID 空间,但相应报文开销也更大。

5.3 经典 CAN 数据长度

经典 CAN 数据帧最多携带:

text 复制代码
8 字节数据

DLC 是数据长度编码。对于普通经典 CAN 数据帧,通常使用 0~8 表示相应的数据长度。

5.4 数据帧与远程帧

经典 CAN 支持:

  • 数据帧:携带实际数据。
  • 远程帧:请求相应数据,自身不携带数据字段。

它们通过 RTR 等相关字段区分。

在许多现代应用中,通常采用周期发送和应用层命令/响应,而不是依赖远程帧机制。


六、CAN FD 与经典 CAN 有什么区别?

CAN FD 在经典 CAN 基础上扩展了数据长度和速率能力。

对比项 经典 CAN CAN FD
最大数据长度 8 字节 64 字节
数据阶段速率 与仲裁阶段相同 可通过 BRS 切换到更高速率
远程帧 支持 不支持
ID 长度 11 位或 29 位 11 位或 29 位

CAN FD 数据长度不是任意 0~64 字节全部直接编码。常见 DLC 映射为:

text 复制代码
0~8、12、16、20、24、32、48、64 字节

设计 CAN FD 网络时,需要同时检查:

  • 控制器是否支持 CAN FD。
  • 收发器是否满足目标数据速率。
  • 总线拓扑是否适合更高速的数据阶段。
  • 网络中的其他节点是否兼容 FD 报文。

不要默认经典 CAN 节点能正常容忍 CAN FD 报文。


七、多个节点同时发送,CAN 如何仲裁?

CAN 使用非破坏性逐位仲裁。

7.1 发送节点会监测总线

节点发送时,同时观察总线状态。

在仲裁字段中,如果节点:

text 复制代码
发送隐性 1
却读到显性 0

就说明有其他节点在这一位发送了显性 0。

该节点输掉仲裁,停止竞争,转为接收,让获胜节点继续发送。

7.2 仲裁示例

假设两个节点同时发送标准数据帧:

text 复制代码
A:ID = 0x100
B:ID = 0x180

对应 11 位标识符:

text 复制代码
A:0 0 1 0 0 0 0 0 0 0 0
B:0 0 1 1 0 0 0 0 0 0 0

前三位相同,第 4 位:

text 复制代码
A 发送 0
B 发送 1
总线显示 0

因此:

text 复制代码
A 获胜,继续发送
B 退出仲裁,等待下一次机会

7.3 为什么叫非破坏性?

因为获胜节点的报文不会因仲裁竞争而被破坏。

输掉仲裁也不属于传输错误,不能把它与 CRC 错误或位错误混为一谈。

7.4 "ID 越小优先级越高"有前提

对于同格式的数据帧,比较 ID 时,数值越小,仲裁优先级越高。

但比较不同帧格式或数据帧与远程帧时,还要考虑 SRR、IDE、RTR 等位。

另外:

高优先级报文不能打断一份已经开始正常发送的报文。

它只影响下一次总线竞争。

CAN 的非破坏性仲裁机制可参考 Kvaser CAN 协议介绍。


八、ACK 到底表示什么?

ACK 是 CAN 开发中最容易误解的机制之一。

8.1 ACK 的产生过程

在 ACK 槽中:

text 复制代码
发送节点:发送隐性
正确接收报文的正常接收节点:发送显性

发送端观察到显性,就知道至少有接收节点正确接收了这份报文。

8.2 ACK 不等于目标设备执行成功

ACK 只能说明协议层接收情况,不能证明:

  • 指定目标设备一定收到。
  • 软件已经从 FIFO 取出报文。
  • 对应任务已完成处理。
  • 控制命令已经执行。
  • 执行结果正确。

总线上的其他正常节点也可能提供 ACK。

而且,验收过滤器没有把这条报文交给应用程序,并不意味着节点一定不会 ACK。

8.3 关键命令需要业务响应

例如:

text 复制代码
控制器发送:启动电机,序号 15
电机返回:序号 15,已启动

这种业务应答才用于确认目标设备的处理结果。

因此应区分:

text 复制代码
CAN ACK:报文接收确认
业务响应:命令执行确认

8.4 为什么只有一块板可能发不成功?

正常外部总线通信需要其他接收节点提供 ACK。

如果总线上只有一个发送节点,它可能持续发生 ACK 错误。

另外:

  • 监听模式分析仪通常不会 ACK。
  • 正常模式分析仪可能提供 ACK。
  • 内部回环模式属于另一类测试。
  • 自接收并不自动等同于外部 ACK。

正常应答过程可参考 TI CAN 物理层报告。


九、CAN 如何检测错误?

CAN 提供多种错误检测机制。

错误类型 简要含义
位错误 发送位与监测位不一致,协议规定的例外除外
填充错误 位填充规则被破坏
CRC 错误 接收计算结果与报文 CRC 不一致
格式错误 固定格式字段出现不符合规则的位
ACK 错误 发送端未获得正确应答

9.1 位填充是什么?

经典 CAN 在规定的帧区域中,会在连续 5 个相同位后插入一个相反位。

例如:

text 复制代码
原始位序列:0 0 0 0 0
插入填充位:0 0 0 0 0 1

接收端按规则去除填充位。

它有助于维持同步,同时使实际报文长度与数据内容相关。

因此,计算总线负载时不能只统计有效数据字节。

9.2 检测到错误后会怎样?

节点检测到错误后,会根据当前错误状态发送相应错误标志,使当前报文被判为无效。

发送控制器通常具有自动重传机制,但具体行为受控制器配置影响,例如是否关闭自动重传、是否采用单次发送模式。

应用程序应区分:

text 复制代码
报文已进入发送邮箱
报文已开始发送
报文已成功完成发送

它们不是同一个状态。


十、Error Active、Error Passive 和 Bus-Off

CAN 通过错误计数和状态转换,限制异常节点对总线的影响。

两个重要计数器是:

text 复制代码
TEC:发送错误计数器
REC:接收错误计数器

10.1 Error Active:错误主动状态

通常当:

text 复制代码
TEC < 128
REC < 128

节点处于错误主动状态,可以正常通信,并在检测错误时发送主动错误标志。

10.2 Error Passive:错误被动状态

当任一错误计数达到 128:

text 复制代码
TEC ≥ 128
或者
REC ≥ 128

节点进入错误被动状态。

它仍可能参与通信,但错误标志和发送约束发生变化,以降低对网络的影响。

10.3 Bus-Off:总线关闭状态

当:

text 复制代码
TEC > 255

节点进入 Bus-Off,停止正常参与总线通信。

需要强调:

Bus-Off 由发送错误计数 TEC 触发,REC 超过阈值不会直接触发 Bus-Off。

10.4 不是每个错误都简单"计数加 1"

TEC 和 REC 的增减有具体规则,并存在例外。

一个重要例子:

仅因为缺少 ACK 而不断重发,并不意味着节点一定持续增加 TEC,最终进入 Bus-Off。 错误被动状态下的特定 ACK 错误条件存在计数例外。

因此,诊断时不能简单推断:

text 复制代码
没有 ACK → 一直加错误计数 → 必然 Bus-Off

应结合实际控制器状态和协议规则分析。

10.5 Bus-Off 不能只靠反复复位

推荐流程:

text 复制代码
检测 Bus-Off
    ↓
保存错误状态和诊断信息
    ↓
按业务需要进入安全状态
    ↓
检查接线、位时序和波形
    ↓
满足协议及控制器恢复条件
    ↓
恢复通信并统计重复发生次数

是否自动恢复、如何触发恢复,要参考具体控制器手册。


十一、波特率与位时序怎么配置?

11.1 波特率的基本关系

常见计算关系为:

text 复制代码
bitrate = CAN 内核时钟 /(分频值 × 每位时间量子数)

例如:

text 复制代码
CAN 时钟:48 MHz
分频:6
每位:16 个时间量子

则:

text 复制代码
48 MHz /(6 × 16)= 500 kbit/s

但寄存器可能采用"实际值减 1"等编码方式,不能直接把公式中的数字照搬进寄存器。

11.2 采样点是什么?

CAN 控制器会在每个位时间的某个位置读取总线状态,这个位置就是采样点。

采样点过早或配置不合适,可能使控制器在信号尚未稳定时采样。

配置时需要考虑:

  • 总线长度。
  • 收发器传播延迟。
  • 节点时钟误差。
  • 支线和拓扑。
  • 目标位速率。

11.3 SJW 是什么?

SJW 是同步跳转宽度,用于限制重同步时允许进行的时间调整。

它不是越大越好,应与位时序和控制器要求匹配。

11.4 波特率相同也可能通信异常

两个节点都标注为 500 kbit/s,不代表配置一定正确。

还应核对:

  • 实际 CAN 时钟。
  • 分频参数。
  • 各时间段配置。
  • 采样点。
  • SJW。
  • 振荡器误差。
  • CAN FD 的数据阶段参数。

十二、接收过滤器怎么理解?

验收过滤器决定哪些报文进入控制器的接收缓存。

常见方式包括:

  • 精确匹配。
  • 掩码匹配。
  • 范围匹配。

具体支持方式因控制器而异。

例如:

text 复制代码
只接收 ID 0x200
或者
接收 0x200~0x20F 这一组消息

调试过滤器时,应注意:

  1. 标准帧与扩展帧配置是否正确。
  2. ID 是否需要移位后写入寄存器。
  3. 掩码位的含义是否理解正确。
  4. 数据帧与远程帧是否被区分。
  5. 报文被路由到哪个 FIFO。
  6. FIFO 中断是否已启用。

初次联调时,可先采用较宽松的过滤配置,确认通信正常后,再逐步收紧规则。


十三、CAN 中断与 FreeRTOS 如何配合?

推荐的接收结构是:

text 复制代码
CAN 接收中断
    ↓
读取报文并快速入队
    ↓
退出中断
    ↓
协议解析任务处理数据
    ↓
业务任务执行命令

中断中应尽量避免:

  • 阻塞等待。
  • 长时间打印。
  • 复杂协议解析。
  • 大量计算。
  • 等待其他外设完成操作。

逻辑示例:

c 复制代码
/* 伪代码:具体硬件 API 取决于 MCU 和驱动库 */

void CAN_RxIRQHandler(void)
{
    CanMessage message;
    BaseType_t higherPriorityTaskWoken = pdFALSE;

    if (CAN_ReadMessage(&message))
    {
        if (xQueueSendFromISR(
                canRxQueue,
                &message,
                &higherPriorityTaskWoken) != pdPASS)
        {
            /* 统计接收队列溢出 */
        }
    }

    /* 按硬件要求清除中断标志 */

    portYIELD_FROM_ISR(higherPriorityTaskWoken);
}

任务中处理:

c 复制代码
void CanProtocolTask(void *argument)
{
    CanMessage message;

    for (;;)
    {
        if (xQueueReceive(
                canRxQueue,
                &message,
                portMAX_DELAY) == pdPASS)
        {
            ParseCanMessage(&message);
        }
    }
}

实际项目还需要:

  • 保证中断优先级满足 FreeRTOS 的 API 调用约束。
  • 根据驱动要求处理 FIFO 中剩余报文。
  • 监测硬件 FIFO 和软件队列溢出。
  • 确保队列元素包含完整数据,而不是生命周期不明的临时指针。

十四、应用层还需要约定什么?

CAN 解决报文传输,但不自动定义数据含义。

例如,两字节温度:

text 复制代码
Byte0 = 0x01
Byte1 = 0x2C

接收端必须知道:

  • 采用大端还是小端。
  • 有符号还是无符号。
  • 单位是 ℃ 还是 0.1℃。
  • 是否有偏移。
  • 哪个值表示无效数据。

如果约定大端、单位为 0.1℃:

c 复制代码
uint16_t raw =
    ((uint16_t)data[0] << 8) |
    (uint16_t)data[1];

float temperature = raw * 0.1f;

得到:

text 复制代码
0x012C = 300
温度 = 30.0℃

如果另一个节点采用小端解析,结果就会完全不同。

建议每条消息都定义:

项目 示例
ID 0x300
帧格式 标准数据帧
数据长度 8 字节
发送周期 100 ms
字节序 大端
信号单位 0.1℃
超时时间 500 ms
异常值 按业务约定
序号/校验 根据可靠性需求设计

对于关键控制命令,还应考虑业务应答、超时、重试和重复执行问题。


十五、总线负载为什么不能只算数据字节?

经典 CAN 报文除有效数据外,还包含:

  • 帧头。
  • 仲裁字段。
  • 控制字段。
  • CRC。
  • ACK。
  • EOF。
  • 位填充。
  • 帧间隔。

因此:

text 复制代码
总线占用时间 ≠ 数据字节数 × 8 / 波特率

高负载时,可能出现:

  • 低优先级报文等待时间变长。
  • 发送队列积压。
  • 接收 FIFO 溢出。
  • 业务超时。
  • 错误重传进一步增加负载。

设计时应评估:

text 复制代码
正常周期流量
+ 突发命令流量
+ 诊断或升级流量
+ 错误重传余量

不能只看平均负载,还要关注短时间内的突发流量。


十六、CAN 通信异常的排查顺序

第一步:查供电和模式

  • 收发器供电是否正常?
  • IO 电平是否兼容?
  • 待机或使能脚是否正确?
  • 控制器是否处于正常模式?
  • 是否误启用监听或回环?

第二步:查接线和终端

  • CAN_H 与 CAN_L 是否接反?
  • 线缆是否断开?
  • 两端终端是否正确?
  • 是否存在额外终端?
  • 地参考或隔离方案是否合理?

第三步:查位时序

  • 实际时钟是否正确?
  • 波特率是否一致?
  • 采样点与 SJW 是否合适?
  • CAN FD 的 BRS 和数据阶段参数是否匹配?

第四步:查协议状态

  • 是否获得 ACK?
  • 是否丢失仲裁?
  • TEC、REC 如何变化?
  • 是否有错误帧?
  • 是否进入 Error Passive 或 Bus-Off?

第五步:查软件和业务

  • 过滤器是否误过滤?
  • FIFO 是否溢出?
  • 接收队列是否已满?
  • 任务是否及时处理?
  • ID、字节序、单位是否一致?
  • 是否存在应用层超时或重复执行?

可以记成:

先硬件,后时序;先协议,后业务。


十七、面试常见问题速答

1. CAN 为什么需要收发器?

控制器侧使用逻辑电平,CAN 总线使用差分信号。收发器负责两者之间的电气转换。

2. 为什么两个 120Ω 电阻测起来约为 60Ω?

因为两个终端电阻并联。测量应在断电且没有其他电路影响时进行。

3. ID 越小,优先级一定越高吗?

同格式数据帧竞争时可以这样理解。跨格式或涉及远程帧时,还要结合其他仲裁位比较。

4. 输掉仲裁属于错误吗?

不属于。输掉仲裁的节点停止竞争,获胜节点继续发送。

5. 有 ACK 是否说明命令执行成功?

不能。ACK 是协议层接收确认,执行成功需要应用层响应。

6. REC 达到 256 会进入 Bus-Off 吗?

不会直接触发。Bus-Off 由 TEC 超过 255 触发。

7. CAN 报文 CRC 正确,业务数据就一定可靠吗?

不一定。还可能存在旧数据、丢消息、错误的消息来源、软件处理错误或字段解析不一致。

8. 经典 CAN 能直接发送 20 字节吗?

不能在单个经典 CAN 数据帧中发送,需要上层分包;支持 CAN FD 的网络可以选择合适的 FD 数据长度。


十八、总结

稳定的 CAN 通信需要同时满足三个层面的要求:

text 复制代码
物理层:供电、收发器、接线、终端、波形
协议层:帧格式、仲裁、ACK、错误处理、位时序
应用层:字段定义、缓存、超时、响应、重复处理

其中最值得记住的几个结论是:

  • CAN 控制器处理协议,CAN 收发器处理电气信号。
  • 高速 CAN 主干两端通常各放一个 120Ω 终端电阻。
  • 显性 0 覆盖隐性 1,是逐位仲裁的基础。
  • 输掉仲裁不会破坏获胜报文,也不属于通信错误。
  • ACK 不等于目标设备已经执行命令。
  • Bus-Off 应查明根因,不能只靠反复复位。
  • CAN 数据含义、字节序和业务可靠性需要应用层约定。

最后用一句话概括:

接线正确是基础,位时序匹配是前提,仲裁决定发送先后,应用协议决定设备能否真正协同工作。

参考资料

实际开发时,还应结合目标 MCU 的参考手册、CAN 收发器数据手册及所用 CAN/CAN FD 协议规范核对具体参数。

相关推荐
Tronlong创龙13 小时前
SBC‑TLT153 嵌入式 Linux 应用开发,交叉编译与 GDB 调试实践(上)
嵌入式硬件·嵌入式开发·硬件开发·工业控制·工业开发板
endeavor122 天前
can总线(五)
c语言·stm32·单片机·can
endeavor122 天前
CAN总线
stm32·单片机·can
CodeQingqing4 天前
Zcanpro + candbc 调试 can 设备
can·dbc·zcanpro·汽车can
明如正午4 天前
用 Python 一键把 ASC 文件转成 BLF(基于 python-can)
python·can·blf·asc
圆周率智能 iMLite AI4 天前
嵌入式高尔夫地图如何压到单洞 100KB?离线图源的数据组织与压缩思路
mcu·边缘计算·嵌入式开发·rtos·离线地图·高尔夫·高尔夫地图
Tronlong创龙6 天前
IoTGateway可以让网关开发速度快一倍?
arm开发·嵌入式开发·硬件开发·工业控制·工业开发板
流浪0019 天前
大模型技术全景(十一):智能体通信协议 MCP、A2A 与 ANP
llm·agent·通信协议·mcp·a2a·anp
iCxhust9 天前
CAN信号电平与485信号电平实测
单片机·can·通讯·rs485