
- •Введение в дсп.
- •Работа номер 1
- •9.Сдача работы:
- •If cond jump label;// условный переход
- •2.Показать как минимум две программы с разным темпом мигания от
- •Задание 2.5 - работа с таймером
- •Сдача задания 2.5: Задание – задать заметную на глаз частоту прерываний таймера
- •Задание 2.6 Использование таймера и прерывания от кнопки
- •Сдача задания 2.6: Задание – при нажатии на кнопку светодиод должен прекращать мигать, при повторном нажатии опять начинать мигать.
- •Сдача задания 3.1:
- •Сдача заданий 3.1.2 и 3.1.3:
- •If ne jump firstdac; // переход к пустому ацп Сдача задания 3.1.4:
- •Сдача задания 3.1.5:
- •1.Oб`ясните, почему нельзя использовать обычное сложение.
- •2.Почему инициализация регистров делается после вызова CodecInit ?
- •3.Почему запрещаются прерывания перед инициализацией регистров
- •If eq jump nofiltr; // если 0, не делаем фильтрацию
Сдача задания 3.1:
Показать сигнал на осциллографе.
Сравните входной сигнал с генератора и выходной сигнал на ЦАП при
разных частотах. Об`ясните результат.
Задание 3.1.2
.Выдать сигнал светодиода на каждые 0xFFFF отсчетов АЦП.
Задание 3.1.3
.Выдать сигнал светодиода на каждые N отсчетов АЦП. N должно быть
задано в файле
#define N 20000
Сдача заданий 3.1.2 и 3.1.3:
Показать зависимость частоты мерцания диода от частоты
генератора.
Задание 3.1.4
Вывести сигнал только в один из ЦАПов.
Заведите переменную count.
.var count;
Инициализируйте ее - занесите 0.
Далее в процедуре обработки переключайте один из битов этой
переменной и в зависимости от состояния бита отправляйте в ЦАП либо
сигнал, либо 0.
ax1=dm(count); // чтение
ar=tglbit 1 of ax1; // преключение бита с уставкой флагов
dm(count)=ar; // запись переменной
If ne jump firstdac; // переход к пустому ацп Сдача задания 3.1.4:
Показать сигналы от разных ЦАПов на осциллографе.
Задание 3.1.5
Вывести сигнал с АЦП в окно Debug window-Plot.
Создайте циклический буфер в секции seg_input.
Это самая большая секция в памяти данных
.section/dm seg_input;
.var/circ buf2[256];//модификатор circ обязателен для циклических буферов
До инициализации кодека иниациализируйте буфер:
l2=length(buf2); // длина буфера
m2=1; // инкремент для регистра I2
i2=buf2; // адрес начала
………..
dm(i2,m2)=…. // запись в буфер, после обращения i2=i2+m2;
Если теперь записывать сигнал с АЦП в буфер, то регистр I2 будет
циклически перебирать все ячейки буфера и при останове программы
содержимое буфера можно посмотреть в виде графика.
Запишите в буфер сигнал с одного АЦП и сохраните в виде файла gif или
jpg. Запишите в буфер тот же сигнал, но с обоих АЦП и сохраните в виде
файла gif или jpg.
Сдача задания 3.1.5:
Показать картинки от одного АЦП и от двух.
Сравните сигналы и об`ясните результат.
Задание 3.2
Цифровая фильтрация сигнала АЦП.
Имеющиеся компоненты для выполнения работы:
Файл codec.asm - файл с процедурами для работы с кодеком:
CodecStop
CodecInit
File 2189ezkit.ldf - файл для линкера - включить в Linker files.
Файл codec.asm надо включить в папку Sourse Files.
Необходимый вид секции обслуживания прерываний кодека (порта0):
.section/pm seg_rth;
….
JUMP SPORT0_tx; NOP; NOP; NOP; /*SPORT0_TX*/
JUMP SPORT0_rx; NOP; NOP; NOP; /*SPORT0_RX*/
….
Процедура SPORT0_tx определена в файле codec.asm и используется для
инициализации кодека.
Процедура SPORT0_rx используется для пересылки данных из АЦП в ЦАП и пишется студентом. В процедуре обработки прерывания используйте второй набор регистров.
Простейший вид цифровой фильтрации - усреднение на заданном интервале. Сигнал АЦП записывается в циклический буфер, все числа в буфере складываются, сумма делится на число чисел в буфере. Результат есть отфильтрованное значение сигнала.
Для операций суммирования в ДСП есть сумматор-умножитель, который делает умножение с суммированием. Для наших целей необходимо только суммирование.
Ниже показан пример суммирования чисел в буфере buf0, длина буфера определена через #define как buflen.
L1=0; // инициализация буфера для суммировния
M1=1; // инкремент
I1=buf0; // адрес
mr0=0; // регистры умножителя -сумматора mr0,mr1
mr1=0; // зануляем регистры
my0=1; // умножаем на 1 - надо только сумму
cntr=buflen;
do ka2 until ce;
mx0=dm(I1,M1); // число из буфера
ka2: mr=mr+mx0*my0(ss); // mr0,mr1 - сумма,(ss) - оба операнда signed
//integer
Суммирование 32 битное, результат в 2-х регистрах, в отличие от обычной операции сложения типа AR=AX0+AY0;
Результат суммирования надо разделить на buflen. Операция деления в ДСП в явном виде отсутствует, есть только некие элементарные операции, позволяющие более просто реализовать алгоритм деления через вычитание. Поэтому задача слегка упрощена – разрешаем в качестве buflen только степени двойки и деление делаем через операцию сдвига. Сдвиговый регистр ДСП - это регистры результата SR0,SR1 и регистр SE, задающий сдвиг. Определяем shift как степень, в которую надо возвести двойку, чтобы получить buflen.
#define shift -3; // buflen = 8, сдвиг вправо - отрицательное число
SE=shift; // задание сдвига в регистре SE
SR = ASHIFT MR1 (HI); // сдвигаем регистр МR1 на величину в SE
// (HI) - сдвиг через старшие биты (SR1)
SI = mr0; // SI - регистр-источник для устройства сдвига
SR = SR OR LSHIFT SI (LO); // сдвигаем младшие биты и делаем OR с
//результатом сдвига старших бит
ax0=sr0; // результат сдвига (деления на 8) помещаем в AX0
Программа должна включать в себя следующее:
1.Задать три циклических буфера
буфер 0 - для суммирования
буфер 1 - для вывода в Debug window данных с АЦП
буфер 2 - для вывода в Debug window данных после фильтра
2.Инициализация кодека: CodecInit.
3. Запретить прерывания.
Инициализировать регистры для записи в буфера.
l3=length(buf3);
m3=1;
i3=buf3;
Рекомендуется использовать I0,M0,L0 для записи в буфер 0
I3,M3,L3 для суммирования буфера 0
Рекомендуется использовать I1,M1,L1 для записи в буфер 1
I2,M2,L2 для записи в буфер 2
Не забудьте разрешить прерывания после инициализации регистров.
4.Бесконечный цикл.
3.Процедура обработки прерывания Sport0_RX. Эта процедура должна:
a) принимать данные от АЦП
б) разделять данные от 1 и 2 АЦП
в) складывать данные от 1 АЦП в буфер 1
г) фильтровать эти данные
д) складывать отфильтрованные данные в буфер 2
е) пересылать отфильтрованные данные в один из ЦАПов
засылать 0 в другой ЦАП.
Задайте вывод в Debug Window-Plot двух буферов на одном графике. Для этого надо задать один буфер, нажать ADD, затем задать второй буфер и опять нажать ADD. В Plot Settings-Style задайте разные цвета для отображения содержимого буферов. Щелкните правой кнопкой мыши на графике и переключите состояние переключателя Allow Docking. Это позволит поместить окно Debug Window поверх всех и увеличить его размер. Там же можно поменять параметры окна вывода. При наличии осциллографа можно смотреть отфильтрованные данные на экране осциллографа.
Если программа написана правильно, то после останова программы в окне графиков вы увидите два сигнала - после АЦП и отфильтрованный. Выглядеть это должно примерно так.
Так как буфера циклические, а останов несинхронизован, картинки могут быть искажены. Сравните исходный и фильтрованный сигнал при разной степени фильтрации.
Сдача задания 3.2.1:
Запишите картинки, покажите. Об`ясните результат.
Вопросы: