Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лр / ТСАиУ Лабораторная работа №3 Задание 2024

.pdf
Скачиваний:
0
Добавлен:
21.12.2025
Размер:
1.21 Mб
Скачать

Лабораторная работа №3 «Обмен данными между ЭВМ и

внешними устройствами с заданной частотой дискретизации»

Задание № 1 Вывод данных с прерыванием текущей программы процессора

1. Разработать программу генерации произвольного числа периодов периодического аналогового сигнала с заданными амплитудными характеристиками и периодом квантования (указываются преподавателем из таблицы 2.1.). Для минимизации времени работы программы обработки прерывания следует до начала эксперимента рассчитать мгновенные значения сигнала на интервале равном одному периоду.

Варианты заданий

 

 

 

Таблица 2.1

 

 

 

 

 

 

Вид сигнала, U(i)

Амплитуда, Umax.

Число точек на

Период

варианта

 

 

 

[В]

периоде, М

квантования

 

 

 

 

сигнала, мкс

 

 

 

 

 

 

 

 

 

 

 

 

 

1

U маxsin2 i/M,

 

0 i M

4,5

200

300

 

 

 

 

 

 

2

2Umaxi/M ,

0 i M/2

4,0

200

280

 

2Umax(1-i/M ), M/2 i M

 

 

 

 

 

 

 

 

 

3

Umax ,

0 i 3/4M

5,0

100

200

 

0,

3/4M i M

 

 

 

 

 

 

 

 

 

4

2Umaxi/M ,

0 i M/2

4,0

200

320

 

-2Umax(1-i/M ), M/2 i M

 

 

 

 

 

 

 

 

 

5

Umax ,

0 i M/2

4,0

100

240

 

-Umax,

M/2 i M

 

 

 

 

 

 

 

 

 

6

Umaxexp(-2i/M) ,

0 i M

5,0

100

220

 

 

 

 

 

 

7

U маx/sin2 i/M,

0 i M

4,0

200

260

 

 

 

 

 

 

8

2Umaxi/M ,

0 i M/2

2,5

100

250

 

2Umax(1-i/M ), M/2 i M

 

 

 

 

 

 

 

 

 

 

2. Соединить выход ЦАП с входом осциллографа и с помощью осциллографа проконтролировать соответствие установленных амплитудных характеристик сигнала и наблюдаемых значений. Определить интервал вывода отдельных значений T и частоту генерируемого сигнала f. Убедиться, что сигнал выводится с заданным периодом квантования.

Задание № 2 Ввод данных с прерыванием текущей программы процессора

1. Разработать программу, осуществляющую:

a) ввода в реальном времени массива данных из модуля АЦП в ОЗУ ЭВМ с прерыванием фоновой программы от таймера L-154 (период дискретизации сигнала и канал мультиплексора указаны в таблице 2.2);

б) преобразования значений кодов АЦП в значения напряжения UКВ по окончании ввода всего массива; в) вывода массива исходных данных в файл.

Сигнал подключается с помощью ассиметричной схемы измерения аналоговых сигналов. Измерения проводятся на 1000 точках.

Варианты заданий

Таблица 2.2

 

 

 

 

 

 

 

Диапазон

Вид, амплитуда (если есть) и

Канал

 

Период

варианта

сигналов ЦАП,

частота измеряемого сигнала

АЦП

 

квантования

 

 

 

сигнала, мкс

 

[В]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

5,0

Меандр

1

 

440

 

 

частота 500Гц

 

 

 

 

 

 

 

 

 

2

2,5

Синусоидальный,

2

 

400

 

 

амплитуда 1.2В, частота 900Гц

 

 

 

 

 

 

 

 

 

3

1,0

Треугольный

3

 

380

 

 

амплитуда 1В, частота 600Гц

 

 

 

 

 

 

 

 

 

4

2,5

Синусоидальный,

4

 

340

 

 

амплитуда 1.5В, частота 700Гц

 

 

 

 

 

 

 

 

 

5

2,0

Треугольный

5

 

300

 

 

амплитуда 1.5В, частота 400Гц

 

 

 

 

 

 

 

 

 

6

1,0

Синусоидальный,

6

 

280

 

 

амплитуда 1В, частота 500Гц

 

 

 

 

 

 

 

 

 

7

5,0

Меандр

2

200

 

 

частота 1200Гц

 

 

 

 

 

 

 

8

2,0

Синусоидальный,

1

320

 

 

амплитуда 1.3В, частота 800Гц

 

 

 

 

 

 

 

2.Соединить соответствующий выход генератора с осциллографом. Установить на выходе генератора вид, амплитуду и частоту сигнала согласно таблице 2.2.

3.Соединить соответствующий выход генератора с нужным каналом АЦП.

4.С помощью разработанной программы провести регистрацию сигнала с генератора. Убедиться, что данные были получены.

5.По снятым данным в отчете построить график измеренного сигнала от времени.

Задание № 3

Ввод данных с определенной частотой с помощью таймера IBM PC

1. Разработать программу, осуществляющую:

a) ввода в реальном времени массива данных из модуля АЦП в ОЗУ ЭВМ с запуском измерений по таймеру Intel 8254 ЭВМ;

б) преобразования значений кодов АЦП в значения напряжения UКВ по окончании ввода всего массива; в) вывод массива снятых данных в файл.

Параметры регистрации и сигала необходимо взять такие же как в задании 2.

2. В отчете сравнить результаты регистрации с заданием 2.

Примеры программ

Задание 1. Вывод сигнала на выход ЦАП:

В примере рассмотрена генерация сигнала вида амплитудой 5В и с числом точек на периоде равным 100 и интервалом дискретизации равным 400 микросекунд.

Аналогично с лабораторной работой №1 рассчитываем цифровое значение амплитуды:

0В это 2048.

Рассчитываем значение для 5В

UDAC = U (n - 2048), где U =2,5 мВ

Откуда n= UDAC/ U+2048= 5/0.0025+2048=4048

Нас интересует именно прирост относительно 0, в данном случае он составляет 2000.

Программа на Turbo Pascal для задания №1:

Uses Dos, crt;

const M=100; T=400;

var

U:array[0..M] of integer;

OldIntB:pointer; i,count: integer;

Procedure IntDAC; interrupt;

{Ключевое слово Interrupt приводит к генерации машинных команд,

обеспечивающих сохранение в стеке всех регистров процессора при входе в процедуру IntADC и извлечение их из стека перед выходом из нее.}

Begin

asm STI end;{ Установка IF=1 в регистре флагов ЦП. }

PortW[$300]:=U[count];{Вывод в ЦАП очередного значения.}

inc(count); {Инкремент программного счетчика. }

if count > M then count:=1; {Проверка текущего значения программного счетчика count}

if keypressed then Port [$21]:=Port [$21] or $8; {Запрет прерываний от входа IR3 если нажата любая клавиша}

Port[$20]:=$20;{ IS3=0 Сброс бита регистра ISR OCW2. }

End;

Procedure SetTime(T:word);{Процедура установки таймера L-154 для формирования прерываний с заданным интервалом}

var N1, N2: word;

Begin

if (T >= 10)

then

begin

Port[$30B]:=$36; {1 канал в режиме меандр, константа пересчета 2 байта}

Port[$30B]:=$56; {2 канал в режиме меандр, константа пересчета 1 младший байт}

N2:=10; N1:= T div N2;

Port[$308]:=Lo(N1);Port[$308]:=Hi(N1);

Port[$309]:=Lo(N2);

end

else writeln ('The parameter NOT in range!');

end;

Begin

{ Основная программа.}

Port [$30F]:= 0; {Запретили генерацию прерываний на плате.}

Port[$21]:=Port[$21] OR $8;{Запрещены прерывания от вх IR3.}

for i:=1 to M do U[i]:=Round(2048+2000*sqr(sin(2*pi*i/M)));

{Сформирован массив данных синусоидального сигнала на интервале одного периода}

GetIntVec($B,OldIntB); {Сохранение старого вектора прерывания от входа IR3 в переменной OldIntD.}

SetIntVec($B,@IntDAC); {Установили новый вектор прерывания от IR3 на процедуру IntADC}

SetTime(T); {Запуск таймера}

Port[$30F]:=1; {Разрешены прерывания от таймера.}

Port[$21]:=Port[$21] AND (NOT ($8)); {Разрешены прерывания от

IR3 в регистре IMR контроллера прерываний.}

count:=1;

while not keypressed do; {Здесь должна быть фоновая программа, которая будет выполняться совместно с программой вывода данных на ЦАП модуля, но в нашем случае ее нет, поэтому цикл пустой.}

while keypressed do readkey;

Port [$30F]:= 0; {Снова запретили генерацию прерываний на плате.}

SetIntVec($B,OldIntB);{Восстановление старого вектора прерываний от IR3.}

end.

Программа на Borland С++ для задания №1:

#include <math.h>

#include <dos.h>

const int M=100, T=400;

int U[M];

int count=0,count2=0;

void interrupt IntDAC(...) //Оперативная программа обслуживания прерываний

{

asm sti; //Установка IF=1 в регистре флагов ЦП.

outpw(0x300,U[count]); //Вывод в ЦАП очередного значения.

count++; //Инкремент программного счетчика.

if(count==М){count=0;count2++;} //Проверка текущего значения программного счетчика count с его сброс при достижении конца массива.

outp(0x20,0x20); //IS3=0 Сброс бита регистра ISR OCW2.

}

int SetTime(int Time)//Установка таймера на L-154

{

if (T>=10)

{

outp(0x30B,0x36); //1 канал в режиме меандр, константа пересчета 2 байта

outp(0x30B,0x56); //2 канал в режиме меандр, константа пересчета 1 младший байт

Time=Time/10;

outp(0x308,Time%256);outp(0x308,Time/256); //Вывод старшего и младшего байтов константы пересчета таймера канала 0

outp(0x309,10); //Вывод младшего байта константы пересчета таймера канала 0

}

return 0;

}

