Перейти к содержанию

Шина LIN

LIN — однопроводная шина автомобиля для недорогих узлов: один ведущий опрашивает по расписанию до пятнадцати ведомых на скорости до 20 кбит/с. Ниже — кадр и его поля, физический уровень с подтяжками и порогами, расписание, сон и диагностика по спецификации LIN 2.2A, подключение трансивера MCP2003B и реализация на UART микроконтроллера.

Обновлено Редакция GAW

LIN (Local Interconnect Network) — последовательная шина для мехатронных узлов автомобиля: датчиков, кнопок, исполнительных механизмов. Спецификация называет её дополнением к другим сетям автомобиля там, где не нужны пропускная способность и гибкость CAN: узел LIN — это обычный UART, недорогой трансивер и генератор без кварца, а вся шина — один провод и масса. Один ведущий узел опрашивает ведомых по расписанию, поэтому время доставки каждого сигнала известно заранее.

Все числа в статье — из спецификации LIN 2.2A (декабрь 2010 года), даташитов Microchip на трансивер MCP2003B и микроконтроллер ATtiny167 и справочного руководства RM0008 на STM32F1. Где расчёт наш, это сказано прямо.

Коротко

  • Линии: одна сигнальная линия LIN и масса. В покое линия подтянута к напряжению аккумулятора: у ведущего — 1 кОм с диодом, у ведомых — 30 кОм с диодом.
  • Узлы: один ведущий и ведомые, всего не больше 16; длина шины — до 40 м.
  • Скорость: от 1 до 20 кбит/с. Ведомые обходятся без кварца: до синхронизации их частота может отличаться от номинальной до 14 %.
  • Кадр: заголовок от ведущего (break не короче 13 бит, sync 0x55, PID) и ответ от одного узла: 1–8 байт данных и контрольная сумма.
  • Уровни: доминант (логический 0) — ниже 40 % напряжения питания приёмника, рецессив (логическая 1) — выше 60 %.
  • Стандарты: спецификации LIN 1.3–2.2A консорциума LIN, с 2016 года — международная серия ISO 17987; в США — рекомендации SAE J2602.

Как устроена сеть LIN

Сеть LIN (в спецификации — кластер) состоит из одной ведущей задачи и нескольких ведомых. Ведущая задача работает в ведущем узле, который содержит ещё и ведомую задачу; остальные узлы содержат только ведомую. Ведущая задача решает, какой кадр и когда идёт по шине: она передаёт заголовок с идентификатором. Ведомая задача, которая публикует этот идентификатор, отвечает данными. Отвечать может любой узел, включая сам ведущий, а принимают ответ все узлы, которым он нужен, — подписчики.

Сеть LIN: ведущий, ведомые узлы, одна сигнальная линия и массаВсе узлы подключены к одной линии LIN и к общему проводу — массе автомобиля. Ведущий подтягивает линию к напряжению аккумулятора VBAT через диод и резистор 1 кОм, каждый ведомый — через диод и резистор 30 кОм внутри трансивера. В покое линия в рецессивном состоянии, близком к VBAT; доминантный уровень создаёт транзистор передающего узла, прижимая линию к массе. Длина шины — до 40 м, узлов — не больше 16.ЭБУ ведущегоLINVBATDR1 кОмВедущийМК + трансиверВедомый 130 кОм + диодВедомый 230 кОм + диодВедомый n30 кОм + диод…шина до 40 м, не больше 16 узловпокой и 1 — рецессив, около VBAT; 0 — доминант, около массыведомые питаются от того же VBAT; обратный провод — масса автомобиля
Сеть LIN: все узлы на одной линии и общей массе. Ведущий подтягивает линию к VBAT через диод и 1 кОм, каждый ведомый — через диод и 30 кОм внутри трансивера

Отсюда главные свойства LIN:

  • Нет арбитража. Передатчик ответа назначен заранее, и два узла не начнут передачу одновременно. Исключение — кадры по событию, где конфликт возможен и разрешается отдельным расписанием (о них ниже).
  • Предсказуемое время. Ведущий проходит таблицу расписания по кругу, поэтому период обновления каждого сигнала известен на этапе проектирования.
  • Дешёвые ведомые. Байт синхронизации в каждом заголовке позволяет ведомым работать от встроенного RC-генератора, а кадр передаётся обычным UART с одним стоп-битом.

Узлы описываются файлами: описание сети (LDF, LIN Description File) задаёт скорость, кадры, сигналы и расписания, а файл возможностей узла (NCF) — свойства готового ведомого. По LDF генерируется программа ведущего, поэтому ведомые от разных производителей собираются в одну сеть без переделки.

Версии LIN и стандарты

LIN 1.0 вышел в июле 1999 года, в ноябре 2000 года — LIN 1.2, в ноябре 2002-го — LIN 1.3, в котором поправили физический уровень ради совместимости узлов разных производителей. LIN 2.0 (2003) переработал спецификацию: добавил расширенную контрольную сумму с PID, стандартные диагностику и настройку узлов, файлы возможностей узлов и автоматическое определение скорости. LIN 2.1 вышел в 2006 году, LIN 2.2 собрал исправления, а LIN 2.2A (декабрь 2010) поправил сигнал пробуждения. Её выпустили уже после закрытия консорциума LIN, и она остаётся одной из самых распространённых версий.

