4、LIN主节点架构:主节点功能框图、主任务与从任务、调度表概念、主节点硬件选型(MCU+收发器)
好,咱们进入正题。这一章讲的是主节点的骨架——架构。
很多人一上来就写代码,结果发现总线跑不起来。为什么?因为没搞明白主节点到底在干什么。说白了,主节点就是整个LIN网络的“指挥官”。它不发话,从节点只能干等着。
4.1 主节点功能框图
先看一张图,我脑子里已经画好了。主节点内部其实就两大块:MCU 和 LIN收发器。
MCU负责跑协议栈、处理调度表、生成报文头。收发器负责把MCU的UART信号转成总线上的电平信号。中间连着一根线,叫TXD和RXD。
嗯,这里要注意:收发器不是可选项,是必需品。MCU的UART引脚直接怼到总线上?不行,电平不匹配,而且没有总线唤醒、故障保护这些功能。
主节点功能框图(文字描述)
+-------------------+ TXD/RXD +-------------------+
| MCU | <----------------> | LIN收发器 |
| - 调度表引擎 | | - 电平转换 |
| - 主任务/从任务 | | - 总线唤醒 |
| - UART外设 | | - 故障检测 |
+-------------------+ +-------------------+
|
| LIN总线(单线)
v
+-----------+
| 从节点1 |
+-----------+
+-----------+
| 从节点2 |
+-----------+
我在项目中遇到过有人把收发器省了,直接用MCU的IO口模拟。结果呢?通信距离超过1米就丢包,抗干扰能力几乎为零。所以,别省这个钱。
4.2 主任务与从任务
一个主节点内部,其实跑着两个“角色”:主任务 和 从任务。
你想想看,主节点既要发调度表,又要响应自己的从任务。这两个任务怎么共存?
主任务负责:
- 按照调度表,定时发送报文头(同步间隔+同步场+标识符场)
- 监控总线状态,处理错误
- 管理唤醒和休眠
从任务负责:
- 接收主任务发来的报文头
- 根据标识符判断:是自己要发的,还是自己要收的
- 如果是自己发,就填充数据场和校验场
- 如果是自己收,就读取数据
我个人习惯把主任务放在定时器中断里跑,从任务放在主循环里轮询。为什么?因为主任务对时间精度要求高,中断里跑最稳。从任务可以慢一点,没关系。
避坑指南: 我曾经在一个项目里把主任务和从任务都放在中断里,结果中断嵌套导致调度表乱了。后来改成主任务中断+从任务轮询,问题解决。记住:中断里只做最紧急的事。
4.3 调度表概念
调度表,说白了就是一张“时间表”。它告诉主节点:什么时间该发哪个报文头。
举个例子,一个简单的调度表:
// 调度表条目结构
typedef struct {
uint8_t frame_id; // 报文标识符(0x00-0x3F)
uint16_t slot_time; // 时隙长度(单位:位时间)
} schedule_entry_t;
// 调度表定义
const schedule_entry_t schedule_table[] = {
{0x01, 1000}, // 先发ID=0x01的报文,时隙1000位时间
{0x02, 1000}, // 再发ID=0x02
{0x03, 500}, // ID=0x03,时隙500位时间
{0x01, 1000}, // 循环回来,再发ID=0x01
};
调度表可以循环执行,也可以有条件跳转。比如:
- 无条件循环:一直按顺序发,适合周期性数据
- 条件跳转:比如检测到某个事件,跳到另一个调度表
- 单次执行:发完就停,适合诊断或配置
我记得有一次调试,发现某个从节点总是丢数据。查了半天,原来是调度表的时隙设得太短,从节点来不及处理。后来把时隙从500位时间改成800位时间,问题消失。
注意: 调度表的时隙长度,必须大于报文传输时间 + 从节点处理时间。否则总线会乱套。一般建议留20%的余量。
4.4 主节点硬件选型(MCU+收发器)
选型这件事,我踩过不少坑。直接说结论:
MCU选型要点
- UART数量:至少1个,最好带LIN硬件支持(自动生成同步间隔)
- 定时器:至少1个16位定时器,用于调度表计时
- Flash/RAM:调度表不大,8KB Flash + 1KB RAM足够
- 工作电压:3.3V或5V,看收发器匹配
我个人常用的MCU:
| 型号 | 内核 | UART | LIN硬件支持 | 价格(批量) |
|---|---|---|---|---|
| STM32F042 | Cortex-M0 | 2个 | 是 | 约$0.8 |
| NXP S32K116 | Cortex-M0+ | 3个 | 是 | 约$1.2 |
| Microchip PIC18F | 8位 | 1个 | 否(需软件模拟) | 约$0.5 |
收发器选型要点
- 兼容标准:必须符合LIN 2.x或ISO 17987
- 工作电压:通常12V(车载),也有5V版本
- 唤醒功能:支持本地唤醒和总线唤醒
- 保护功能:过温保护、短路保护、地偏移保护
常用的收发器:
| 型号 | 电压 | 速率 | 特点 |
|---|---|---|---|
| TJA1020 | 12V | 20kbps | 经典款,稳定 |
| MCP2003 | 12V | 20kbps | 带休眠模式 |
| SN65HVDA100 | 5V/12V | 20kbps | 宽电压,抗干扰强 |
我的经验: 选收发器时,一定要看它的地偏移范围。车载环境地电位可能差好几伏,如果收发器不支持±5V地偏移,通信就会出错。我曾经用过一个便宜的收发器,地偏移只有±2V,结果在实车上频繁丢帧。后来换成TJA1020,再没出过问题。
嗯,这一章的内容就这些。下一章我们讲主节点的软件架构——调度表引擎的实现。到时候我会贴出完整的代码,手把手教你写一个调度表管理器。