ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
19 апреля
721093
Evgeny_CD, Архитектор (17.12.2016 01:19, просмотров: 30978)
Высоконадежный протокол поверх UART. Частично основано на идеях fk0. Основная засада UART - это если проихойдет инверсия бита в момент старта или стопа, то слетит фреймовая синхронизация. И если посылки идут подряд, мы примем лажу вместо пакета. Пусть мы делаем шину а ля RS-485, скорость до 250 КБит/сек, на микроконтроллерах, которые гарантированно успевают отработать прерывание от каждого байта такого потока за время, скажем, передачи нескольких бит. Пусть нам надо передать 8 байт. Кодируем их, скажем, Хемминг (13,8). Получаем 8 пакетов по 13 бит. Теперь берем по одному первому биту из этих пакетов и получаем "переставленный" пакет из 8 бит. Вторые биты - второй пакет....13 пакетов. 13 байтов. Теперь берем байт, засовываем в UART, а когода оно сгенерит прерывание "пуст", то выставляем на линю высокий уровень длительностью >10 бит (полная посылка с одним стартовым и стоповым), после чего передаем второй байт. Получаем передачу 13 байт с перерывами между ними в 1 байт. Итого эффективно 26 байт, в которых только 8 информационных, чуть меньше 31%. В реальности пусть даже 25%. Если во время приема байта произойдет сбой, то потеряется только этот байт, и идущий "сзади" стоп длиной в байт компенсирует любые глюки нашего байта. Но если из 13 "транспонированных байтов" мы потеряем 1, то сможем декодировать эти 8 байтов без потерь. BER 1/13 (если по битикам подсчитать, максимальный BER там будет хуже - но не суть) - это очень сильный уровень помех для дифференциальной линии. За такое можно заплатить эффективностью канала в 25% Итак, мы получили сильно более устойчивый, чем стандартный RS-485. Да, есть тонкие эффекты - энергия на бит и все такое, скорость мы задрали. Но если эффективной скорости "9600, но чтобы всегда" достаточно, то вполне себе решение. Но нам ведь надо передавать данные и питание по одной паре, правда? :) DC balance в UART сделать довольно легко. Стартовый и стоповый бит дают его, из 256 комбинаций 8 бит выбираем 128, в которых он есть. Да, надо будет потрахаться с 7 битным кодированием, но это не принципиальные детали. Но у нас есть длинные паузы, которые все испортят, верно? Сразу после того, как UART передал байт, мы получаем прерывание. Обрабатывая его, мы программируем таймер и программируем полярность паузы. Т.е. один раз "байтовую паузу" мы передаем нулем, один раз - единицей. Все, и тут DC balance есть. Он будет неидеальным - набортные UARTы могут генерить прерывание с задержкой, мы получим некоторую постоянку - но можно к выходу UART прифигарить простенькую логику, которая будет подменять уровень паузы. Приемник этого хозяйства несложен. После получения байта запускаем "датчик длинной паузы" (можно сделать по разному), а после - нормальный прием байта. Развязка дросселями и кондерами - идея стара, как мир. Получаем самое простое и эффективное решение задачи "питание и данные по одной паре".