С 2016 года LIN — международный стандарт серии ISO 17987 из восьми частей: от протокола и транспортного уровня до физического уровня 12/24 В, тестов на соответствие и LIN по линии питания. В редакции 2025 года ведущий и ведомый называются commander и responder. В США рекомендации по применению LIN выпускает SAE: серия J2602 впервые опубликована в 2004 году, обновлена в 2012-м и основана на LIN 2.0.

Ведущий LIN 2.x работает с ведомыми LIN 1.3 в одной сети: он просто не просит у них расширенную сумму, диагностику, определение скорости и сигнал ошибки. Обратное неверно: ведущий LIN 1.3 не знает расширенной суммы, и ведомые LIN 2.x с ним не работают.

Физический уровень

Физический уровень LIN основан на стандарте ISO 9141 (K-линия диагностики) с доработками для меньших помех. Линия LIN — один провод относительно массы автомобиля. Каждый узел подключён к ней выходом с открытым коллектором: передатчик может только прижать линию к массе или отпустить её. Отпущенную линию к напряжению аккумулятора тянут подтягивающие резисторы с последовательными диодами: 1 кОм у ведущего и 30 кОм внутри трансивера каждого ведомого. Диоды обязательны: при обрыве питания узла ток с шины иначе питал бы его электронику через подтяжку.

Отсюда два состояния линии. Рецессивное — линия отпущена, напряжение близко к питанию, это логическая 1 и состояние покоя. Доминантное — хотя бы один узел прижал линию, напряжение близко к массе, это логический 0. Если один узел передаёт 1, а другой 0, на линии будет 0 — доминант побеждает.

Уровни на шине LIN относительно питания приёмникаНапряжение шины откладывается в долях напряжения питания узла VSUP. Выше 60 % VSUP приёмник видит рецессивный уровень, логическую единицу, ниже 40 % — доминантный, логический ноль. Между порогами — зона, где состояние не определено. Спад формирует трансивер с ограничением скорости фронта, подъём — подтягивающие резисторы и ёмкость шины с постоянной времени от 1 до 5 мкс.VSUP0,6 VSUP0,4 VSUP0tрецессив = 1доминант = 0не определеноспад — трансиверподъём фронта: подтяжки и ёмкость шины, τ = 1–5 мкс
Пороги приёмника считаются от его собственного питания VSUP: выше 60 % — рецессив, ниже 40 % — доминант. Спад формирует трансивер, подъём — подтяжка и ёмкость шины

Пороги отсчитываются не от напряжения аккумулятора, а от питания приёмника VSUP: оно ниже на падение напряжения на диодах и проводах, а масса узлов в автомобиле может «гулять» до 11,5 % напряжения аккумулятора. Основные параметры физического уровня по таблицам 6.6, 6.7 и 6.11 спецификации:

ПараметрЗначение
Напряжение аккумулятора, при котором узел работает (VBAT)8–18 В
Питание трансивера (VSUP)7,0–18 В
Порог доминанта на входе приёмникане выше 0,4 VSUP
Порог рецессива на входе приёмникане ниже 0,6 VSUP
Гистерезис приёмникане больше 0,175 VSUP
Ток ограничения передатчика в доминанте40–200 мА
Подтяжка ведущего, с последовательным диодом900–1100 Ом, номинал 1 кОм
Подтяжка ведомого, с последовательным диодом20–60 кОм, номинал 30 кОм
Длина шиныдо 40 м
Ёмкость шины вместе с узлами1–10 нФ
Постоянная времени шины τ1–5 мкс
Ёмкость узла ведущего / ведомого220 пФ / 220 пФ, не больше 250 пФ
Погонная ёмкость провода100 пФ/м, не больше 150 пФ/м
Число узловне больше 16

Ограничения на длину и число узлов связаны через постоянную времени: τ=CшиныRшины\tau = C_\text{шины} R_\text{шины}, где Cшины=Cвед+n Cузла+Cлинии′LC_\text{шины} = C_\text{вед} + n\,C_\text{узла} + C'_\text{линии} L, а RшиныR_\text{шины} — все подтяжки параллельно. Наш расчёт по типовым значениям для ведущего и 15 ведомых на 40 м: Cшины=220+15⋅220+100⋅40=7520C_\text{шины} = 220 + 15 \cdot 220 + 100 \cdot 40 = 7520 пФ, Rшины=1 кОм∥(30 кОм/15)≈667R_\text{шины} = 1\text{ кОм} \parallel (30\text{ кОм} / 15) \approx 667 Ом, τ≈5,0\tau \approx 5{,}0 мкс — ровно верхняя граница. Поэтому спецификация и советует не больше 16 узлов: каждый следующий снижает сопротивление шины ещё примерно на 3 %.

Скорость фронтов спецификация не задаёт в вольтах на микросекунду: вместо этого она нормирует коэффициенты заполнения D1–D4 — долю рецессива в периоде из двух бит при чередовании 0 и 1, измеренную по заданным порогам приёмника при худших нагрузках шины (1 нФ и 1 кОм, 6,8 нФ и 660 Ом, 10 нФ и 500 Ом). Трансиверы формируют пологие фронты с ограничением скорости нарастания: так меньше помех. Для скоростей 10,4 кбит/с и ниже ради лучшей ЭМС действуют свои нормы — D3 и D4. Ещё два требования: узел не должен повреждаться при замыкании линии на массу или на плюс аккумулятора до 26,5 В, а при потере своей массы или питания — мешать остальной сети.

