лр / ТСАиУ Лабораторная работа №3 Задание 2024
.pdfЛабораторная работа №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.
