nбл, Бит
|
Vэф/V
|
50
|
0,49
|
100
|
0,71
|
150
|
0,76
|
200
|
0,78
|
250
|
0,77
|
300
|
0,75
|
350
|
0,73
|
400
|
0,7
|
450
|
0,67
|
500
|
0,63
|
В итоге получаем
Рисунок 2.9 - Определение оптимальной длины блока.
По графику (рис 2.9) получаем nбл_опт= 210 бит. Выбираем ближайшую длину информационной части блока из
ряда [!!!] : k= 240 бит, тогда nбл=240+12+8+3+2=265 бит
Число блоков: Nбл=209.
Таким образом, предполагаемый формат блока будет иметь вид
Рисунок
2.10 - Структура блока
По
заданию информация представлена в виде слов МТК-2, то есть каждое слово по 5
бит. В блоке будет передаваться по 48 слов МТК-2.
2.2.3 Формат
ответного сообщения
При наличии обратного канала связи в большинстве случаев целесообразно
использовать УЗО с ОС. Устройства с информационной ОС позволяют обнаруживать
ошибки практически любой кратности, но к каналу обратной связи предъявляются
такие же требования, как и к прямому. Поэтому У3O с ИОС наиболее эффективно
могут быть использованы при скорости передачи 300/200 бит/с, так как УПС для
такой скорости образуют в полосе канала ТЧ два идентичных двунаправленных
дискретных канала.
Если передача должна осуществляться на скорости 600 бит/сек или выше, то
эффективность использования канала связи УЗО с ИОС снижается, и в этом случае
для повышения верности передачи применяют УЗО с РОС.
Так как заданная скорость передачи превышает 600 бит/с, то необходимо
использовать РОС с применением помехоустойчивого кодирования.
Выбранный способ кодирования обеспечивает помехозащищенное кодирование с
учетом заданной вероятности искажений.
Для начала определим все возможные виды ответного сообщения:
передача данных окончена;
запрос следующего блока информации, сигнал «Подтверждение»;
повторный запрос блока, сигнал «Запрос».
Таким образом потребуется 2 бита для описания вида сообщения:
- передача данных окончена;
- запрос следующего блока;
- повторный запрос блока;
Для ответного сообщения целесообразно применить асинхронный старт-стопный
метод, так как:
сообщения небольшой длительности;
паузы между сообщениями больше, чем длина сообщения
Формат сообщения для передачи по обратному каналу с РОС будет иметь вид,
представленный на рисунке
Рисунок
2.11 - Формат ответного сообщения.
Старт-1,5
бита, 0,5 бит - контрольная пауза, 1стоповый бит, информация - 2 бита
Для
исправления ошибок используем дублирование информации. Такой метод прост в
технической реализации и может обеспечить нужную вероятность ошибочного приема.
Применим пятикратное дублирование. Таким образом, длина блока будет
равна:1,5+0,5+10+1=13 бит.
Вероятность
трансформации в данном случае
(2.6)
где
p - вероятность ошибки.
При
3-х кратном дублировании: , что не удовлетворяет требованиям третьей категории
помехоустойчивости. Пятикратное дублирование информации обеспечивает требуемую
вероятность ошибочного приема информации.
2.3 Расчет
среднего времени запаздывания информации
Время передачи для одного источника рассчитывается по (2.7)
(с) (2.7)
Время
цикла передачи от N источников информации определяется по формуле (2.8)
(с) (2.8)
Среднее
время ожидания сообщением обслуживания на выходе источника информации
определяется по формуле (2.9)
(с) (2.9)
Время передачи для одного источника по обратному каналу
(с)
Время
цикла передачи от N источников информации определяется по формуле (2.10)
. (2.10)
Время
передачи для одного источника по прямому и обратному каналу:
=+ =59,3(с)
Время
цикла передачи от N источников информации по прямому и обратному каналу
определяется по формуле (2.10):
(с)
Среднее
время ожидания сообщением обслуживания на выходе источника информации
определяется по формуле (2.9):
(с)
Среднее
время запаздывания информации определяется по
формуле:
(с)
Выводы к
главе 2
Таким образом, были получены следующие данные, необходимые для
дальнейшего проектирования:
ü Вычислена оптимальная скорость модуляции, на основе которой
определена стандартная скорость 1200 Бод;
ü Определен вид модуляции - ЧМ;
ü Вычислена оптимальная длина маркера, разработана его
структура (рис. 2.8);
ü Определена оптимальная длина блока, на основании которой
выбрана длина информационной части из стандартного ряда ( рис.2.9);
ü Разработан формат прямого и обратного сообщения (рис 2.10 и
2.11)
ü Рассчитаны основные временные параметры системы.
3. Разработка
структурных схем и алгоритмов функционирования СПД
3.1
Разработка структурной схемы передающего устройства
Система передачи данных состоит из передающей и приемной частей.
Структурная схема передающей части СПД представляет собой совокупность основных
блоков, реализующих заданные функции, и связей между ними. Связи указываются
только между теми блоками, которые непосредственно взаимодействуют в процессе
работы СПД.
Основными блоками являются:
o устройство управления (УУ);
o счетчик повторных запросов (СПЗ);
o блок формирования информации (БФИ);
o кодирующее устройство (КУ);
o блок начальной установки (БНУ);
o формирователь тактовых импульсов (ФТИ);
o датчик номера блока (ДНБ);
o датчик маркерной комбинации (ДМК);
o анализатор обратного канала связи (АОКС);
o блок аварийной сигнализации и индикации (БАСИ);
o ключевая схема (Кл);
o формирователи сигналов обмена (ФСО1 и ФСО2);
o буферный накопитель (БН);
o датчик адреса источника (ДА);
o блок преобразования передаваемой информации (БППИ);
Основным блоком УЗО является устройство управления (УУ), которое
управляет работой всех остальных блоков. Управляющие воздействия на выходе УУ
вырабатываются на основе анализа входящих сигналов и зависят от временной
позиции в пределах информационного блока. Переключение УУ происходит под
действием тактовых импульсов, формируемых ФТИ. Для установления устройств в
начальное состояние применяется блок начальной установки. Данные, поступающие с
источников, отправляются в БППИ, где происходит их преобразование к виду,
подходящему для обработки в КУ. Обработанные данные поступают в буферный
накопитель, затем объединяются с адресом источника, поступающим с ДА, маркерной
комбинацией, формируемой ДМК, и номером блока, поступающим с ДНБ. Эти данные
составляют информационную последовательность от источника, и ее формирование
происходит в БФИ.
Затем информационная последовательность поступает на кодирующее
устройство КУ, в котором к информационной последовательности добавляются
проверочные биты. Отметим, что биты, отведенные под маркер, не кодируются, так
как при расчетах длины маркера оговорено, что он может искажаться (до 4-х
ошибок). После добавления проверочных бит в конец блока информация передается в
УПС. В конце каждого блока УУ опрашивает состояние АОКС и в случае наличия
сигнала «Подтверждение» осуществляет дальнейшую передачу последующих блоков
либо при наличии сигнала «Запрос» прекращает ввод информации и выдает повторно
из БН блок, в котором обнаружена ошибка.
Для индикации аварийных ситуаций в схему включен блок аварийной
сигнализации и индикации (БАСИ). Также этот блок служит для индикации состояния
СПД. Блок аварийной ситуации должен индицировать следующие возможные состояния:
включение питания АПД; передача или прием; нет ответа с приемной стороны;
ошибка передачи.
Для анализа поступающей информации по обратному каналу служит анализатор
обратного канала связи (АОКС). Из обратного канала связи на АОКС поступает
закодированное сообщение. Декодирование поступившей информации осуществляется
мажоритарным способом. Если поступил сигнал «Запрос», то АОКС увеличивает
значение счетчика числа повторных запросов на единицу. Если сигнал «Запрос»
посылается более, чем заданное число раз(назовем его Nз), то УУ выдает на БАСИ код ошибки.
Для реализации передачи от нескольких источников, УУ должно циклически
опрашивать источники информации (ИИ) о готовности их передавать информацию.
Последовательно проверяются адреса источников, до момента нахождения источника,
готового к передаче информации. По адресу происходит коммутация канала с нужным
источником, с которого данные поступают для обработки.
Для работы схемы необходим блок временного хранения данных, в который
будет помещаться информация, полученная от одного из источников информации.
Данные будут храниться там до передачи их приемнику. Для временного хранения
данных служит буферный накопитель (БН). Для связи УУ с УПС и источниками
информации предусмотрены ФСО1 и ФСО2.
Ключевая схема представляет собой мультиплексор со стробированием, где:
· адресные входы - код номера источника (поступает со счетчика адреса);
· информационные сигналы - информация с источников;
· сигнал стробирования - связь с УУ.
Структурная схема передающей части СПД выглядит следующим образом
Рисунок3.1 - Функциональная схема передающей части СПД.
3.2 Алгоритм
функционирования приемного устройства
Включение питания индицируется блоком аварийной сигнализации и индикации.
Далее сигналы с блока начальной установки передаются на управляющее устройство,
осуществляется сброс буферного накопителя, блока формирования информации,
регистров кодирующего устройства, счетчика адреса и номера блока. Далее УУ
начинает увеличивать счетчик адреса и одновременно запрашивать сигнал о
готовности выбранного источника. При обнаружении готового источника
инициализируется режим передачи и приема, данные с выбранного источника
помещаются в буферный накопитель, формируется сообщение для передачи. Сообщение
поступает на кодирующее устройство, в котором к нему добавляются проверочные
биты. По сигналу УУ кодирующее устройство отправляет информацию в УПС.
Производится передача сообщения.
Далее проверяется обратный канал, Происходит прием ответного сигнала. При
поступлении сообщения происходит его декодирование и проверяется верность
доставки данных. Если сообщение от источника доставлено с ошибками, подается
сигнал на устройство управления и СПЗ, происходит повторная передача блока
информации. При отсутствии ошибок передается следующий блок информации. Если
ответное сообщение не приходит в течение заданного интервала времени, УУ подает
код аварии в БАСИ. Если данные больше передавать не требуется, системе можно
отключить питание. Алгоритм передающей части СПД:
Рисунок 3.2 - Блок-схема алгоритма передающей части
3.3
Разработка структурной схемы приемного устройства
Структурная схема приемной части СПД содержит следующие блоки:
- устройство управления (УУ);
- блок начальной установки (БНУ);
- формирователь тактовых импульсов (ФТИ);
- блок аварийной сигнализации и индикации (БАСИ);
- регистр маркерной комбинации (РгМК);
- регистр служебной комбинации (РгСК);
- входной регистр (ВхРг);
- дешифратор маркерной комбинации (ДшМК)
- декодирующее устройство (ДКУ);
- буферный накопитель (БН);
- формирователь сообщения обратной связи(ФСОС);
- блок анализа служебной комбинации (БАСК);
- блок преобразования и выдачи информации (БПВИ);
- формирователи сигналов обмена (ФСО1 и ФСО2);
Работой приемной части управляет устройство управления. Так же, как и в
передающей части, необходимо ввести в схему блоки БАСИ, ФТИ, БНУ. Для выявления
маркера необходимы дешифратор и регистр маркерной комбинации. Информация,
пришедшая с УПС, поступает в регистр маркерной и служебной комбинации, а также
во входной регистр. По сигналу УУ, БАСК анализирует номер блока и адрес
источника, после чего выдает ответ в УУ. Декодирующее устройство вычисляет
синдром ошибок и информирует УУ о наличии или отсутствии ошибок. При безошибочной
передаче УУ подает сигнал на БН, и данные поступают в БПВИ. В БПВИ происходит
преобразование информации к виду, пригодному для ООД.
Так как канал передачи полудуплексный, приемное устройство должно
отправить приемному устройству отчет о приеме блока информации. Для этого
приемник формирует квитанцию и отправляет ее по обратному каналу. Для
формирования квитанции в схему добавлен ФСОС.
Помимо анализа верности передачи служебной информации, БАСК подсчитывает
общее число верно переданных блоков и по окончании передачи данных от источника
формирует УУ и по обратному каналу отправляется сообщение «передача окончена».
Существует возможность синхронизации ГТИ с УПС. С помощью ФСО1
реализуется связь между УПС и УУ, а с помощью ФСО2 - между УУ и ООД.
Таким образом, структурная схема приемной части будет иметь следующий
вид:
Рисунок 3.3 - Структурная схема приемной части
3.4 Алгоритм
функционирования приемного устройства
Работа передающей части УЗО начинается с включения питания. Включение
питания индицируется блоком аварийной сигнализации и индикации. Далее сигналы с
блока начальной установки передаются на управляющее устройство, осуществляется
сброс в ноль буферного накопителя и входных регистров, кодирующего устройства,
БАСК.
После включения питания передающая и приемная части должны
синхронизировать свою работу. При маркерном способе передачи поиск маркерной
комбинации производится путем постоянного анализа поступающей
последовательности. Если во время приема одного кадра следующая маркерная
комбинация не приходит через заданное время, то УУ принимает решение о
неисправности и выдает код ошибки в БАСИ.
При выявлении МК, БАСК формирует УУ об отсутствии или наличии ошибок в
служебной информации. Если ошибки не обнаружены, приемное устройство принимает
данные и декодирует их. При успешном декодировании данные поступают далее через
БПВИ к приемнику информации. Если имеются ошибки в служебной комбинации или
декодирование неуспешно, по обратному каналу посылается квитанция об ошибке
(сигнал «Запрос»). При безошибочном приеме отправляется сигнал «Подтверждение».
После окончания передачи кадра, приемное устройство отправляет по
обратному каналу сигнал «передача окончена» и начинает поиск маркерной
комбинации следующего кадра информации.
Таким образом, алгоритм работы приемной части будет следующим:
Рисунок 3.4 - Блок-схема алгоритма приемной части
3.5 Синтез
схем кодирующего и декодирующего устройств
Кодирующее устройство циклических кодов строится в соответствии с
выбранным полиномом.
Для реализации кодирующего устройства циклического кода необходимо
выполнить следующие операции:
). умножить кодируемую последовательность на хr, где r
равно наивысшей степени образующего полинома;
). полученное произведение поделить на образующий полином;
). полученный остаток от деления суммировать с кодируемой
последовательностью, умноженной на хr.
Проверочными битами являются биты остатка от деления кодируемой
последовательности на образующий полином. Суммирование кодируемой
последовательности, умноженной на хr, с остатком от деления приводит к тому, что закодированная
последовательность нацело делится на образующий полином. Это свойство
используется при построении декодирующих устройств.
По заданию, образующий полином Р(х) выбран двенадцатой степени.
Следовательно, при кодировании информационной последовательности необходимо
сначала умножить ее на 1012, а затем поделить на образующий полином; полученный
остаток сложить с информационной последовательностью и получить закодированную
последовательность.
Вид выбранного образующего полинома:
P(x) = x12 +x11+x3+x2 +x+1.
Таким образом, структурная схема декодера
Рисунок 3.5 - Структурная схема кодера
В этой схеме имеются два ключа К1 и К2. В исходном состоянии ключ К1
находится в положении «1», ключ К2 замкнут. При этом к информационных бит
старшим разрядом вперед поступают на выход схемы и через сумматор на схему
деления на образующий полином Р(х). После передачи к-символов схема управления,
представленная УУ, переключает ключ К1 в положение «2», а ключ К2 размыкает. На
этом деление заканчивается и за r-тактов
осуществляется выдача остатка от деления .
В курсовом проекте необходим лишь контроль циклическим кодом, то есть контроль
ошибок. Для обнаружения ошибки достаточно разделить принятую последовательность
на образующий полином и проанализировать остаток. При нулевом остатке ошибок
при передаче не обнаружено, в противном случае в принятой последовательности
содержатся ошибки и требуется повторная передача блока. Аналогично кодеру, n-бит старшим разрядом вперед
поступают на вход схемы деления на образующий полином Р(х), при этом ключ К1 в
положении «1». После передачи n-символов
схема управления переключает ключ К1 в положение «2» и остаток за r тактов поступает на УУ. Структурная
схема декодера будет иметь вид.
Рисунок 3.6 - Структурная схема декодера
Выводы к
главе 3
В процессе проектирования были разработаны структурные схемы приемного и
передающего устройства, а также кодирующего и декодирующего устройства согласно
заданному полиному, описаны алгоритмы работы передающей и приемных частей СПД.
На основании полученных данных можно приступить к программной реализации кодера
и декодера.
4. Разработка
кодирующего и декодирующего устройства
4.1 Описание
программы
Общие сведения
В соответствии с заданием на курсовой проект был разработан программный
продукт «Передача и прием информации с использованием CRC - кода», наглядно демонстрирующий работу кодера и
декодера циклического кода. Приложение было разработано в среде
программирования C++ Builder 5.0. Компиляция выполнена без
использования динамических библиотек и runtime пакетов с целью обеспечения переносимости программы
на компьютер, где не установлена среда C++ Builder
5.0. Для функционирования приложения на компьютере должна быть установлена
операционная система семейства Microsoft Windows.
Аппаратные требования приложения невелики, благодаря чему оно может быть
использовано и на «слабых» компьютерах.
Функциональное значение
Приложение наглядно демонстрирует формирование информационной и
проверочной последовательности кодером, внесение каналом передачи данных
вектора ошибок, выявление декодером наличия ошибок в принятой последовательности.
Программа предназначена лишь для демонстрации работы кодера и декодера
циклического кода, поэтому с помощью неё возможно преобразование информационной
последовательности ограниченной длины. Степень образующего полинома также
ограничена.
Входные данные
Программный продукт позволяет вводить данные с клавиатуры или загружать
из файла. Исходными данными являются:
· информационная последовательность,
· образующий полином P(x),
· вектор ошибок
Ввод названных данных производится в двоичном виде (нули и единицы), что
позволяет наглядно анализировать работу системы.
Выходные данные
Выходными данными программы является таблицы, показывающие содержимое
регистров кодера и декодера циклического кода, а также результат декодирования
(наличие или отсутствие ошибок в принятой последовательности). Программный
продукт позволяет сохранять в файл в бинарном виде информационную
последовательность, образующий полином, вектор ошибок, содержимое регистров
кодера и декодера. Сохранённые программой данные можно загружать в качестве
входных данных. Сохранение информации в бинарном виде позволяет проверить
правильность её работы с помощью сторонних шестнадцатеричных редакторов.
Математическая постановка задачи
Циклические коды находят наибольшее распространение в
системах передачи данных с решающей обратной связью, что обусловлено их
высокими корректирующими свойствами, сравнительно простой реализацией,
невысокой избыточностью. Особенно они эффективны при обнаружении пакетов
ошибок. Циклические коды относятся к блочным систематическим кодам, в которых
каждая комбинация кодируется самостоятельно в виде блока таким образом, что
информационные k и проверочные г
элементы всегда находятся на определенных местах. Для упрощения процедуры
кодирования и декодирования проверочные биты размещают в конце блока.
Кодирование передаваемого сообщения осуществляется умножением двоичной
последовательности G(x) на одночлен хr, имеющий ту же степень, что и
образующий полином Р(х), с добавлением к этому произведению остатка R(x), полученного после деления произведения G(x)*xr на образующий
полином, т. е. передаваемое в канал связи сообщение F(x) имеет вид:
F(x) = G(x)* xr+R(x). (4.1)
При декодировании принимаемая последовательность F(x) снова делится
на образующий полином Р(х). Полученный нулевой остаток R(x)=0
свидетельствует об отсутствии ошибок в принятом блоке, а отличие от нуля - о
наличии ошибок.
Описание логической структуры
Для моделирования работы кодера и декодера циклического кода в составы
программы был включен класс Coder.
В состав класса входят следующие переменные:
Таблица 4.1 - Переменные класса Coder
Имя переменной
|
Тип
|
Комментарии
|
Step_P
|
integer
|
Степень образующего
полинома
|
V
|
|
Объем передаваемой
информации
|
i
|
|
Счетчики в циклах
|
j
|
|
|
Inf
|
bool *
|
Указатель на массив
информации
|
Pol
|
|
Указатель на массив
представления полинома
|
Reg_Cod
|
|
Указатель на массив
представления кодера
|
Reg_Dec
|
|
Указатель на массив
представления декодера
|
Err
|
|
Указатель на вектор ошибок
|
Для представления информации в программе используется тип bool. Это приводит к увеличению объема
занимаемой памяти, но в данном случае оно несущественно, так как передается
лишь 240 бит. Каждый элемент массива Reg_Cod и Reg_Dec
соответствует одной ячейке регистра.
Прототипы функций класса Coder:
· void Init();
· bool* getInf();
· bool* getPol();
· bool* getReg();
· void setInf(bool* );
· void setPol(bool* );
· void setReg(bool* );
· void setSt(int);
· int getSt();
· int getV();
· bool* getDec();
· bool* getErr();
· void setDec(bool* );
· void setErr(bool* );
· void coder::Cod();
· void coder::Decod().
Функция Init() - конструктор класса.
Большинство функций класса предназначены для «извлечения» или изменения
значения закрытых переменных класса. Наибольший практический интерес
представляют функции кодирования (void Cod() ) и декодирования (void Decod() )
информации.
Рисунок 4.1 - Блок-схема алгоритма функции Cod()
Рисунок 4.2 - Блок-схема алгоритма функции Decod()
Моделирование работы системы происходит в несколько этапов:
1. инициализация образующего полинома;
2. формирование информационной последовательности;
. кодирование;
. наложение вектора ошибок;
. декодирование.
Все перечисленные этапы отражены в интерфейсе программы.
Рисунок 4.3 - Интерфейс программы.
4.2
Тестирование программной реализации
Пусть объем исходной информации равен 1 байту: I=10111011
Полином
четвертой степени:
Для
кодирования требуется умножить исходную информацию на xr и разделить
на образующий полином. Полученный остаток от деления сложить по модулю два с
исходной последовательностью, умноженной на xr. Для анализа
работы кодера и декодера нужно знать не частное, а лишь остаток от деления.
Тест
первый - нулевой вектор ошибок
1
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
0
|
0
|
0
|
0
|
1
|
1
|
0
|
0
|
1
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
1
|
0
|
0
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
0
|
1
|
1
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
1
|
0
|
0
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
0
|
1
|
0
|
0
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
0
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
1
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0
|
0
|
1
|
1
|
|
|
|
|
|
Рисунок 4.4 - Кодирование исходной последовательности
Остаток от деления в двоичном виде: 0011.
1
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
0
|
0
|
1
|
1
|
Для декодирования разделим информацию на образующий полином
1
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
0
|
0
|
1
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
1
|
0
|
0
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
0
|
1
|
1
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
1
|
0
|
0
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
0
|
1
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
1
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
1
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0
|
0
|
0
|
0
|
|
|
|
|
|
Рисунок 4.5 Декодирование информационной последовательности (нулевой
вектор ошибок)
Нулевой вес остатка свидетельствует об отсутствии ошибок в принятой
последовательности.
Тест второй (одиночная ошибка).
Исказим третий бит закодированной последовательности:
1
|
0
|
0
|
1
|
1
|
0
|
1
|
1
|
0
|
0
|
1
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
0
|
1
|
0
|
0
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
1
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
0
|
1
|
0
|
0
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
1
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0
|
1
|
0
|
1
|
|
|
|
|
|
Рисунок 4.6 - Декодирование информационной последовательности (одна
ошибка)
Так как вес остатка не равен нулю, то информация передана с ошибками.
Тест третий (двойная ошибка).
Исказим 4-й и 5-й бит передаваемой последовательности
1
|
0
|
1
|
0
|
0
|
0
|
1
|
1
|
0
|
0
|
1
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
1
|
0
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
1
|
1
|
0
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
1
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
1
|
0
|
0
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
|
0
|
0
|
1
|
|
|
|
|
|
Рисунок 4.7 - Декодирование информационной последовательности (две ошибки)
Остаток от деления свидетельствует о наличии ошибок в принятой
последовательности.
Введем предложенные данные для тестирования программной реализации
Рисунок 4.8 - Тестирование программной реализации (первый тест)
Рисунок 4.9 - Тестирование программной реализации (второй тест)
Рисунок 4.10 - Тестирование программной реализации (третий тест)
Результаты тестирования полностью совпали с теорией, что свидетельствует
о верной работе программной реализации.
Выводы к
главе 4
В процессе проектирования была разработана программная реализация кодера
и декодера циклического кода, описан интерфейс программы, а также приведены
блок - схемы функций кодирования и декодирования информации.
Листинг программы приведен в приложении C.
Заключение
В результате проектирования получена система передачи данных, а именно
приемная и передающая части устройства защиты от ошибок, реализующие прием и
передачу сообщения при синхронном маркерном способе фазирования. Разработаны
форматы сообщений, а также устройства кодирования и декодирования информации
при передаче информационных сообщений и квитанций по прямому и обратному
каналу. Используется полудуплексный канал связи и решающая обратная связь.
Приложение А
Список используемых сокращений
СПД - система передачи данных.
УФЦ - устройство фазирования по циклу.
ТИ - система телеизмерения.
ТС - система телесигнализации.
ТУ - система телеуправления.
ТУ-ТС - система телеуправления и телесигнализации.
ТИ-ТС - система телеизмерения и телесигнализации.
ОС - обратная связь.
ИОС - информационная обратная связь.
РОС - решающая обратная связь.
КОС - комбинированная обратная связь.
ГВП - групповое время прохождения.
УУ - устройство управления.
СПЗ счетчик повторных запросов.
БФИ - блок формирования информации.
КУ - кодирующее устройство.
БНУ - блок начальной установки.
ФТИ - формирователь тактовых импульсов.
ДНБ - датчик номера блока.
ДМК - датчик маркерной комбинации.
АОКС - анализатор обратного канала связи.
БАСИ - блок аварийной сигнализации и индикации.
Кл - ключевая схема.
ФСО - формирователь сигналов обмена.
ФК - фазовый корректор.
БН - буферный накопитель.
ДА - датчик адреса источника.
БППИ - блок преобразования передаваемой информации.
РгМК - регистр маркерной комбинации.
РгСК - регистр служебной комбинации.
ВхРг - входной регистр.
ДшМК - дешифратор маркерной комбинации.
ДКУ - декодирующее устройство.
ФСОС - формирователь сообщения обратной связи.
БАСК - блок анализа служебной комбинации.
БПВИ - блок преобразования и выдачи информации.
Приложение Б
Листинг программы
Coder.h
#ifndef coderH
#define coderH
//-----------------coder
{protected::Step_P; //степень полинома
bool *Inf; //указатель на массив информационных
элеметов*Pol; //указатель на массив представления полинома
bool *Reg_Cod;*Err;
bool *Reg_Dec; //регистры кодераV; //объем
информации
public:i,j; //счетчикиInit();* getInf();* getPol();*
getReg();setInf(bool* );setPol(bool* );setReg(bool*
);setSt(int);getSt();getV();* getDec();* getErr();setDec(bool* );setErr(bool*
);coder::Cod();coder::Decod();};.cppPACKAGE coder *My;
//---------------------------------------------------------------------------
#endif
#include <vcl.h>
#pragma hdrstop
#include "coder.h"package(smart_init)coder::Init()
{ Inf=0; Pol=0; Reg_Cod=0; Step_P=0; Reg_Dec=0; Err=0; V=12;
}* coder::getInf() { return Inf; }* coder::getPol() {
return Pol; }* coder::getReg() { return Reg_Cod; }coder::setInf(bool*
A) { Inf=A; }coder::setPol(bool* A) { Pol=A;}coder::setReg(bool* A)
{ Reg_Cod=A; }coder::setSt(int B) { Step_P=B; }coder::getSt() {
return Step_P; }coder::getV() { return V; }* coder::getDec() {
return Reg_Dec; }* coder::getErr() { return
Err;}coder::setDec(bool* A) { Reg_Dec=A;}coder::setErr(bool* A) { Err=A;
}coder::Cod()
{if(Inf!=0&&Pol!=0)
{ if (Reg_Cod==0) Reg_Cod=new
bool[Step_P];(i=0;i<Step_P;i++)
{ Reg_Cod[i]=0; } //Начальное заполнение регистра
for(i=0;i<V-Step_P;i++)
{ bool Scan=Inf[i]^Reg_Cod[0];(Scan==0)
{for(j=0;j<Step_P;j++) { Reg_Cod[j]=Reg_Cod[j+1];
}_Cod[Step_P-1]=0; }(Scan==1)
{ for(j=0;j<Step_P;j++) {
Reg_Cod[j]=Reg_Cod[j+1]^Pol[j+1]; }_Cod[Step_P-1]=1; } }(i=0;i<Step_P;i++)
{ Inf[V-Step_P+i]=Reg_Cod[i]; } } }
//-------------------------------------------------------------------------------coder::Decod()
{ if(Inf!=0&&Pol!=0&&Err!=0)
{ Reg_Dec=new bool[Step_P];(i=0;i<Step_P;i++) {
Reg_Dec[i]=0; }(i=0;i<V;i++) { bool
Scan=Reg_Dec[0];(Scan==0)
{for(j=0;j<Step_P-1;j++) { Reg_Dec[j]=Reg_Dec[j+1];
}_Dec[Step_P-1]=Inf[i]^Err[i]; }(Scan==1)
{ for(j=0;j<Step_P-1;j++) {
Reg_Dec[j]=Reg_Dec[j+1]^Pol[j+1]; }_Dec[Step_P-1]=(Inf[i]^Err[i])^1; } } }
}.cpp
#pragma hdrstop
#include <stdio.h>
#include "Unit3.h"
#include "Unit2.h"
#include "coder.h"
#include <math.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"*Form1; coder * My;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{ My=new coder; My->Init(); }
//---------------------------------------------------------------------------__fastcall
TForm1::Button1Click(TObject *Sender)
{Randomize(); My->setSt(StrToInt(Edit1->Text));
int Step_P=My->getSt(); //считывание степени полинома
StringGrid2->ColCount=Step_P+1;(My->getPol()!=0) delete
[Step_P+1] My->getPol(); //если массив не инициализирован* Pol=new bool[Step_P+1];
Pol[0]=1; Pol[Step_P]=1;(i=1;i<Step_P;i++) { Pol[i]=random(2); } //инициализация полинома(i=0;i<Step_P+1;i++)
{
StringGrid2->Cells[i][1]=IntToStr(Pol[i]);->Cells[i][0]=IntToStr(Step_P-i);
} //вывод на экран->Visible=true;
Label2->Visible=true; My->setPol(Pol); }
//---------------------------------------------------------------------------__fastcall
TForm1::Inversia_pol(TObject *Sender) //инверсия элемента в массиве полинома
{My->getPol()[Scan]=StrToInt(StringGrid2->Cells[Scan][1])^1;->Cells[Scan][1]=IntToStr(My->getPol()[Scan]);}
//---------------------------------------------------------------------------__fastcall
TForm1::scan(TObject *Sender, int ACol, int ARow,bool &CanSelect)
{Scan=ACol;}
//---------------------------------------------------------------------------__fastcall
TForm1::Button2Click(TObject *Sender)
{ int
Step_P=My->getSt();(RadioButton1->Checked==true&&My->getSt()<32&&My->getSt()>2) //Заполнение информационного массива random
{ bool* Inf=My->getInf();(Inf==0) Inf=new
bool[240];->ColCount=240;(i=0;i<My->getV()-Step_P;i++) //Инициализация информации
{ Inf[i]=random(2);
StringGrid1->Cells[i][0]=IntToStr(Inf[i]);
}(i=My->getV()-Step_P;i<My->getV();i++)
{ Inf[i]=0; StringGrid1->Cells[i][0]=IntToStr(Inf[i]); } //Умоножаем на степень полинома->Visible=true;
My->setInf(Inf);
}(RadioButton2->Checked==true&&My->getSt()<32&&My->getSt()>2) //загрузка из файла
{bool* Inf=My->getInf();
OpenDialog1->DefaultExt="isk";
OpenDialog1->FilterIndex=2;(OpenDialog1->Execute())
{ FILE
*P=fopen(OpenDialog1->FileName.c_str(),"r");
fseek(P,0l,0);a[33]={0}; i=0;{ a[i]=fgetc(P); i++; }
while(feof(P)==0&&i<33);(Inf==0) Inf=new bool[My->getV()]; char
A=128;
for(i=0;i<30;i++) //вывод на экран
{A=128;(j=0;j<8;j++)
{ Inf[8*i+j]=((a[i]&A)>>(7-j))&0x1; A=A/2; }
}->ColCount=My->getV();
StringGrid4->ColCount=My->getV();(i=0;i<My->getV();i++)
{StringGrid4->Cells[i][0]=IntToStr(Inf[i]);
StringGrid1->Cells[i][0]=IntToStr(Inf[i]); }->Visible=true;
StringGrid4->Visible=true;>setInf(Inf); fclose(P); } } }
//---------------------------------------------------------------------------__fastcall
TForm1::Inversia_inf(TObject *Sender)
{My->getInf()[Scan]=StrToInt(StringGrid1->Cells[Scan][0])^1;->Cells[Scan][0]=IntToStr(My->getInf()[Scan]);}
//---------------------------------------------------------------------------__fastcall
TForm1::Button3Click(TObject *Sender) //кодирование информации
{ My->Cod(); StringGrid3->ColCount=My->getSt();
StringGrid3->Visible=true;
for(i=0;i<My->getSt();i++) //Вывод на экран
регистров кодера
{StringGrid3->Cells[i][0]=IntToStr(My->getReg()[i]);
}*Err=My->getErr();(Err==0) { Err=new bool[My->getV()];
}->ColCount=My->getV();(i=0;i<My->getV();i++)
{ Err[i]=0;
StringGrid4->Cells[i][0]=IntToStr(My->getInf()[i]);->Cells[i][1]=IntToStr(0);
}->Visible=true; My->setErr(Err); }
//---------------------------------------------------------------------------__fastcall
TForm1::Inversia_err(TObject *Sender)
{My->getErr()[Scan]=StrToInt(StringGrid4->Cells[Scan][1])^1;->Cells[Scan][1]=IntToStr(My->getErr()[Scan]);
}
//---------------------------------------------------------------------------__fastcall
TForm1::Button4Click(TObject *Sender) //декодирование
{ My->Decod(); StringGrid5->ColCount=My->getSt();
StringGrid5->Visible=true;(i=0;i<My->getSt();i++) {
StringGrid5->Cells[i][0]=IntToStr(My->getDec()[i]); }
int E=0 ; //наличие ошибки(i=0;i<My->getSt();i++) //проверка
регстра декодара на наличие "1"
{ if(My->getDec()[i]==1) E=1; }
if (E==0) Label6->Caption="Ошибок не обнаружено" ; //нулевой
вес остатка(E==1) Label6->Caption="Передача произведена с
ошибками" ; }
//---------------------------------------------------------------------------__fastcall
TForm1::BitBtn2Click(TObject *Sender) //Сохранение полинома в файл
{ SaveDialog1->DefaultExt="pol";
SaveDialog1->FilterIndex=2;(SaveDialog1->Execute())
{FILE
*P=fopen(SaveDialog1->FileName.c_str(),"w+");
fseek(P,0l,0);(My->getPol()!=0)
{char A=0; int B=128;(i=0;i<=(My->getSt())/8;i++)
{ A=0; B=0x80;(j=0;j<8;j++)
{ if(8*i+j<=My->getSt())
A=A|((My->getPol()[i*8+j])*B);=B/2; }(A,P); }(P); } } }
//---------------------------------------------------------------------------__fastcall
TForm1::BitBtn1Click(TObject *Sender) //Загрузка полинома из файла
{ OpenDialog1->DefaultExt="pol"; OpenDialog1->FilterIndex=2;(OpenDialog1->Execute())
{ FILE
*P=fopen(OpenDialog1->FileName.c_str(),"r");
fseek(P,0l,0);>setSt(StrToInt(Edit1->Text)); char a[4]={0}; i=0;{
a[i]=fgetc(P); i++; } while(feof(P)==0&&i<4);(My->getPol()!=0)
delete [My->getSt()+1] My->getPol();->ColCount=My->getSt()+1; bool*
Pol=new bool[32]; char A=128;
for(i=0;i<4;i++) //вывод на экран
{ A=128;(j=0;j<8;j++)
{Pol[8*i+j]=((a[i]&A)>>(7-j))&0x1; A=A/2; }
}(i=0;i<=My->getSt();i++)
{StringGrid2->Cells[i][0]=IntToStr(My->getSt()-i);
StringGrid2->Cells[i][1]=IntToStr(Pol[i]);
}->Text=StrToInt(My->getSt()); StringGrid2->Visible=true;
Label2->Visible=true;>setPol(Pol); fclose(P); } }
//---------------------------------------------------------------------------__fastcall
TForm1::BitBtn3Click(TObject *Sender) //запись информации в файл
{SaveDialog1->InitialDir=GetCurrentDir();
SaveDialog1->DefaultExt="inf";->FilterIndex=2;(SaveDialog1->Execute())
{ FILE
*P=fopen(SaveDialog1->FileName.c_str(),"w+");fseek(P,0l,0);(My->getInf()!=0)
{char A=0; int B=128;(i=0;i<32;i++)
{ A=0; B=0x80;(j=0;j<8;j++)
{ A=A|((My->getInf()[i*8+j])*B); B=B/2; }(A,P); } }(P); } }
//---------------------------------------------------------------------------__fastcall
TForm1::BitBtn4Click(TObject *Sender) //сохранение значений регистров кодера
{ SaveDialog1->DefaultExt="cod";
SaveDialog1->FilterIndex=2;(SaveDialog1->Execute())
{FILE
*P=fopen(SaveDialog1->FileName.c_str(),"w+");
fseek(P,0l,0);(My->getReg()!=0)
{ char A=0; int B=128;(i=0;i<=(My->getSt())/8;i++)
{ A=0; B=0x80;(j=0;j<8;j++)
{ if(8*i+j<My->getSt())
A=A|((My->getReg()[i*8+j])*B);=B/2; }(A,P); }(P); } } }
//---------------------------------------------------------------------------__fastcall
TForm1::BitBtn6Click(TObject *Sender) //сохранение значений регистров декодера
{SaveDialog1->DefaultExt="dec";
SaveDialog1->FilterIndex=2;(SaveDialog1->Execute())
{ FILE
*P=fopen(SaveDialog1->FileName.c_str(),"w+");
fseek(P,0l,0);(My->getDec()!=0)
{ char A=0; int B=128;(i=0;i<=(My->getSt())/8;i++)
{ A=0; B=0x80;(j=0;j<8;j++)
{ if(8*i+j<My->getSt())
A=A|((My->getDec()[i*8+j])*B); B=B/2; }(A,P); }(P); } } }
//---------------------------------------------------------------------------__fastcall
TForm1::BitBtn5Click(TObject *Sender) //Сохранение вектора ошибок
{ SaveDialog1->DefaultExt="err";
SaveDialog1->FilterIndex=2;(SaveDialog1->Execute())
{ FILE
*P=fopen(SaveDialog1->FileName.c_str(),"w+");
fseek(P,0l,0);(My->getErr()!=0)
{char A=0; int B=128;(i=0;i<32;i++)
{ A=0; B=0x80;(j=0;j<8;j++)
{ A=A|((My->getErr()[i*8+j])*B); B=B/2; }(A,P); } }(P);
} }
//---------------------------------------------------------------------------__fastcall
TForm1::BitBtn7Click(TObject *Sender) //Считывание вектора ошибок
{ bool* Err=My->getErr();
OpenDialog1->DefaultExt="err"; OpenDialog1->FilterIndex=2;(OpenDialog1->Execute())
{FILE
*P=fopen(OpenDialog1->FileName.c_str(),"r"); fseek(P,0l,0); char
a[33]={0}; i=0;{ a[i]=fgetc(P); i++;}
while(feof(P)==0&&i<33);(Err==0) Err=new
bool[My->getV()];A=128;(i=0;i<30;i++) {A=128; //вывод на экран(j=0;j<8;j++)
{ Err[8*i+j]=((a[i]&A)>>(7-j))&0x1; A=A/2; }
}->ColCount=240;(i=0;i<My->getV();i++)
{StringGrid4->Cells[i][1]=IntToStr(Err[i]);
}->Visible=true; My->setErr(Err); fclose(P); } } }