Скорость и синхронизация

Скорость шины LIN — от 1 до 20 кбит/с; конкретное значение (номинальную скорость) задаёт описание сети. В примере описания из спецификации — 19,2 кбит/с.

Генератор ведущего должен быть точным, а ведомым точность не обязательна: они подстраиваются по байту sync в начале каждого кадра. В байте 0x55 со старт- и стоп-битом уровни чередуются, и спады идут через 2, 4, 6 и 8 битовых интервалов от начала старт-бита. Измерив время между ними, ведомый вычисляет длительность бита ведущего и держит её до конца кадра. Допуски скорости по таблицам 6.1–6.3:

УзелДопуск
Ведущий, относительно номинальной скоростименьше ±0,5 %
Ведомый без синхронизации, относительно номинальнойменьше ±1,5 %
Ведомый с синхронизацией — до неё, относительно номинальнойменьше ±14 %
Ведомый с синхронизацией — после неё, относительно ведущегоменьше ±2 %
Два ведомых между собойменьше 2 %

±14 % — точность, которой встроенный генератор достигает с заводской калибровкой. Её хватает, чтобы узнать break, а дальше синхронизация по байту 0x55 подгоняет скорость до ±2 %.

Каждый байт синхронизируется по спаду своего старт-бита. Спецификация допускает любую схему выборки, если первая выборка бита сделана не раньше 7/16, а последняя — не позже 10/16−tBFS10/16 - t_\text{BFS} битового интервала, где tBFSt_\text{BFS} — точность обнаружения спада старт-бита, не хуже 2/16 бита. Если выборок несколько, бит определяется большинством. Пример из спецификации — UART с 16 тактами на бит: спад старт-бита обнаруживается с точностью 1/16 бита, а выборки делаются с 7/16 до 9/16 бита.

Кадр LIN

Кадр состоит из заголовка, который передаёт ведущий, и ответа от узла-издателя:

  • Break — не меньше 13 битовых интервалов доминанта и разделитель не короче одного бита. Break нарушает формат байта, и ведомый узнаёт начало кадра в любой момент, даже посреди приёма. Порог обнаружения у ведомого — 11 своих битовых интервалов, у ведомого с кварцем или керамическим резонатором — 9,5.
  • Sync — байт 0x55 для подстройки скорости.
  • PID — защищённый идентификатор: 6 бит ID и два бита чётности.
  • Данные — от 1 до 8 байт. Число байтов для каждого ID заранее известно издателю и подписчикам; многобайтные величины передаются младшим байтом вперёд.
  • Контрольная сумма — последний байт ответа.

Каждое поле, кроме break, — байт UART: старт-бит 0, восемь бит данных младшим вперёд, стоп-бит 1. Между байтами могут быть паузы, а между заголовком и ответом — пауза для ответа, обе неотрицательные.

Кадр LIN с ID 0x10: break, sync 0x55, PID 0x50, данные 4A 55 93 E5, контрольная сумма 0x960000000000000Break13 бит1Разд.1 бит0101010101Sync0x550000010101PID0x500010100101Данные 10x4A0101010101Данные 20x550110010011Данные 30x930101001111Данные 40xE50011010011Контр. сумма0x96
Кадр с ID 0x10 и четырьмя байтами данных по битам: break и разделитель, sync 0x55, PID 0x50, данные 4A 55 93 E5 и расширенная контрольная сумма 0x96

Собрать кадр из своих ID и данных или проверить байты с логического анализатора можно прямо здесь. Тот же калькулятор с таблицами и пояснениями — на странице «Кадр LIN по байтам».

Исходные данные

Режим
HEX

6 бит: от 00 до 3F; 3C и 3D — диагностические кадры

4A 55 93 E5, 0x4A,0x55 или 4A5593E5

Контрольная сумма

Результат

Байты после break
55 50 4A 55 93 E5 96
sync, PID, данные, контрольная сумма
Защищённый идентификатор (PID)
0x50P1 = 0, P0 = 1, ID = 010000 — кадр сигналов (обычные данные)
Контрольная сумма, расширенная
0x96по PID и данным
Заголовок
1,771 мс34 бита; с допуском 40 % — до 2,479 мс
Ответ
2,604 мс50 бит; до 3,646 мс
Кадр
4,375 мсслот в расписании — не меньше 6,125 мс

Кадр на шине

Break — не меньше 13 бит в доминантном (низком) уровне, затем разделитель и байтовые поля: старт-бит, 8 бит данных младшим вперёд, стоп-бит.

Кадр LIN: 55 50 4A 55 93 E5 960000000000000Break13 бит1Разд.1 бит0101010101Sync0x550000010101PID0x500010100101Данные 10x4A0101010101Данные 20x550110010011Данные 30x930101001111Данные 40xE50011010011Контр. сумма0x96
БайтСуммаПеренос
0x500x50—
0x4A0x9A—
0x550xEF—
0x930x83был: вычли 0xFF
0xE50x69был: вычли 0xFF
инверсия0x96контрольная сумма