int main()

{

void (interrupt far *oldvect)(...);//Переменная oldvect для хранения старого вектора прерывания

outp(0x30F,0);//Запретили генерацию прерываний на плате

outp(0x21,inp(0x21) | 0x8);// Запрещены прерывания от вх

IR3.

oldvect=getvect(0xB);// Сохранение старого вектора прерывания от входа IR3 в переменной

setvect(0xB,IntDAC); // Установили новый вектор прерывания от IR3 на процедуру IntADC

for(int i=0;i<M;i++)

U[i]=floor(2048+2000*pow(sin(2*M_PI*i/M),2));

//Сформирован массив значений синусоидального сигнала в квадрате на интервале одного периода, round в Borland C++ 2.0 нет, используем floor для округления до целого

SetTime(T); //Запуск таймера на L-154

outp(0x30F,1); //Разрешены прерывания от таймера

outp(0x21,inp(0x21) & (!0x8));// Разрешены прерывания от IR3

в регистре IMR контроллера прерываний

while(count2<1000); //Организуем цикл на 1000 периодов сигнала, по идее здесь нужно написать код фоновой программы, но ее у нас нет и цикл пустой.

outp(0x30F,0);//Снова запретили генерацию прерываний на плате

setvect(0xB, oldvect); //Восстановили старый вектор прерывания

return 0;

}

Задание 2. Регистрация сигнала со входа АЦП:

В примере рассмотрена фиксация сигнала 5,12 В по первому каналу с интервалом 400 микросекунд. Методика регистрации входных сигналов была рассмотрена в лабораторной работе №1.

Для того, чтобы корректно вычислить математическое ожидание и дисперсию измеряемого сигнала необходимо отсечь от выборки не полностью снятые периоды в начале и конце массива измерений. Методика отсечки измерений зависит от вида измеряемого сигнала. В любом случае нужно будет рассматривать значения сигнала с точностью не более сотых вольта, поскольку сигнал измеряется с шумами.

Программа на Turbo Pascal для задания №2:

Uses Dos, crt;

const: M = 1000; T=400;

var

Uvx: array [1..M] of integer; {Объявление массива для хранения снятых данных}

Ureal: real; {Переменная для расчета значений сигнала в вольтах}

OldIntB: pointer; i, count:integer; f:text;

s:string; {строковая переменная для записи в файл}

Procedure wait(i:word); var j:word;

begin for j:=1 to i do asm nop end; end;

Procedure IntDAC; interrupt;

{Оперативная программа обслуживания прерываний.}

Begin {Старт оперативной программы}

asm STI end;{Установка IF=1 в регистре флагов ЦП} Port[$304]:=$FF; {Запуск АЦП на измерение}

asm NOP end;

while (Port[$302]>=$F8) do ; {Проверка окончания измерения.}

Uvx[count]:=PortW[$300] {Считываем очередное значение} inc(count); {Инкремент программного счетчика}

if count>M then Port [$21]:=Port [$21] or $8; {Запрет прерываний от входа IR3, если значение count больше конечного значения М}.

Port[$20]:=$20;{IS3=0 Сброс бита регистра ISR – OCW2} End; {Конец оперативной программы}

Procedure SetTime(T:word);{Процедура установки таймера L-154 для формирования прерываний с заданным интервалом}

var N1, N2: word;

Begin

if (T >= 10)

then

begin

Port[$30B]:=$36; {1 канал в режиме меандр, константа пересчета 2 байта}

Port[$30B]:=$56; {2 канал в режиме меандр, константа пересчета 1 младший байт}

N2:=10; N1:= T div N2;

Port[$308]:=Lo(N1);Port[$308]:=Hi(N1);

Port[$309]:=Lo(N2);

end

else writeln ('The parameter NOT in range!');

end;

Begin { Основная программа.}

Port [$30F]:= 0; Port[$21]:=Port[$21] OR $8;

Port[$302]:=$E0;

{Устанавливаем канал и режим измерения АЦП}

wait(?); {Задержка на переключение, из ЛР2 }

GetIntVec($B,OldIntB); SetIntVec($B,@IntDAC); SetTime(T);

Port[$30F]:=1; Port[$21]:=Port[$21] AND (NOT ($8));

while count<=M do; {Здесь должна быть фоновая программа, которая будет выполняться совместно с программой ввода данных c АЦП модуля}

{Вывод в файл}

assign(f, 'c:\LR2INT.txt'); rewrite(f);

for i:=1 to M do begin

Ureal:=2.5*(Uvx[i]-2048)/1000; {Расчет измеренных

значений в вольтах}

str(Ureal:4:2,s);

writeln(f,s);

end;

Port [$30F]:= 0; SetIntVec($B,OldIntB);

end.