Проектирование устройства передачи данных по радиоканалу
Тогда стоимостная оценка затрат будет
равна:
З= ΣКiai- ΣЛiаi + ΣUiai=720,3-609,12+2188,8=2299,98 тыс.грн.
Определение
экономического эффекта
Экономический эффект за расчетный
период определяется по формуле:
Э=Рт-Зт
Где Рт — стоимостная оценка
результата.
Э =
2633,71-2299,98= 334 тыс. грн.
Прибыль, остающаяся в распоряжении
предприятия в расчете на одно изделие составляет:
Пои=Э/ ΣАi
Пои= 334000/3000=111,3
грн.
Срок возврата единовременных затрат
составляет:
Tв=(
ΣКi*αi - ΣЛi*αi)/Э
Тв =
(920,3-509,12)/(3419,14-2496)=0,7 года
7. Охрана труда
7.1 Характеристика проектируемого прибора
Данный прибор выполняет функции приёма
и передачи аналогового сигнала по радиоканалу при этом осуществляя функции модуляции
и демодуляции используя цифровой сигнальный процессор фирмы Analog Devices ADSP 2115. При приёме демодулированный сигнал передаётся через
последовательный порт в IBM -
совместимый компьютер, где обрабатывается и данные выводятся на экран компьютера.
При передаче цифровой код принимается
из компьютера и после модуляции направляется в радиопередатчик.
Данное устройство обработки сигналов работает
совместно с компьютером и с блоком приёма и передачи сигнала по радиоканалу
(БППСР). Подробная работа БППСР в данном дипломном проекте не рассматривается по
различным причинам (большое кол-во входящих подблоков, огромное кол-во функций и
т.п. ), мы просто принимаем его как необходимый узел для практического использования
нашего устройства. В свою очередь наше устройство очень тесно связано с компьютером,
даже более того, работа оператора с нашим устройством заключается в его работе с
компьютером. Исходя из этого необходимо принять соответствующие меры для организации
рабочего места оператора с точки зрения охраны труда.
Меры для организации рабочего места и
безопасности проведения настроечных работ рассмотрим в пункте 7.3.
Разрабатываемому изделию
следует определить набор требований по технике безопасности на этапе
эксплуатации. В компьютерах наи-большую опасность представляет поражение
электрическим током. Источники питания компьютеров (кроме блокнотных) и
переферийных устройств рассчитаны на сеть переменного тока 220В 50Гц. Типовой
блок питания включается в сеть трехпроводным шнуром питания с вилкой, bимеющей заземляющий контакт.
Заземляющий провод соединен с корпусом и его "схемной землёй".
Питающие провода проходят через высокочастотный фильтр, подавляющий импульсные
помехи, емкость конденсаторов фильтра пропорциональна мощности источника
питания.
Для обеспечения
сохранности техники (интерфейсных цепей) заземляющие контакты всех соединяемых
между собой устройств (компьютер, монитор, принтер) должны надёжно объединяться
через соответствующие розетки. Питание монитора через транзитный разъём блока
питания системного блока обеспечивает это соединение.
Для обеспечения
электробезопасности соединенные между собой заземляющие контакты розеток должны
соединяться с общим проводом заземления или с нулевым проводом питания сети
(исключая возможность его переключения на фазный провод). Игнорирование этого правила
может приводить к появлению на корпусе устройств напряжения прикосновения 110В
переменного тока. Уровень ограничения тока при прикосновении определяется
ёмкостью конденсаторов фильтра и зависит от мощности устройства. Ток через
человека, имеющего контакт с землёй (например, через пол) и прикоснувшегося к
устройству, может достигать десятков миллиампер,что является опасным для жизни.
Блок питания компьютера
обычно имеет стандартный конструктив и набор проводов с разъёмами питания
системной платы и перефирийных устройств. Устройство конструктивно выполнено в
виде печатной платы, размещаемой в отдельном корпусе. Блок питается от
источника питания напряжением 5 и 12 вольт постоянного тока. Сигнальные
напряжения не превышают 5 вольт, что практически безопасно. Устройство
выполнено на интегральных микросхемах и дискретных элементах. Суммарная рассеиваемая
мощность на плате не превышает 5 Вт. Создаваемый тепловой поток меньше
теплового потока создаваемого остальными узлами компьютера, дополнительная
теплоизоляция не требуется.
Блок не создает
сколь-нибудь значительных электромагнитных, СВЧ, ВЧ полей. Поскольку
разрабатываемое устройство устанавливается на штатное место, особенности
эксплуатации отсутствуют. Наружный кожух устройства изготавливается из изоляционного
материала исключающего появление на нём потенциала опасного для человека (
пластмасса, дерево и т.п.). Ниже приведена конструкция кожуха и вентиляционных отверстий.
Рис. 7.1 Конструкция кожуха.
7.2 Анализ тестирования устройства
№ |
Этап настройки |
Приборы, участвующие в настройке |
Опасности и вредные факторы |
Мероприятия, устранящие выявленные опасности и вредные
факторы |
1. |
Программирова-ние цифрового сигнального процессора |
ЭВМ
(Intel Pentium)
|
Влияние
мягкого рентгеновского излучения от ЭЛТ на зрение |
Применение защитного экрана, монитора типа Low Radiation,
правильное расположение монитора на рабочем месте |
2. |
Отладка программы |
ЭВМ
(Intel Pentium)
|
Влияние
мягкого рентгеновского излучения от ЭЛТ на зрение |
Применение защитного экрана, монитора типа Low Radiation,
правильное расположение монитора на рабочем месте |
3. |
Тестирование входных и выходных сигналов |
Осцилограф (C1-99),
генератор (Г1-34)
|
Опасность поражения электрическим током |
Заземление корпуса осцилографа |
Рис. 7.3 Блок - схема тестирования.
Как видно из блок-схемы на стадии тестирования
прибора в которой существует опасность поражения эл. током, необходимо выполнять
заземление используемых приборов. Для предотвращения влияния на зрение мягкого
рентг. излучения необходимо выбирать рекомендуемый монитор.
7.3 Организация рабочего места и безопасность
проведения тестирования
В данном дипломном проекте создается устройство
которое напрямую связано с компьютером и управляется с помощью его. Для
обслуживания данного устройства требуется опытный оператор, который должен находится
за компьютером и следить за принимаемой информацией и при необходимости передавать
другую информацию. В этом случае оператор постоянно находится за компьютером. Поэтому
необходимо разработать меры по правильной организации рабочего места и безопасности
проведения настроечных работ. Мероприятия для безопасности проведения
тестирования Тестирование производится оператором на его рабочем месте. Под
рабочим местом понимается зона, оснащенная необходимыми техническими
средствами, в которой совершается трудовая деятельность исполнителя или группы
исполнителей, совместно выполняющих одну работу или операцию. Главным
требованием при выборе основного оборудования является обеспечение на данном
рабочем месте необходимых безопасных комфортных условий труда и производительности
труда, поэтому выбираемое оборудование должно отвечать требованиям эргономики,
т.е. требованиям техники безопасности, психологическим и физиологическим
возможностям работающего, с учетом его антропомет- рических показателей. Под
планировкой рабочего места понимают взаимное расположение основного и
вспомогательного оборудования, инвентаря и оснастки на отведенной производственной
площади, обеспечивающее наиболее эффективное выполнение трудовых процессов,
экономию усилий, минимальное утомление работающего и безопасность его труда. Рабочее
место при наладке представляет собой стол, стул. На столе расположено следующее
оборудование: - компьютер персональный типа INTEL PENTIUM ; - монитор цветной
типа LG 14 ' LR; - осциллограф типа C1-99; - генератор сигналов типа Г1-34; -
принтер Canan BJ-200; Оператор напрямую соприкасается с клавиатурой, мышью, осциллографом
и монитором. Тестирование заключается в поиске ошибок в программном
обеспечения, проверке электрических соединений. В помещениях с ПК
обеспечивается равномерное распределение яркости (перепад яркости не превышает
1:3), исключаются яркие источники света и блестящие отражающие предметы в поле
зрения оператора. Источником электромагнитных полей и излучений могут служить
монитор и осциллограф. Выбранные монитор (ДП 14' LR) и
осциллограф (С1-99) сконструированы таким образом, что все виды излучений
находятся в диапазоне допустимых значений на любых расстояниях от них (нормируется
по ГОСТ 12.1.006 - 84 и по ГОСТ 12.1.002 - 84). Источником шума и вибрации
может служить принтер. Выбранный принтер Canon BJ-200 использует химическую технологию печати, уровень шума,
создаваемого при работе, удовлетворяет самым строгим требованиям. Для освещения
применяют газоразрядные лампы. Допустимая пульсация освещенности для зрительных
работ составляет 10%. Поскольку весь комплекс оборудования при наладке
устройства питается от сети переменного тока напряжением 220V, 50Hz то для
защиты от воздействия электрического тока корпуса монитора, принтера, клавиатуры
выполняются из диэлектрического материала. Корпуса, сделанные из металлического
материала заземляются, все провода должны быть надежно заизолированы. Дополнительные
меры безопасности:
·
Конструкция всех
элементов рабочего места (РМ) должна исключать возможность прикосновения
человека к частям и элементам под напряжением свыше 36 В при любых, в том числе
ошибочных, действиях пользователя, не связанных со вскрытием корпуса.
·
Система
электропитания РМ должна обеспечивать гальваническую развязку от потенциала
"земли" с сопротивлением не менее 1 МОм.
·
Система
электропитания РМ должна быть оборудована устройством защитного отключения,
обеспечивающим отключение питающих напряжений от рабочих мест при возникновении
утечки на "землю" свыше 10 мА, при перегрузках и коротких замыканиях.
·
Конструкция
соединителей и разъемов должна исключать возможность ошибочного подсоединения к
линиям с неверным напряжением. Кабели электропитания должны иметь достаточную механическую
прочность (обеспечиваемую, например, защитной гибкой пластмассовой трубкой или
гибким проволочным экраном.).
Мероприятия по эргономике и организации
рабочего места:
Эргономика и эстетика производства
являются составными частями культуры производства, т.е. комплекса мер по
организации труда, направленных на создание благоприятной рабочей обстановки.
В основе повышения культуры
производства лежат требования научной организации труда. Культура производства
достигается правильной организацией трудовых процессов и отношений между
работающими, благоустройством рабочих мест, эстетическим преобразованием среды.
Во время работы часто возникают
ситуации, в которых оператор ЭВМ должен за короткий срок принять правильное
решение. Для успешного труда в таких условиях необходимы рационально
организованная окружающая среда, ограничивающая работника от воздействия
посторонних раздражителей, которыми могут быть: мрачная окраска стен, неудобное
расположение сигнализации, клавиш управления. Поэтому всеми средствами нужно
снижать утомление и напряжение оператора ЭВМ, создавая обстановку
производственного комфорта.
Размерные
характеристики рабочего места
Конструкцией рабочего места должно
быть обеспечено выполнение трудовых операций в пределах зоны досягаемости
моторного поля. Зоны досягаемости моторного поля в вертикальной и
горизонтальной плоскостях для средних размеров тела человека приведены в ГОСТ
12.2.032-78 на стр.2.
Выполнение трудовых
операций "часто" и "очень часто" должно быть обеспечено в
пределах зоны легкой досягаемости. Поскольку наладка блока может производиться
как мужчинами, так и женщинами, следует учесть средние антропометрические
показатели и мужчин и женщин. Так как высота рабочих поверхностей является
регулируемой, то значения будем выбирать для роста 1800 мм. Оно составит 800 мм
согласно номограмме 4 приведенной в ГОСТ 12.2.032-78 на стр.4. Конструкция
регулируемого кресла должна соответствовать ГОСТ 21889- 76. Форма рабочей
поверхности прямоугольная. Расположение оборудования на рабочей поверхности:
Рис.7.3.2.1 - Расположение
приборов на рабочей поверхности стола и распределение зон их досягаемости.
Зона 1 - зона
расположения наиболее важных органов управ-ления.
Зона 2 - зона
расположения легкодоступного оборудования.
Зона 3 - зона размещения
редкоиспользуемых органов управления.
В зоне 1 расположены
монитор и клавиатура. В зоне 2 расположен осциллограф, мультиметр и налаживаемое
устройство. В зоне 3 расположен принтер. Монитор, как самое важное средство
отображения информации, должен быть установлен таким образом, чтобы центр ЭЛТ
находился на линии взгляда или немного ниже.
7.4 Выводы по охране труда
В ходе разработки раздела "Охрана
труда" было создано три параграфа характеризующие работу устройства ,
кодирования - декодирования информации на цифровом сигнальном процессоре, с точки
зрения безопасности жизнедеятельности. В качестве детального изучения и устранения
одной из опасностей была выбрана: Организация рабочего места оператора
и безопасность проведения тестирования. Т.к. оператор нашего устройства должен работать
за ЭВМ, все расматривалось с точки зрения обустройства и безопасности работы оператора
ЭВМ. Оценка тяжести и напряженности труда по эргономическим показателям целью
отнесения их к определенной категории осуществляется по наибольшему
количественному критерию. В результате анализа эргономических показателей
психофизиоло-гических факторов можно сделать вывод, что работа по наладке
устройства относится к категории "легкая, малонапряженная".
Приложение 1
Главный модуль
main.c
//
Подключаем заголовочные файлы и объявляем локальные и глобальные // переменные
#include <drivers.h>
#include <nbdp.h>
#include <string.h>
#include <ctype.h>
int PTT_Recalc;
int DebugLevel;
/*-------------------------------------------------------------*/
int cntr;
int CALL_ID[10];
//
Объявление внешних функций и переменных
extern
void FreeSignal(void);
extern int IsCharReady(void);
extern int FRE_FLAG;
extern int setISS,setIRS;
/*-------------------------------------------------------------*/
void main()
{
int save_dsw;
/*-------------------------------------------------------------*/
// Сброс выводов
FL2..FL0
asm("reset fl0;");
asm("reset fl1;");
asm("reset fl2;");
init_1847(); // Инициализация
кодека
AD1847
UART_Init(); // Инициализация
интерфейса
UART
//
Дадим команду host-устройству на
инициалицацию
SendCommandHost("INIT","POWER
ON");
// Инициализируем
структуру
NBDP (narrowband direct printing)
NBDP_Init();
//
Процесс обмена данными
while(1)
{
if(COMF
& 1)
{
if(COMF
& 0x02) arq(); // запустить протокол ARQ
,
описание в
//
npdp_arq.c
else
if(COMF & 0x1C) fec(); // запустить протокол FEC
,
описание в
//
npdp_fec.c
else
// Если другое сотояние COMF,
то ошибку в host
{
SendHostError(5,COMF); /* COMF ERROR */
StandBy();
}
}
if(FRE_FLAG)
// Если модем свободен
{
FRE_FLAG=0;
//
Отправим команду в host , что модем свободен
SendCommandHost("FRE",FRE_FLAG
== 1 ? "1":"0");
}
/*
Если символ готов к передаче , выбрать команды из порта*/
if(IsCharReady()) SerialDriver();
// Передача
символов
в
HOST
if((COMF & 1) && (ho_count))
{
char block[15],d;
int i=0;
while(hoRead(&d) != -1)
{
block[i++] = d;
if(i>14) break;
}
block[i]=0;
SendCommandHost("TXT",block); // отправка
блока
в
host
}
} // end of while
} // end of main()
/*-------------------------------------------------------------*/
int
CheckCommRequest(char *DATA) // Проверка корректности номера
//
объекта связи (парохода), по
//
которому происходит связь с данным
//
объектом
{
int j=0,tmp;
for(j=0;DATA[j]!=';';)
{
tmp
= DATA[j];
if(!(tmp>='0'
&& tmp<='9')) // цифры не могут быть кодом объекта
{
SendHostError(11,tmp); /* ERR;01.1;ID WRONG DIGIT
(%c),ID[j] */
return 1;
}
CALL_ID[j] = tmp;
j++;
if(j>9) break;
}
CALL_ID[j]=0;
if(j!=4
&& j!=5 && j!=9) /* incorrect ID */ // символ ';' в коде должен
быть // третьим, четвертым или восьмым
{
SendHostError(12,j);
return
1;
}
return
0; // проверка успешна, возврат 0.
}
/*-------------------------------------------------------------*/
//
массив названий команд для функции SendCommandHost(char
*cmd, ...)
char *cmds[] =
{
"TXT","ARQ","CFE","SFE","SET",
/* 0... 4 */
"STA","INI","DEB","DBG","DIA",
/* 5... 9 */
"FRE","STB","TST","STR","FCC",
/* 10...14 */
NULL
};
int CheckCommRequest(char *DATA);
/*-------------------------------------------------------------*/
Программа модуляции
За основу данного способа модуляции взята
- частотная модуляция с использованием протокола морского телеграфа NBDP ( narrowband direct printing) - узкополосное буквопечатанье. В основе
лежит таблица кодовых значений сиволов, которые представляются в виде комбинации
1 и 0 и после модулируются с соответственно частотами 1615 Hz и 1785 Hz. (
таблица символов в файле nbdp_table.c ).
Mod.c
//
Подключаем заголовочные файлы и объявляем локальные и глобальные // переменные
#include <drivers.h>
#include <template.h>
#include <nbdp.h>
/*-------------------------------------------------------------*/
/*#define OUT_KOEFF 0x6000*/
#ifdef RX_TO_TX_
extern int RX_TO_TX[2];
#endif
/*-------------------------------------------------------------*/
int PH_ACC,TMP_PH_ACC;
int PH_INC;
int mod_ready=1;
int BITTIME=1;
int bits_left;
int out_data;
volatile int l_out,r_out;
extern int FDIV,FS_PTT_OFF;
int dbg_cntr;
/*-------------------------------------------------------------*/
/* MODULATOR */
/*-------------------------------------------------------------*/
extern void Timing(void);
void
modulator(void)
{
//
Возможна работа в тестовом режиме.
if(SelfTest) goto test_modes;
FDIV++;
//
через 10 мс обнуление отсчетов и посылка в хост синхронизирующего // сигнала цикла
ARQ.
if(FDIV==80) {FDIV=0;NBDP_THR_TX();}
#ifdef RX_TO_TX_
tx_buf[1] = RX_TO_TX[0];
tx_buf[2] = RX_TO_TX[1];
return;
#endif
//
Проверка нужна ли модуляция, если нет то возврат
if(!Modulator_ON)
{
PH_ACC = 0;
return;
}
restart:
if(mod_ready)
{
tx_buf[1] = tx_buf[2] = 0;
if(FS_PTT_OFF) // выключение
модуляции
{
FS_PTT_OFF=0;
PTT_OFF();
}
return;
}
test_modes:
BITTIME--;
if(BITTIME==0)
{
/*=== determine the new bit from out byte ===*/
// Режим реальной
работы
if(!SelfTest) out_data <<= 1; /* 7 bit mode */
if(out_data & 0x80) /* MARK */
{
PH_INC = MARK_INC;
asm("
#define PFDATA 0x3fe5
ar = b#0000000001000000; /* set 1 PF6/TLG OUT */
ay1 = dm(PFDATA);
ar = ar or ay1;
dm(PFDATA) = ar;");
}
else /* SPACE */
{
PH_INC = SPACE_INC;
asm("
ar = b#1111111110111111; /* reset 1 PF6/TLG OUT */
ay1 = dm(PFDATA);
ar = ar and ay1;
dm(PFDATA)
= ar;");
}
//
Тестовый режим, работа в 8-битном режиме
if(SelfTest) out_data <<= 1;
BITTIME = BITLENGTH;
bits_left--;
if(bits_left<0)
{
mod_ready=1;
modulating();
goto restart;
}
else
{
/* blink by PF7 as syncro_out */
asm("
ar = dm(PFDATA);
ar = tglbit 7 of ar;
dm(PFDATA) = ar; ");
/* -------------------------- */
}
}
/*asm ("dis m_mode;");*/
PH_ACC += PH_INC;
l_out = sin_i(PH_ACC);
tx_buf[2]
= l_out; // выдача результатов в порт ( связь с кодеком)
}
/*-------------------------------------------------------------*/
void modulating(void)
{
if(SelfTest)
{
if(SelfTest==1) /* space */
{
out_data = 0;
}
else if(SelfTest==2) /* mark */
{
out_data = 0xFF;
}
else if(SelfTest==3) /* dot */
{
/* 10101010 */
out_data = 0xAA;
}
else if(SelfTest==4) /* big dot */
{
/* 11110000 */
out_data = 0xF0;
}
else
{
SelfTest=0;
}
BITTIME=1;
bits_left=8;
// 8-битный режим работы
mod_ready=0;
return;
}
//
В случае тестового режима дальше не идем
if(mod_ready == 0) return;
BITTIME=1;
if(ModulatorGet(&out_data)==0) /* nothing to get
*/
{
// обнуление
флагов
и
возврат
/* clear PF6 as TLG & PF7 as syncro_out */
asm("
ar = dm(PFDATA);
ar = clrbit 7 of ar;
ar = clrbit 6 of ar;
dm(PFDATA) = ar; ");
/*
-------------------------- */
return;
}
bits_left=7;
// 7-битный режим работы
mod_ready=0;
}
Программа демодуляции
Принцип демодуляции входного сигнала нашего
устройства, основывается на том, что нам известны частоты поступающие от
отдельного устройства приема сигнала по радиоканалу, уже отфильтрованные и
поданные на вход нашего устройства. И нам необходимо выделить соответственно частоты
1785 Hz = MARK = ' 0 ' и 1615 Hz = SPACE = ' 1 ' и получить
определенный код. После получении кода происходит раскодирование по таблице NBDP и передача в ЭВМ, где программа TERMINAL соответственно реагирует на данные
кода.
// Demod.c
//
Подключаем заголовочные файлы и объявляем локальные и глобальные // переменные
#include <drivers.h>
#include <stdlib.h>
#include <template.h>
#include <nbdp.h>
extern void out_mcr(int data);
#define DMD_KOEFF 0x019A
#define DMD_LEVEL 0x1000 /* порог
срабатывания
*/
#define OUT_MARK 'M'
#define OUT_SPACE 'S'
#define OUT_ERR 'E'
int my_fir(int NewValue);
int my_sqrt(int NewValue);
/*-------------------------------------------------------------*/
volatile int l_in,r_in;
int Demodulator_ON=1; // Demodulator ON/OFF flag
int PH_TONE_ACC[2]; // опорный
MARK/SPACE PHASE ACC
int PH_TONE_INC[2] = {MARK_INC, SPACE_INC};
int
i,j; // временные счетчики
int
R [4]; // временные результаты
int S [4]; // частичные
суммы
int DL[4*BITLENGTH]; // Delay lines for 4 bands
int DLp = 0; // DL pointer
int countN=BITLENGTH; // Cycle count
int
REZ[2]; // Результаты
int
PRZLT[2]; // Приблизительные результаты (prev.
Rez)
int svMode; /* Save multiplier mode location */
int JitterOff; /* Bit syncro OFF flag */
int OutData[2];
void demodulator(void)
{
//
Если демодулятор откл., то обнуление результатов и возврат
if(!Demodulator_ON && (dip_sw &
DIP_SW1))
{
REZ[0] = 0;
out_mcr(0);
goto CheckCycle;
}
if(SelfTest)
// Если тестовый режим, то возврат
{
return;
}
//
Выключение режима целочисленной арифметики
asm("dis
m_mode;");
l_in = rx_buf[IN_CHNL];
//
ограничить входной сигнал для устранения переполнения фильтра
r_in = _FRACT_MULTIPLY_(r_in,DMD_KOEFF);
Заполняем
массив временных результатов для MARK
и SPACE
PH_TONE_ACC[0] += PH_TONE_INC[0];
R[0] = _FRACT_MULTIPLY_(r_in,sin_i(PH_TONE_ACC[0]));
R[1] = _FRACT_MULTIPLY_(r_in,cos_i(PH_TONE_ACC[0]));
PH_TONE_ACC[1] += PH_TONE_INC[1];
R[2] = _FRACT_MULTIPLY_(r_in,sin_i(PH_TONE_ACC[1]));
R[3] = _FRACT_MULTIPLY_(r_in,cos_i(PH_TONE_ACC[1]));
//Извлекаем
старые данные и добавляем новые
for(i=0;i<4;i++)
{
S[i] = S[i] - DL[DLp];
S[i] = S[i] + R[i];
DL[DLp++] = R[i];
}
if(DLp >= (4*BITLENGTH)) DLp=0; /* wrap DL
pointer */
//
Получение результата по каждому фильтру.
PRZLT[0] = REZ[0]; // Предварительный
результат
REZ[0] = _FRACT_MULTIPLY_(S[0],S[0]) +
_FRACT_MULTIPLY_(S[1],S[1]);
REZ[1] = _FRACT_MULTIPLY_(S[2],S[2]) + _FRACT_MULTIPLY_(S[3],S[3]);
if(dip_sw & DIP_SW2)
{
REZ[0] = my_sqrt(REZ[0]);
REZ[1] = my_sqrt(REZ[1]);
}
R[1] = (REZ[0]-REZ[1]);
R[2] = (REZ[0]+REZ[1]);
R[0] =
_FRACT_MULTIPLY_((_FRACT_DIVIDE_(R[1],R[2])),0x6400);
REZ[0] = R[0];
/* debug solution output */
tx_buf[1] = REZ[0];
/*================================================
STEP 4.
Time supervision, bit detection, etc.
================================================*/
CheckCycle:
countN--;
if(!countN)
{
if(abs(REZ[0]) > DMD_LEVEL)
{
if(REZ[0] > 0)
{
OutData[0] = OUT_MARK;
asm("reset fl0; set fl2; set fl1; ");
}
else
{
OutData[0] = OUT_SPACE;
asm(" set fl0; reset fl2; set fl1; ");
}
}
else
{
OutData[0] = OUT_ERR;
asm(" set fl0; set fl2; reset fl1; ");
}
countN
= BITLENGTH;
//
отправляем на ЦАП (кодек)
NBDP_THR_RX(OutData[0]);
}
//
включение режима целочисленной арифметики
asm("ena
m_mode;");
}
Дополнительные
программы и функции
1. Программа nbdp_table.c
Содержит таблицу соответствия кодов ASCII и кодов формата NBDP.
#include <nbdp.h>
/*B - MARK FREQ:1785Hz
/*Y - SPACE FREQ:1615Hz
/* ¦ +-----------------¦
5-Unit ¦ 7-Unit ¦ */
/* ¦No ¦LET ¦FIG ¦RUS ¦ Code
¦ Code ¦ */
UCHAR _7bit_code[]= {
/*+--+-----+-----+-----+---------+-----------¦ */
0x71 ,/*¦01¦A 41 ¦- 2D ¦А 80 ¦ZZAAA ¦BBBYYYB 71 ¦ */
0x27 ,/*¦02¦B 42 ¦? 3F ¦Б 81 ¦ZAAZZ ¦YBYYBBB 27 ¦ */
0x5c ,/*¦03¦C 43 ¦: 3A ¦Ц 96 ¦AZZZA ¦BYBBBYY 5C ¦ */
0x65 ,/*¦04¦D 44 ¦Wh?? ¦Д 84 ¦ZAAZA ¦BBYYBYB 65 ¦ */
0x35 ,/*¦05¦E 45 ¦3 33 ¦Е 85 ¦ZAAAA ¦YBBYBYB 35 ¦ */
0x6c ,/*¦06¦F 46 ¦Э*9D ¦Ф 94 ¦ZAZZA ¦BBYBBYY 6C ¦ */
0x56 ,/*¦07¦G 47 ¦Ш*98 ¦Г 83 ¦AZAZZ ¦BYBYBBY 56 ¦ */
0x4b ,/*¦08¦H 48 ¦Щ*99 ¦Х 95 ¦AAZAZ ¦BYYBYBB 4B ¦ */
0x59 ,/*¦09¦I 49 ¦8 38 ¦И 88 ¦AZZAA ¦BYBBYYB 59 ¦ */
0x74 ,/*¦10¦J 4A ¦Ю*07 ¦Й 89 ¦ZZAZA ¦BBBYBYY 74 ¦ */
0x3c ,/*¦11¦K 4B ¦( 28 ¦К 8A ¦ZZZZA ¦YBBBBYY 3C ¦ */
0x53 ,/*¦12¦L 4C ¦) 29 ¦Л 8B ¦AZAAZ ¦BYBYYBB 53 ¦ */
0x4e ,/*¦13¦M 4D ¦. 2E ¦М 8C ¦AAZZZ ¦BYYBBBY 4E ¦ */
0x4d ,/*¦14¦N 4E ¦, 2C ¦Н 8D ¦AAZZA ¦BYYBBYB 4D ¦ */
0x47 ,/*¦15¦O 4F ¦9 39 ¦О 8E ¦AAAZZ ¦BYYYBBB 47 ¦ */
0x5a ,/*¦16¦P 50 ¦0 30 ¦П 8F ¦AZZAZ ¦BYBBYBY 5A ¦ */
0x3a ,/*¦17¦Q 51 ¦1 31 ¦Я 9F ¦ZZZAZ ¦YBBBYBY 3A ¦ */
0x55 ,/*¦18¦R 52 ¦4Ч34 ¦Р 90 ¦AZAZA ¦BYBYBYB 55 ¦ */
0x69 ,/*¦19¦S 53 ¦' 27 ¦С 91 ¦ZAZAA ¦BBYBYYB 69 ¦ */
0x17 ,/*¦20¦T 54 ¦5 35 ¦Т 92 ¦AAAAZ ¦YYBYBBB 17 ¦ */
0x39 ,/*¦21¦U 55 ¦7 37 ¦У 93 ¦ZZZAA ¦YBBBYYB 39 ¦ */
0x1e ,/*¦22¦V 56 ¦= 3D ¦Ж 86 ¦AZZZZ ¦YYBBBBY 1E ¦ */
0x72 ,/*¦23¦W 57 ¦2 32 ¦В 82 ¦ZZAAZ ¦BBBYYBY 72 ¦ */
0x2e ,/*¦24¦X 58 ¦/ 2F ¦Ь 9C ¦ZAZZZ ¦YBYBBBY 2E ¦ */
0x6a ,/*¦25¦Y 59 ¦6 36 ¦Ы 9B ¦ZAZAZ ¦BBYBYBY 6A ¦ */
0x63 ,/*¦26¦Z 5A ¦+ 2B ¦З 87 ¦ZAAAZ ¦BBYYYBB 63 ¦ */
0x0f ,/*¦27¦CR 0D -- -----
¦AAAZA ¦YYYBBBB 0F ¦ */
0x1b ,/*¦28¦LF 0A -- -----
¦AZAAA ¦YYBBYBB 1B ¦ */
0x2d ,/*¦29¦LET 16 --
----- ¦ZZZZZ ¦YBYBBYB 2D ¦ */
0x36 ,/*¦30¦FIG 0F --
----- ¦ZZAZZ ¦YBBYBBY 36 ¦ */
0x1d ,/*¦31¦SP 20 -- -----
¦AAZAA ¦YYBBBYB 1D ¦ */
0x2b ,/*¦32¦RUS 00 --
----- ¦AAAAA ¦YBYBYBB 2B ¦ */
/*--------------------------------------------------------------
*/
#ifdef RUSSIAN // структура данных
под русский алфавит
struct CVT CVT_TABLE[] =
{
/*¦ +-----------------¦
5-Unit ¦ 7-Unit ¦ */
/*¦ No ¦LET ¦ FIG ¦RUS ¦ Code
¦ Code ¦ */
/*+----+-------+-------+---------+--------------------¦
*/
{0x41,0x2D,'a' },/*¦01¦A
41 ¦- 2D ¦А 80 ¦ZZAAA ¦BBBYYYB 71 ¦
*/
{0x42,0x3F,'b' },/*¦02¦B
42 ¦? 3F ¦Б 81 ¦ZAAZZ ¦YBYYBBB 27 ¦
*/
{0x43,0x3A,'c' },/*¦03¦C
43 ¦: 3A ¦Ц 96 ¦AZZZA ¦BYBBBYY 5C ¦
*/
{0x44,0x03,'d' },/*¦04¦D
44 ¦Wh?? ¦Д 84 ¦ZAAZA ¦BBYYBYB 65 ¦
*/
{0x45,0x33,'e' },/*¦05¦E
45 ¦3 33 ¦Е 85 ¦ZAAAA ¦YBBYBYB 35 ¦
*/
0x46,',/*¦06¦F
46 ¦Э*9D ¦Ф 94 ¦ZAZZA ¦BBYBBYY 6C ¦ */
{0x47,'{' ,'g' },/*¦07¦G
47 ¦Ш*98 ¦Г 83 ¦AZAZZ ¦BYBYBBY 56 ¦ */
{0x48,'}' ,'h' },/*¦08¦H
48 ¦Щ*99 ¦Х 95 ¦AAZAZ ¦BYYBYBB 4B ¦ */
{0x49,0x38,'i' },/*¦09¦I
49 ¦8 38 ¦И 88 ¦AZZAA ¦BYBBYYB 59 ¦
*/
{0x4A,'`' ,'j' },/*¦10¦J
4A ¦Ю*07 ¦Й 89 ¦ZZAZA ¦BBBYBYY 74 ¦ */
{0x4B,0x28,'k' },/*¦11¦K
4B ¦( 28 ¦К 8A ¦ZZZZA ¦YBBBBYY 3C ¦
*/
{0x4C,0x29,'l' },/*¦12¦L
4C ¦) 29 ¦Л 8B ¦AZAAZ ¦BYBYYBB 53 ¦
*/
{0x4D,0x2E,'m' },/*¦13¦M
4D ¦. 2E ¦М 8C ¦AAZZZ ¦BYYBBBY 4E ¦
*/
{0x4E,0x2C,'n' },/*¦14¦N
4E ¦, 2C ¦Н 8D ¦AAZZA ¦BYYBBYB 4D ¦
*/
{0x4F,0x39,'o' },/*¦15¦O
4F ¦9 39 ¦О 8E ¦AAAZZ ¦BYYYBBB 47 ¦
*/
{0x50,0x30,'p' },/*¦16¦P
50 ¦0 30 ¦П 8F ¦AZZAZ ¦BYBBYBY 5A ¦
*/
{0x51,0x31,'q' },/*¦17¦Q
51 ¦1 31 ¦Я 9F ¦ZZZAZ ¦YBBBYBY 3A ¦
*/
{0x52,0x34,'r' },/*¦18¦R
52 ¦4Ч34 ¦Р 90 ¦AZAZA ¦BYBYBYB 55 ¦ */
{0x53,0x27,'s' },/*¦19¦S
53 ¦' 27 ¦С 91 ¦ZAZAA ¦BBYBYYB 69 ¦
*/
{0x54,0x35,'t' },/*¦20¦T
54 ¦5 35 ¦Т 92 ¦AAAAZ ¦YYBYBBB 17 ¦
*/
{0x55,0x37,'u' },/*¦21¦U
55 ¦7 37 ¦У 93 ¦ZZZAA ¦YBBBYYB 39 ¦
*/
{0x56,0x3D,'v' },/*¦22¦V
56 ¦= 3D ¦Ж 86 ¦AZZZZ ¦YYBBBBY 1E ¦
*/
{0x57,0x32,'w' },/*¦23¦W
57 ¦2 32 ¦В 82 ¦ZZAAZ ¦BBBYYBY 72 ¦
*/
{0x58,0x2F,'x' },/*¦24¦X
58 ¦/ 2F ¦Ь 9C ¦ZAZZZ ¦YBYBBBY 2E ¦
*/
{0x59,0x36,'y' },/*¦25¦Y
59 ¦6 36 ¦Ы 9B ¦ZAZAZ ¦BBYBYBY 6A ¦
*/
{0x5A,0x2B,'z' },/*¦26¦Z
5A ¦+ 2B ¦З 87 ¦ZAAAZ ¦BBYYYBB 63 ¦
*/
{0x0D,0x0D,0x0D},/*¦27¦CR 0D
-- ----- ¦AAAZA ¦YYYBBBB 0F ¦ */
{0x0A,0x0A,0x0A},/*¦28¦LF 0A
-- ----- ¦AZAAA ¦YYBBYBB 1B ¦ */
{0x01,0x01,0x01},/*¦29¦LET
16 -- ----- ¦ZZZZZ ¦YBYBBYB 2D ¦ */
{0x02,0x02,0x02},/*¦30¦FIG
0F -- ----- ¦ZZAZZ ¦YBBYBBY 36 ¦ */
{0x20,0x20,0x20},/*¦31¦SP 20
-- ----- ¦AAZAA ¦YYBBBYB 1D ¦ */
{0x03,0x03,0x03},/*¦32¦RUS
00 -- ----- ¦AAAAA ¦YBYBYBB 2B ¦ */
2. Программа nbdp.c
Содержит функции для работы с протоколом
NBDP, а также объявление всех глобальных переменных
используемых в обмене данными по протоколу NBDP.
#include <nbdp.h>
#include <drivers.h>
#include <string.h>
#include <ctype.h>
#include <template.h>
/*-------------------------------------------------------------*/
UINT No; /* Channel No */
UCHAR COMF; /* COMMUNICATION FLAG */
/* b0 : 0=stanby 1=communication */
/* b1 : 1=ARQ Mode */
/* b2 : 1=CFEC Mode */
/* b3 : 1=SFEC Mode */
/* b4 : 1=GFEC Mode */
/* b5 : 0=send 1=recv */
/* b6 : 1 = SLAVE wait PHASING, 0 = SLAVE PHASED */
/* b7 : */
UCHAR STATE; /* COMMUNICATION STATE */
UCHAR LAST_STATE;
/* FEC ARQ */
/* 0 stand-by stand-by */
/* 1 set receive mode send before process */
/* 2 syncro signal rx receive before process */
/* 3 FEC msg rcv 7id-phasing-master */
/* 4 Synchronous signal send 7id-rephasing-master */
/* 5 ID send 4id-phasing-master */
/* 6 FEC msg send 4id-rephasing-master */
/* 7 stop signal send 7id-phasing-slave */
/* 8 7id-rephasing-slave */
/* 9 4id-phasing-slave */
/* 10 4id-rephasing-slave */
/* 11 iss */
/* 12 irs */
UCHAR arqf; /* ARQ flag */
/* b0 : 0 = slave, 1=master */
/* b1 : 1 = WRU */
/* b2 : 1 = OVER FLAG */
/* b3 : */
/* b4 : */
UCHAR SelfTest;
UCHAR FirstIdleBlock;
UCHAR SendFCCInfo;
UCHAR IDLEAcnt; /* IDLE ALFA counter for FEC */
UINT RxErr,RxOK; /* Received Err and OK symbol */
UCHAR SHIFT; /* LET=0,FIG=1,RUS=2 */
/*UCHAR PTT;*/ /* -BK intenal bit */
UCHAR WRU_SUPPORT=1;
UCHAR DX[5]; /* INPUT DX LINE FOR FEC */
UCHAR RX[5]; /* INPUT RX LINE FOR FEC */
UCHAR ID_IN[7]; /* INPUT SFEC ID SHIFT REG */
UCHAR SFSIS4[4]; /* SFEC self identification signal
for 4-digit ID */
UCHAR SFSIS5[4]; /* SFEC self identification signal
for 5-digit ID */
UCHAR SFSIS9[7]; /* SFEC self identification signal
for 9-digit ID */
UCHAR SCID[7]; /* SFEC called station ID */
UINT n[10]; /* ARQ(and other) supervisor counters */
UCHAR connector;
UCHAR CB[3][3]; /* CALLING BLOCK DURING SLAVE
PHASING */
/* AND FOR CALL DURING ARQ MASTER */
UCHAR CIB[3][3]; /* CALLER ID BLOCK FOR 7-digit
SLAVE SYNC */
UCHAR CCS[3]; /* CS DURING ARQ MASTER CALL */
/* AND DURING SLAVE PHASING */
UCHAR CKERR; /* CK errors during phasing */
/*UCHAR RCB[3][3];*/ /* REPHASING: CALLING BLOCK
DURING SLAVE REPHASING */
UCHAR RDATA[3]; /* RECEIVE DATA BLOCK */
UCHAR SLICE_BUF[2];
UCHAR LAST_CS;
UCHAR LAST_BLOCK[3];/* last sended block */
UCHAR LAST_BL_NO;
UCHAR LAST_ID[10]; /* last comm try ID */
UCHAR RQ; /* REPEAT REQUEST */
UCHAR RPTF; /* REPEAT FLAG */
UCHAR ID_TYPE; /* 4- or 7-DIGIT ID TYPE. 0-4,1-7 */
UCHAR WRU_CNT; /* MULTIPLE WRU REQUST COUNT */
UCHAR strAAB[21]; /* not converted AAB */
UCHAR AAB[AAB_LEN];/* converted AAB */
UCHAR SIS4[6]; /* self id signal for 4-digit ID */
UCHAR SIS5[6]; /* self id signal for 5-digit ID */
UCHAR SIS9[9]; /* self id signal for 9-digit ID */
UCHAR SCS9[3]; /* self id check sum for 9-digit ID */
char o_shift=4; /* output shift */
char RQ3SIG [3] = "\x33\x33\x33"; /*
rq-rq-rq */
char B_A_B [3] = "\x66\x78\x66"; /* b-a-b */
char EOC_SIG[3] = "\x78\x78\x78"; /* a-a-a
*/
/*UCHAR PRE_KEY; */ /* PRE KEY IN MS (0..100) */
/*UCHAR POST_KEY;*/ /* POST KEY IN MS (0..100) */
UCHAR CFEC_RX=1; /* CFEC RECEIVING ON/OFF, default
ON */
UCHAR FEC_RATE=50; /* FEC ERROR RATE, default 50% */
UCHAR IN_CHNL =2; /* INPUT CHANNEL L/R, default
RIGHT */
UCHAR OUT_CHNL=1; /* OUTPUT CHANNEL L/R, default
LEFT */
UCHAR LAST_RX_CS = 0;
UCHAR LAST_RX_BLOCK = 0;
UCHAR after_rephase = 0;
extern int SlaveAnswerTime; /* Called mode answer
delay */
/*-------------------------------------------------------------*/
void
StandBy(void) // В алгоритме вызывается при ошибке
{
MODEM_STATE=5; /* state = 5 - RESET */
COMF = STATE = SHIFT = RxErr = RxOK = /*RQ = RPTF =
*/ 0;
LAST_STATE = 0;
IDLEAcnt = 0;
connector = 0;
/*memset(DX,0,5);memset(RX,0,5);*/
FirstIdleBlock = 0;
SendFCCInfo = 0;
arqf = 0;
LAST_CS = 0;
o_shift = 4; /* output shift not defined */
WRU_SUPPORT=1; /* Set default as ON */
hiClear();
hoClear();
Clear();
doClear();
if(dip_sw & DIP_SW3)
{
if(SlaveAnswerTime != (21+2))
{
SlaveAnswerTime = 21+2; /* Called mode answer delay 20
ms */
goto inform_host;
}
}
else
{
if(SlaveAnswerTime != (21+5))
{
SlaveAnswerTime = 21+5; /* Called mode answer delay 50
ms */
inform_host:
SendCommandHostDBG(1,"CHANGE SLAVE ANSWER TIME
[%X0 msec]",SlaveAnswerTime-21);
}
}
send_stat();
/*FS[0] = 1;*/ /* restart FREE SIGNAL */
SendCommandHostDBG(1,"STAND BY");
}
/*-------------------------------------------------------------*/
void send_stat(void) /* Послать
статус
устройства
в
host-компьютер
*/
{
/*
SendCommandHost("STAT","%02X;%02X;%02X;%03X;%02X;%02X",
COMF,STATE,arqf,hiIFree,hi_count,connector);
*/
SendCommandHost("STAT","%02X;%02X;%02X;%03X;%02X;%X;%X",
COMF,STATE,arqf,hiIFree,hi_count,MODEM_STATE,connector);
}
/*-------------------------------------------------------------*/
/*-------------------------------------------------------------*/
/* Mode */
/* 0 - ARQ */
/* 1 - CFEC */
/* 2 - SFEC */
/*-------------------------------------------------------------*/
UCHAR convert(char ch) // Конвертер
в
NBDP
{
if(ch == ERR_SMBL) return ERR_SMBL;
{
int index = table2[(int) ch];
if(index)
{
struct CVT *cvt;
cvt = &CVT_TABLE[index-1];
switch(SHIFT)
{
case 0: return cvt->_LET;
case 1: return cvt->_FIG;
case 2: return cvt->_RUS;
}
}
}
return ERR_SMBL;
}
/*-------------------------------------------------------------*/
void NBDP_Init(void) // Инициализация
NBDP (вызывается
из
main.c)
{
SetID(1,"32610",SIS5,NULL,1);
SetID(2,"123456789",SIS9,SCS9,1);
strcpy(SIS9,"\x2e\x33\x65\x33\x27\x39\x2e\x71\x69");
strcpy(SCS9,"\x17\x4e\x69");
/*-------------------------------------------------------------*/
StandBy();
}
3. Программа serial.c
Содержит
функции для работы с последовательным портом.
#include <stdarg.h>
#include <string.h>
#include <drivers.h>
/*-------------------------------------------------------------*/
#define MAX_CMD_LEN 127
unsigned int CMDS, /* command rx state */
CMDL; /* command rx pointer */
char CMD[MAX_CMD_LEN+1]; /* command rx buffer */
/*-------------------------------------------------------------*/
int
chr;
int
SerialDriver(void) // проверка работы и инициализация последоват. порта
{
/*int chr;*/
repeat:
if(get_char(&chr))
{
if(CMDS) /* command receiving */
{
if(CMDL>=MAX_CMD_LEN)
{
SendHostError(0,0);
reset_state:
CMDL=CMDS=0;
return 0;
}
if((CMD[CMDL-1] == ';') && (chr == '@')) /*
EOC */
{
CMD[CMDL++] = chr;
CMD[CMDL] = 0;
HostCommandParser(&CMD[0]);
goto reset_state;
}
else
{
CMD[CMDL++] = chr;
goto repeat;
return 0;
}
}
else /* command waiting */
{
if(chr=='$')
{
CMDL=0;
CMD[CMDL++] = chr;
CMDS=1;
goto repeat;
}
}
}
return 0;
}
/*-------------------------------------------------------------*/
extern unsigned int No;
char BUFFER[MAX_CMD_LEN+1];
int SendCommandHost(char *cmd, char *fmt,...) // функция
для
передачи
// команд
в
терминал
{
/* Make data string to out */
/*int len;*/
va_list argptr;
/* Out the packet header: $CMD;channel_no; */
out_char('$');
out_string(cmd/*,strlen(cmd)*/);
out_char(';');
out_char(No + 0x30);
out_char(';');
/* Out the variable part */
va_start(argptr, fmt);
/*len =*/ vprinter(&BUFFER[0], fmt, argptr);
va_end(argptr);
out_string(BUFFER/*,len*/);
/* Out the end part of packet */
out_string(";@\r\n"/*,4*/);
return 0;
}
/*-------------------------------------------------------------*/
int SendCommandHostDBG(int level, char *fmt,...)
{
/* Make data string to out */
/*int len;*/
va_list argptr;
if(!(dip_sw & DIP_SW4)) return 0; /* not output
debug */
if(level > DebugLevel) return 0;
/* Out the packet header: $CMD;channel_no; */
out_string("$DBG;"); out_char(No + 0x30);
out_char(';');
/* Out the variable part */
va_start(argptr, fmt);
vprinter(&BUFFER[0], fmt, argptr);
va_end(argptr);
out_string(BUFFER);
/* Out the end part of packet */
out_string(";@\r\n");
return 0;
}
Критичные
по быстродействию функции выполняем на языке ассемблер под ADSP
2181.
Sin.dsp
Функции разложения на синус и косинус
используемые при модуляции и демодуляции для вычисления "налету".
.MODULE/RAM _SIN_COS_INTEGER_;
{---------------------------------------------------------------
Sine/Cosine approximation for 1.15 format
int Y = sin_i(int X)
int Y = cos_i(int X)
---------------------------------------------------------------
---------------------------------------------------------------
Calling parameters
AR = X in scaled 1.15 format
M1 = 1
L1 = 0
Return values
AR = X in 1.15 format
Computation time
sin : 30 + (3) cycles
cosine: 32 + (3) cycles
---------------------------------------------------------------
}
.VAR/DM sin_coeff[5];
.INIT sin_coeff : 0x3240, 0x0053, 0xAACC, 0x08B7,
0x1CCE;
.ENTRY sin_i_;
.ENTRY cos_i_;
cos_i_:
AY1 = 0x4000; { AY0 = PI/2 }
AR = AR + AY1; { AR = X+PI/2 }
sin_i_:
SI = AR; { save AR }
I1 = ^sin_coeff; {ptr to coeff buffer }
AY1=0x4000;
AF=AR AND AY1; {check 2nd or 4th quad.}
IF NE AR=-AR; {If yes negate input }
AY1=0x7FFF;
AR = AR AND AY1; {remove sign bit }
MY1=AR;
/*#ifndef GLOBAL_F*/
SR1 = MSTAT; { save MSTAT }
DIS M_MODE; { set fractional }
/*#endif*/
SR0 = MX1; {save MX1 }
MF=AR*MY1 (RND), MX1=DM(I1,M1); {MF = X^2 }
MR=MX1*MY1 (SS) , MX1=DM(I1,M1); {MR = C1*X }
CNTR=3;
DO approx UNTIL CE;
MR=MR+MX1*MF (SS);
approx: MF=AR*MF (RND), MX1=DM(I1,M1);
MR=MR+MX1*MF (SS);
MX1 = SR0; { restore MX1 }
/*#ifndef GLOBAL_F*/
MSTAT = SR1; { restore MSTAT }
/*#endif*/
SR=ASHIFT MR1 BY 3 (HI);
SR=SR OR LSHIFT MR0 BY 3 (LO); {convert to 1.15
format}
AR=PASS SR1;
IF LT AR=PASS AY1; {saturate if needed }
AY1=SI;
AF=PASS AY1;
IF LT AR=-AR;
RTS;
.ENDMOD;
Программа 2181_hdr.dsp
Содержит код инициализации ADSP 2181.
.MODULE/ABS=0 ADSP2181_Runtime_Header;
#define
_MY_HANDLER 1
//
объявление внешних функций Си для использования их в ассемблере
.EXTERNAL ___lib_setup_everything;
.EXTERNAL main_;
#ifndef _MY_HANDLER
.EXTERNAL ___lib_sp0r_ctrl;
#endif
.EXTERNAL stat_flag_;
.EXTERNAL next_cmd_;
.EXTERNAL process_a_bit; { uart }
.EXTERNAL
IRQE_Flag_;
//
Установка векторов прерываний
//
По сбросу загружать функцию Си main
__Reset_vector: CALL ___lib_setup_everything;
CALL main_; RTS; NOP; {Begin C program}
__Interrupt2: rti;NOP;NOP;NOP;
__InterruptL1: rti;NOP;NOP;NOP;
__InterruptL0: rti;NOP;NOP;NOP;
__Sport0_trans: jump _sp0tx;nop;nop;nop;
#ifndef _MY_HANDLER
__Sport0_recv: JUMP ___lib_sp0r_ctrl;NOP;NOP;NOP;
#else
__Sport0_recv: JUMP _sp0rx;NOP;NOP;NOP;
#endif
__InterruptE: ena sec_reg; ar = 1;
dm(IRQE_Flag_)=ar; rti;
__BDMA_interrupt: rti;NOP;NOP;NOP;
#ifndef HW_UART
__Interrupt1: pop sts; /* 20: SPORT1 tx or IRQ1 */
ena timer; rts; rti;
#else
__Interrupt1: rti; /* 20: SPORT1 tx or IRQ1 */
rti; rti; rti;
#endif
__Interrupt0: rti;NOP;NOP;NOP;
__Timer_interrupt: jump process_a_bit; /* 28: timer
*/
rti; rti; rti;
__Powerdown_interrupt: rti;NOP;NOP;NOP;
#ifdef _MY_HANDLER
/*-------------------------------------------------------------
1) Enble sec reg bank
2) Save all unaltered registers
3) Setup stack, Run C-handler
4) Restore unaltered registers
5) disable sec reg bank
-------------------------------------------------------------*/
.var/dm REG_SAVE_SP0RX[11];
.external modulator_;
.external demodulator_;
_sp0rx:
//
сохранение регистров
dm(REG_SAVE_SP0RX
+ 0) = PX; /* 1 */
dm(REG_SAVE_SP0RX + 1) = L0; /* 2 */
dm(REG_SAVE_SP0RX + 2) = I1; /* 3 */
dm(REG_SAVE_SP0RX + 3) = L1; /* 4 */
dm(REG_SAVE_SP0RX + 4) = M2; /* 5 */
dm(REG_SAVE_SP0RX + 5) = M3; /* 6 */
dm(REG_SAVE_SP0RX + 6) = M5; /* 7 */
dm(REG_SAVE_SP0RX + 7) = L5; /* 8 */
dm(REG_SAVE_SP0RX + 8) = I6; /* 9 */
dm(REG_SAVE_SP0RX + 9) = M6; /* 10 */
dm(REG_SAVE_SP0RX + 10) = L6; /* 11 */
/* enable second register bank */
ena sec_reg;
/* set predefined INTR modes */
DIS BIT_REV, DIS AR_SAT, DIS AV_LATCH, ENA M_MODE;
L0=0;
L1=0;
L5=0;
L6=0;
M2=0;
M6=0;
/* restore unaltered registers */
PX = dm(REG_SAVE_SP0RX + 0)/* = PX*/; /* 1 */
L0 = dm(REG_SAVE_SP0RX + 1)/* = L0*/; /* 2 */
I1 = dm(REG_SAVE_SP0RX + 2)/* = I1*/; /* 3 */
L1 = dm(REG_SAVE_SP0RX + 3)/* = L1*/; /* 4 */
M2 = dm(REG_SAVE_SP0RX + 4)/* = M2*/; /* 5 */
M3 = dm(REG_SAVE_SP0RX + 5)/* = M3*/; /* 6 */
M5 = dm(REG_SAVE_SP0RX + 6)/* = M5*/; /* 7 */
L5 = dm(REG_SAVE_SP0RX + 7)/* = L5*/; /* 8 */
I6 = dm(REG_SAVE_SP0RX + 8)/* = I6*/; /* 9 */
M6 = dm(REG_SAVE_SP0RX + 9)/* = M6*/; /* 10 */
L6 = dm(REG_SAVE_SP0RX + 10)/* = L6*/; /* 11 */
rti;
#endif
.var/dm REG_SAVE_SP0TX[11];
_sp0tx:
/* enable second register bank */
ena sec_reg;
ar = dm(stat_flag_);
ar = pass ar;
if ne jump next_cmd_;
/* save unaltered registers */
dm(REG_SAVE_SP0TX + 0) = PX; /* 1 */
dm(REG_SAVE_SP0TX + 1) = L0; /* 2 */
dm(REG_SAVE_SP0TX + 2) = I1; /* 3 */
dm(REG_SAVE_SP0TX + 3) = L1; /* 4 */
dm(REG_SAVE_SP0TX + 4) = M2; /* 5 */
dm(REG_SAVE_SP0TX + 5) = M3; /* 6 */
dm(REG_SAVE_SP0TX + 6) = M5; /* 7 */
dm(REG_SAVE_SP0TX + 7) = L5; /* 8 */
dm(REG_SAVE_SP0TX + 8) = I6; /* 9 */
dm(REG_SAVE_SP0TX + 9) = M6; /* 10 */
dm(REG_SAVE_SP0TX + 10) = L6; /* 11 */
/* enable second register bank */
/*ena sec_reg;*/
/* set predefined INTR modes */
DIS BIT_REV, DIS AR_SAT, DIS AV_LATCH, ENA M_MODE;
L0=0;
L1=0;
L5=0;
L6=0;
M2=0;
M6=0;
call modulator_;
/* restore unaltered registers */
PX = dm(REG_SAVE_SP0TX + 0)/* = PX*/; /* 1 */
L0 = dm(REG_SAVE_SP0TX + 1)/* = L0*/; /* 2 */
I1 = dm(REG_SAVE_SP0TX + 2)/* = I1*/; /* 3 */
L1 = dm(REG_SAVE_SP0TX + 3)/* = L1*/; /* 4 */
M2 = dm(REG_SAVE_SP0TX + 4)/* = M2*/; /* 5 */
M3 = dm(REG_SAVE_SP0TX + 5)/* = M3*/; /* 6 */
M5 = dm(REG_SAVE_SP0TX + 6)/* = M5*/; /* 7 */
L5 = dm(REG_SAVE_SP0TX + 7)/* = L5*/; /* 8 */
I6 = dm(REG_SAVE_SP0TX + 8)/* = I6*/; /* 9 */
M6 = dm(REG_SAVE_SP0TX + 9)/* = M6*/; /* 10 */
L6 = dm(REG_SAVE_SP0TX + 10)/* = L6*/; /* 11 */
rti;
.ENDMOD;
|