Защищённый идентификатор

Идентификатор — 6 бит, значения от 0 до 63. Чтобы искажённый ID не приняли за другой, к нему добавлены два бита чётности:

P0=ID0⊕ID1⊕ID2⊕ID4,P1=ID1⊕ID3⊕ID4⊕ID5‾.P_0 = ID_0 \oplus ID_1 \oplus ID_2 \oplus ID_4, \qquad P_1 = \overline{ID_1 \oplus ID_3 \oplus ID_4 \oplus ID_5}.

P0P_0 занимает разряд 6, P1P_1 — разряд 7 байта PID. Каждый бит ID входит хотя бы в одно уравнение, поэтому ошибка в любом одном бите PID обнаруживается. Все 64 значения:

ID+0+1+2+3+4+5+6+7
0080C14203C4850647
080849CA8B4C0D8ECF
10501192D31455D697
18D8991A5B9CDD5E1F
202061E2A36425A6E7
28A8E96A2BECAD2E6F
30F0B13273B4F57637
387839BAFB3C7DFEBF

Строка — старшие разряды ID, столбец — прибавка к ним. Идентификаторы делятся на три группы:

IDНазначение
0x00–0x3B (0–59)кадры с сигналами
0x3C (60)запрос ведущего (master request): диагностика и настройка
0x3D (61)ответ ведомого (slave response): диагностика и настройка
0x3E, 0x3F (62, 63)зарезервированы, в сетях LIN 2.x не используются

В LIN 1.x длина ответа кодировалась прямо в идентификаторе. Например, в регистре идентификатора контроллера LIN у ATtiny167 для режима LIN 1.3 разряды ID5 и ID4 задают 2 байта (00 и 01), 4 байта (10) или 8 байт (11). В LIN 2.x длина в ID не передаётся, её задаёт описание сети.

Контрольная сумма

Контрольная сумма — инвертированная восьмибитная сумма с переносом: байты складываются, и каждый раз, когда сумма достигает 256, из неё вычитают 255. Классическая сумма считается только по данным — так считали все кадры в версиях до LIN 1.3 включительно. Расширенная, введённая в LIN 2.0, начинает с PID, поэтому защищает и идентификатор. Какую сумму использовать, ведущий знает для каждого ID: классическую — с ведомыми LIN 1.x, расширенную — с LIN 2.x. Диагностические кадры 0x3C и 0x3D всегда используют классическую сумму.

Пример из спецификации, данные 4A 55 93 E5: 0x4A + 0x55 = 0x9F; + 0x93 = 0x132, после переноса 0x33; + 0xE5 = 0x118, после переноса 0x19; инверсия даёт 0xE6. Приёмник складывает тем же способом все байты вместе с контрольной суммой и должен получить 0xFF. Расширенная сумма для того же кадра с ID 0x10 (PID 0x50) — 0x96.

/* LIN checksum: the enhanced model starts with the PID, the classic one sums the data only. */
uint8_t lin_checksum(uint8_t pid, const uint8_t *data, uint8_t n, int enhanced)
{
    uint16_t sum = enhanced ? pid : 0;
    for (uint8_t i = 0; i < n; i++) {
        sum += data[i];
        if (sum > 0xFF)
            sum -= 0xFF;
    }
    return (uint8_t)~sum;
}

Длина кадра и расписание

Номинальное время кадра — его биты без пауз: break с разделителем — 14 бит, sync и PID — по 10, каждый байт ответа — тоже 10:

Tзаг=34 Tбит,Tотв=10 (N+1) Tбит,Tкадр=Tзаг+Tотв,T_\text{заг} = 34\,T_\text{бит}, \qquad T_\text{отв} = 10\,(N + 1)\,T_\text{бит}, \qquad T_\text{кадр} = T_\text{заг} + T_\text{отв},

где NN — число байт данных. Паузы между байтами разрешены, но всё вместе не должно удлинять заголовок и ответ больше чем на 40 %: Tmax=1,4 TномT_\text{max} = 1{,}4\,T_\text{ном}. Узлы обязаны принимать кадр без пауз, а соблюдение максимума проверяют инструменты и тесты; приёмник принимает ответ до следующего break, даже если тот затянулся.

Байт данныхБит в кадре19 200 бит/с10 400 бит/с9 600 бит/с
1542,81 мсдо 3,94 мс5,19 мсдо 7,27 мс5,63 мсдо 7,88 мс
2643,33 мсдо 4,67 мс6,15 мсдо 8,62 мс6,67 мсдо 9,33 мс
3743,85 мсдо 5,4 мс7,12 мсдо 9,96 мс7,71 мсдо 10,8 мс
4844,38 мсдо 6,13 мс8,08 мсдо 11,3 мс8,75 мсдо 12,3 мс
5944,9 мсдо 6,85 мс9,04 мсдо 12,7 мс9,79 мсдо 13,7 мс
61045,42 мсдо 7,58 мс10 мсдо 14 мс10,8 мсдо 15,2 мс
71145,94 мсдо 8,31 мс11 мсдо 15,3 мс11,9 мсдо 16,6 мс
81246,46 мсдо 9,04 мс11,9 мсдо 16,7 мс12,9 мсдо 18,1 мс

Время ведущий отмеряет базовыми интервалами TbaseT_\text{base} — обычно 5 или 10 мс. Каждый кадр занимает в таблице расписания слот из целого числа таких интервалов, и слот должен вмещать максимальное время кадра вместе с задержкой начала заголовка от такта (джиттером):

Tслот=n Tbase,Tслот>джиттер+Tкадр,max.T_\text{слот} = n\,T_\text{base}, \qquad T_\text{слот} > \text{джиттер} + T_\text{кадр,max}.
Расписание LIN: слоты по 10 мс на 19 200 бит/сВедущий начинает каждый слот расписания на такте базового времени 10 мс: передаёт заголовок с идентификатором, после чего отвечает узел-издатель этого кадра. В первом и четвёртом слотах ответ даёт сам ведущий, во втором и третьем — ведомые 1 и 2. Пунктиром показано максимальное время кадра, в 1,4 раза больше номинального; слот должен быть длиннее его вместе с задержкой начала. После четвёртого слота расписание повторяется.ID 0x10ответ: ведущийID 0x21ответ: ведомый 1ID 0x22ответ: ведомый 2ID 0x10ответ: ведущий0 мс10 мс20 мс30 мс40 мсзаголовок (ведущий)ответ ведомогоT кадра max = 1,4 × номинальное
Расписание из четырёх слотов по 10 мс на 19 200 бит/с: заголовок всегда от ведущего, ответ — от издателя кадра. Пунктир — максимальное время кадра, которое должен вмещать слот

Кадр с 8 байтами на 19 200 бит/с длится до 9,04 мс, поэтому в слот 10 мс он помещается, если джиттер ведущего меньше 0,96 мс (наш расчёт). Сменить расписание ведущий может только в начале слота. Новые значения сигналов ведомый должен успеть записать до приёма идентификатора своего кадра, а принятые получает сразу после проверки контрольной суммы.

Типы кадров

  • Безусловный кадр (ID 0–59) — основной: заголовок передаётся в каждом своём слоте, издатель отвечает всегда.
  • Кадр по событию (event triggered) — общий заголовок для нескольких ведомых, каждый отвечает, только если его сигналы изменились. Первый байт данных такого ответа — PID собственного безусловного кадра узла, чтобы ведущий знал, от кого пришли данные. Если ответили двое, ответы столкнутся. Тогда ведущий сам переключается на расписание разрешения конфликта и опрашивает узлы по отдельности. Пример из спецификации — кнопки замков четырёх дверей: нажимают их редко, и опрашивать каждую в каждом цикле расточительно.
  • Спорадический кадр — несколько кадров ведущего делят один слот: передаётся тот, чьи сигналы изменились, а если не изменилось ничего, слот пустует.
  • Диагностические кадры — запрос ведущего 0x3C и ответ ведомого 0x3D, всегда по 8 байт данных и с классической суммой. Заголовок 0x3D ведущий посылает безусловно, а отвечает на него ведомый, которому есть что ответить на предыдущий запрос.

Сигналы внутри кадров — скаляры от 1 до 16 бит или массивы от 1 до 8 байт, передаются младшим битом вперёд и могут пересекать границы байтов. Неиспользуемые биты кадра передаются единицами. Кроме того, каждый ведомый LIN 2.x публикует в одном из своих кадров однобитный сигнал response_error: он выставляется, если в ответе кадра, который узел передавал или принимал, была ошибка, и сбрасывается после успешной передачи. Так ведущий узнаёт о сбоях, которые видит только ведомый.

Сон и пробуждение

Ведущий усыпляет сеть командой: кадр запроса ведущего 0x3C с первым байтом данных 0x00 и остальными 0xFF. Его классическая контрольная сумма — 0x00 (наш расчёт). Ведомый засыпает и сам, если шина не меняла уровень от 4 до 10 с.

Разбудить сеть может любой узел: он переводит линию в доминант на время от 250 мкс до 5 мс. Остальные узлы должны распознать доминантный импульс длиннее 150 мкс с последующим подъёмом и быть готовы к работе через 100 мс. Если за 150–250 мс после сигнала ведущий так и не начал опрос, узел повторяет сигнал; после трёх неудачных попыток он ждёт не меньше 1,5 с перед четвёртой. Ведущий может будить сеть просто заголовком — break сам по себе работает как сигнал пробуждения, но ответа на первый заголовок ждать не стоит.

Диагностика и настройка узлов

Диагностические кадры несут транспортный уровень: блок из 8 байт начинается с адреса узла NAD и байта PCI, за ними идут номер службы SID и данные. Короткое сообщение помещается в один кадр, длинное передаётся первым кадром и продолжениями — всего до 4095 байт. Незаполненные байты передаются как 0xFF.

NADНазначение
0x00зарезервирован для команды сна
0x01–0x7D (1–125)адреса ведомых
0x7Eфункциональный адрес, только для диагностики
0x7Fшироковещательный адрес
0x80–0xFFсвободное использование

Службы с SID 0xB0–0xB7 настраивают узлы: присвоить NAD (0xB0), прочитать идентификацию узла (Read by Identifier, 0xB2, обязательная), сохранить настройку (0xB6), назначить PID кадрам узла (Assign frame identifier range, 0xB7, обязательная). Положительный ответ приходит с RSID = SID + 0x40. Так одинаковые готовые ведомые от разных производителей получают свои идентификаторы в конкретной сети.

Трансивер LIN: MCP2003B

Трансивер переводит логические уровни UART микроконтроллера в уровни шины и обратно. Пример — Microchip MCP2003B: совместим с LIN 1.3–2.2, SAE J2602 и ISO 17987, работает на скоростях до 20 кбит/с, питается от 5,5 до 30 В и защищён от сброса нагрузки до 60 В. Подтяжка шины к питанию 30 кОм (20–60 кОм) с диодом встроена и включается только в рабочем режиме.

Подключение микроконтроллера к шине LIN через трансивер MCP2003BВыход TX микроконтроллера идёт на вход TXD трансивера, выход RXD трансивера с открытым стоком — на вход RX через подтягивающий резистор 4,7 кОм к питанию микроконтроллера. Вывод ввода-вывода управляет входом CS, который включает передатчик. Питание VBB берётся от аккумулятора через диод защиты от переполюсовки, выход VREN включает стабилизатор узла. На выводе LBUS — конденсатор 220 пФ на массу; у ведущего узла к линии добавлены диод и резистор 1 кОм от VBAT.МКVDDRXTXI/OMCP2003BRXDTXDCSWAKEVBBVRENLBUSVSS4,7 кОмкнопка пробужденияVBATзащита от переполюсовкиEN стабилизатораLIN220 пФтолько у ведущегоVBAT1 кОм
Микроконтроллер на шине LIN через MCP2003B, по типовой схеме из даташита DS20005463C. Подтяжка 1 кОм с диодом нужна только ведущему узлу
  • TXD и RXD. Низкий уровень на TXD — доминант на шине, высокий — рецессив. RXD повторяет состояние шины, поэтому микроконтроллер слышит и свои собственные байты. Выход RXD — с открытым стоком, и подтяжка к питанию логики обязательна: трансивер проверяет, что RXD в единице при рецессивной шине, и без подтяжки не перейдёт в рабочий режим.
  • CS включает передатчик. Внутри — подтяжка к массе, поэтому пока микроконтроллер стартует, передатчик выключен и мусор на шину не уходит. Держать CS в единице постоянно производитель не советует.
  • Защита от зависания. Если TXD или сама шина в доминанте дольше примерно 25 мс, передатчик отключается, чтобы неисправный узел не заблокировал сеть.
  • VBB и VREN. Питание трансивера — от аккумулятора через диод защиты от переполюсовки. Выход VREN включает стабилизатор узла во всех режимах, кроме режима сна, поэтому узел может полностью обесточиваться и просыпаться от активности на шине или по входу WAKE.
  • Шина. На выводе LBUS — конденсатор 220 пФ на массу. Ведущий узел добавляет подтяжку 1 кОм от VBAT через диод.

У предшественников MCP2003 и MCP2004 максимальное сопротивление встроенной подтяжки — 47 кОм вместо 60, а сам производитель советует для новых разработок MCP2003B или ATA663211.

LIN на микроконтроллере

Кадр LIN — это байты UART в формате 8N1, поэтому узел строится на любом UART. Отдельного внимания требуют только break и синхронизация у ведомого.

STM32: режим LIN в USART

USART в STM32F1 переходит в режим LIN битом LINEN регистра USART_CR2. В этом режиме бит SBK посылает break из 13 нулевых бит и единичный бит за ним, а приёмник обнаруживает break длиной 10 или 11 бит (бит LBDL) независимо от приёма данных и выставляет флаг LBD. В HAL это функции HAL_LIN_Init() и HAL_LIN_SendBreak(). Последняя только выставляет SBK и не ждёт конца break, поэтому перед передачей байтов ждём, пока аппаратура сбросит бит:

#include <string.h>
#include "stm32f1xx_hal.h"

/* Protected identifier: P0 = ID0^ID1^ID2^ID4, P1 = !(ID1^ID3^ID4^ID5). */
static uint8_t lin_pid(uint8_t id)
{
    uint8_t b0 = id & 1, b1 = (id >> 1) & 1, b2 = (id >> 2) & 1;
    uint8_t b3 = (id >> 3) & 1, b4 = (id >> 4) & 1, b5 = (id >> 5) & 1;
    uint8_t p0 = b0 ^ b1 ^ b2 ^ b4;
    uint8_t p1 = !(b1 ^ b3 ^ b4 ^ b5);
    return (uint8_t)((id & 0x3F) | (p0 << 6) | (p1 << 7));
}

/* Master publishes a frame: break, sync, PID, data and checksum. */
void lin_master_send(UART_HandleTypeDef *huart, uint8_t id, const uint8_t *data, uint8_t n)
{
    uint8_t buf[11];
    uint8_t pid = lin_pid(id);
    int enhanced = id != 0x3C && id != 0x3D;

    buf[0] = 0x55;
    buf[1] = pid;
    memcpy(&buf[2], data, n);
    buf[2 + n] = lin_checksum(pid, data, n, enhanced);

    HAL_LIN_SendBreak(huart);
    while (READ_BIT(huart->Instance->CR1, USART_CR1_SBK)) {
        /* SBK is cleared by hardware during the stop bit of the break */
    }
    HAL_UART_Transmit(huart, buf, 3 + n, 10);
}

Функция lin_checksum() — из примера выше. USART настраивается вызовом HAL_LIN_Init(&huart1, UART_LINBREAKDETECTLENGTH_11B) на скорость шины, 8 бит без чётности. Чтобы запросить данные у ведомого, ведущий передаёт только break, 0x55 и PID, а затем принимает N + 1 байт ответа. Не забудьте, что через трансивер на RX вернутся и собственные байты заголовка.

AVR: аппаратный LIN в ATtiny167 и программный в остальных

У ATtiny87 и ATtiny167 есть контроллер LIN/UART, который выполняет LIN 2.1 и 1.3 аппаратно: формирует и принимает заголовок, считает контрольную сумму, следит за временем кадра и сообщает об ошибках флагами. Break он принимает длиной от 10,5 до 28 бит, а в роли ведомого подстраивает скорость по байту 0x55: допускает отклонение генератора до ±20 % и выравнивает скорость с точностью ±2 %.

У остальных AVR и у Arduino только обычный UART, который не умеет посылать break. Простой приём (наш расчёт): передать байт 0x00 на скорости F⋅9/13F \cdot 9/13. Старт-бит и восемь нулей — 9 бит доминанта на пониженной скорости — длятся ровно 13 номинальных битовых интервалов, а стоп-бит на той же скорости даёт разделитель около 1,44 бита. На 19 200 бит/с это скорость 13 292 бит/с; после байта UART возвращают на номинальную скорость и передают остальные байты заголовка. Ведомому на AVR без кварца нужно ещё подстроить делитель UART: измерить таймером спады байта 0x55 после break.

LIN и CAN

LINCAN
Линииодна линия и массадифференциальная пара CAN_H и CAN_L
Доступ к шинеодин ведущий, расписаниевсе узлы равноправны, побитовый арбитраж
Скорость1–20 кбит/сдо 1 Мбит/с у классического CAN
Данные в кадре1–8 байтдо 8 байт, у CAN FD — до 64
Защита данныхконтрольная сумма из 8 битCRC из 15 бит, подтверждение приёма
Генератор ведомогоRC без кварца, подстройка по syncкварц или точный генератор
Узлов и длинадо 16, до 40 мдесятки узлов, длина зависит от скорости

LIN не конкурирует с CAN, а дополняет его: спецификация отводит LIN нижний уровень иерархической сети автомобиля — там, где не нужны пропускная способность и гибкость CAN. Узлу LIN хватает UART, трансивера и встроенного генератора, тогда как узлу CAN нужны контроллер CAN и кварц.

Типичные ошибки и отладка

  • Не та контрольная сумма. Узел LIN 2.x ждёт расширенную сумму, а программа считает классическую, или наоборот — для диагностических кадров 0x3C и 0x3D. Калькулятор кадра в режиме проверки покажет, с какой суммой совпал байт.
  • ID вместо PID. В заголовке передают 6-битный ID без битов чётности, и ведомые не узнают свой кадр. Для ID 0x10 на шину должен уйти байт 0x50.
  • Нет подтяжки ведущего. Без 1 кОм у ведущего шину тянут только 30 кОм ведомых: постоянная времени шины уходит далеко за 5 мкс, фронты подъёма затягиваются, и на высоких скоростях приёмники начинают ошибаться.
  • Трансивер не включается. У MCP2003B нет подтяжки на RXD или CS в нуле: передатчик выключен, а микроконтроллер видит только тишину.
  • Короткий break. UART без функции break передаёт 0x00 — это лишь 9 бит доминанта, меньше порога 11 бит у ведомого.
  • Масса. Сигнал LIN отсчитывается от массы каждого узла, поэтому плохая масса сдвигает пороги приёмника. Проверяйте разницу масс узлов под нагрузкой.
  • Логический анализатор. Подключайте его к выводам RXD и TXD трансивера, а не к шине на 12 В, и используйте декодер LIN (например, декодер sigrok в PulseView): он показывает break, PID с проверкой чётности, данные и контрольную сумму.

Частые вопросы

Что такое шина LIN и где её применяют?

LIN (Local Interconnect Network) — последовательная однопроводная шина для мехатронных узлов автомобиля: датчиков, кнопок, исполнительных механизмов. Один ведущий узел опрашивает ведомых по заранее составленному расписанию, скорость — от 1 до 20 кбит/с. Узлы строятся на обычном UART и дешёвом трансивере, а ведомым не нужен кварц: они подстраиваются под ведущего по байту синхронизации в каждом кадре. Спецификация называет LIN дополнением к другим сетям автомобиля для тех мест, где не нужны пропускная способность и гибкость CAN.

Чем LIN отличается от CAN?

LIN — один провод и масса, скорость до 20 кбит/с, один ведущий, который решает, кто и когда передаёт, поэтому арбитраж не нужен. CAN — дифференциальная пара, скорости до 1 Мбит/с у классического CAN, все узлы равноправны и делят шину побитовым арбитражем. LIN дешевле: узел — это UART, трансивер и RC-генератор без кварца. Поэтому LIN дополняет CAN там, где его скорость и гибкость не нужны, а не заменяет его.

Какая скорость у шины LIN?

Спецификация LIN 2.2A разрешает любую скорость от 1 до 20 кбит/с, конкретное значение задаётся в описании сети. В примере описания сети из спецификации — 19,2 кбит/с; для скоростей 10,4 кбит/с и ниже спецификация задаёт драйверу отдельные нормы скважности ради лучшей ЭМС. Кадр из 8 байт на 19 200 бит/с длится 6,46 мс номинально и до 9,04 мс с паузами между байтами.

Зачем у ведущего LIN резистор 1 кОм и диод?

Линия LIN в покое подтянута к напряжению аккумулятора: у каждого ведомого внутри трансивера — 30 кОм с диодом, у ведущего — внешние 1 кОм с диодом. Сильная подтяжка ведущего задаёт постоянную времени шины, то есть скорость подъёма фронта при ёмкости линии до 10 нФ. Диод обязателен: без него при обрыве питания узла ток с шины питал бы его электронику.

Как посчитать контрольную сумму LIN?

Сложите байты с переносом: каждый раз, когда сумма превышает 255, вычитайте 255. В конце инвертируйте результат. Для LIN 2.x (расширенная сумма) первым слагаемым идёт PID, для LIN 1.x и диагностических кадров 0x3C и 0x3D (классическая) — только данные. Данные 4A 55 93 E5 дают классическую сумму 0xE6, а с PID 0x50 — расширенную 0x96. Посчитать любую сумму можно в калькуляторе кадра LIN.

Как подключить микроконтроллер или Arduino к шине LIN?

Через трансивер LIN, например MCP2003B: вывод TX микроконтроллера — на TXD, RXD трансивера — на RX с подтягивающим резистором 4,7 кОм к питанию логики, свободный вывод — на CS, питание VBB — от аккумулятора через диод. Ведущему узлу нужна ещё подтяжка 1 кОм с диодом. Программно кадр формирует обычный UART: break, байт 0x55, PID, данные, контрольная сумма. В STM32 USART умеет посылать break из 13 бит сам, а на UART без такой функции break получают, передав 0x00 на пониженной скорости.

Источники

  1. LIN Consortium. LIN Specification Package, Revision 2.2A, 31 December 2010 — разд. 1.1.2 и 1.1.5 — свойства шины, ведущий и ведомые задачи; 1.1.7 — история версий и совместимость с LIN 1.3; 2.3.1 — структура кадра, break, sync, PID, данные, контрольная сумма; 2.3.2 — длина кадра; 2.3.3 — типы кадров; 2.4 — расписание и базовое время; 2.6 — сон и пробуждение; 2.7 — сигнал response_error; 2.8.3 и табл. 2.3–2.5; 3.2 и 4.2 — транспортный уровень, NAD и команды настройки; 6.3 — скорости и допуски, табл. 6.1–6.3; 6.4 — синхронизация и выборка битов, табл. 6.4; 6.5 — физический уровень, рис. 6.3–6.4, табл. 6.6–6.11
  2. CAN in Automation. LIN standards and specifications — история версий LIN, серия ISO 17987 (с 2016 года, обновление 2025 года с терминами commander и responder), рекомендации SAE J2602
  3. Microchip. MCP2003B LIN Transceiver, DS20005463C, 2016 — разд. 1.0 — назначение и нагрузка шины; 1.3 — режимы работы; 1.4, пример 1-1 — типовая схема узла; 1.5 — выводы: RXD с открытым стоком и контролем уровня, CS, WAKE, TXD, тайм-аут доминанта около 25 мс; 2.3 и 2.4 — пороги шины, RSLAVE 20/30/60 кОм, tSLOPE, коэффициенты заполнения
  4. Microchip. MCP2003/4/3A/4A LIN J2602 Transceiver, DS20002230G, 2016 — предшественник MCP2003B, не рекомендован для новых разработок; RSLAVE 20/30/47 кОм
  5. Microchip. ATtiny87/ATtiny167 Data Sheet, DS40002167A, 2020 — гл. 15 «LIN / UART»: аппаратный LIN 2.1 и 1.3, приём break длиной 10,5–28 бит, подстройка скорости по байту 0x55, флаги ошибок, длина ответа в идентификаторе LIN 1.3 (регистр LINIDR)
  6. STMicroelectronics. RM0008 Reference manual STM32F101xx–STM32F107xx, Rev 21, 2021 — разд. 27.3.8 — режим LIN в USART: бит LINEN, break из 13 нулевых бит по биту SBK, обнаружение break длиной 10 или 11 бит (бит LBDL), флаг LBD
  7. STMicroelectronics. STM32F1 HAL, драйвер stm32f1xx_hal_uart.c — HAL_LIN_Init с параметром длины обнаружения break, HAL_LIN_SendBreak устанавливает бит SBK и не ждёт окончания break
  8. sigrok project. sigrok-test: decoder/test/lin — расшифровки кадров LIN 2 декодером sigrok: ID 0x01 и 0x23, данные и расширенные контрольные суммы