лр / ТСАиУ Лабораторная работа №3 Задание 2024
.pdfПрограмма на Borland С++ для задания №2:
#include <dos.h> #include <stdio.h>
const int M=1000, T=400;
int U[M];
int count=0;
void interrupt IntDAC(...)
{
asm sti; //Установка IF=1 в регистре флагов ЦП.
outp(0x304,0xFF); //Запуск АЦП на измерение
asm nop; //Задержка на 1 команду ЦП, чтобы АЦП успел запуститься
while (inp(0x302)>=0xF8); //Проверка окончания измерения, inp
считывает один байт из регистра, старшие биты регистра состояния всегда равны 1111, то есть F, нас интересует 3 бит, из младших, если младшие равны 1000 это 8, если младшие равны 0111, то это 7 U[count]=inpw(0x300);//Заносим результат измерения в массив,
inpw считывает два байта из регистра
count++; //Инкремент программного счетчика.
outp(0x20,0x20); //IS3=0 Сброс бита регистра ISR OCW2.
}
int SetTime(int Time)
{
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 wait(long count)
{
for(int i=0;i<count;i++) asm nop;
return 0;
}
int main()
{
float Uvx; //переменная для расчета входного значения в волтах
void (interrupt far *oldvect)(...);
outp(0x302,0xE0); //Устанавливаем РУ, команда outp записывает один байт
wait(?);//Задержка на переключение мультиплексора из ЛР2
outp(0x30F,0);
outp(0x21,inp(0x21) | 0x8);
oldvect=getvect(0xB);
setvect(0xB,IntDAC);
SetTime(T);
outp(0x30F,1);
outp(0x21,inp(0x21) & (!0x8));
while count<=M; {Здесь должна быть фоновая программа, которая будет выполняться совместно с программой ввода данных c АЦП модуля}
outp(0x30F,0);
setvect(0xB, oldvect);
FILE *f; //Объявляем файл для записи результатов f=fopen("c:\\LR2INT.txt","w"); // Создаем/перезаписываем
файл
char str[5]; //объявляем строковую переменную длинной 5 символов
for(int i=0;i<M;i++)
{
Uvx=(U[i]-2048)*0.0025; //Переводим измерение в вольты sprintf(str,"%f",Uvx); //Переводим в вещественное число
в строку
fputs(str,f); // Записываем строку в файл fputc('\n',f); //Переводим файл на новую строку
}
fclose(f); //Закрываем файл return 0;
}
Задание 3. Регистрация сигнала со входа АЦП с заданным периодом квантования по таймеру ЭВМ:
В примере рассмотрена фиксация сигнала 5,12 В по первому каналу с интервалом 400 микросекунд.
Для получения константы пересчета нужно частоту на входе CLK таймера разделить на требуемую частоту вывода сигнала.
Частота выводимого сигнала:
F=1/ 400 мкс
Рассчитываем константу пересчета:
N = 1193182/(1/0.0004)= 1193182*0,0004= 477,2728 ~477=$1DD
Старший байт: $01, младший байт: $DD
Программа на Turbo Pascal для задания №3:
uses crt;
const M=1000;
var
i:word;
U: array [1..M] of integer;
Ureal:real;
f:text;
Procedure wait(i:word); var j:word;
begin for j:=1 to i do asm nop end; end;
Begin
Port[$302]:=$E0;
wait(?);
{Устанавливаем режим работы таймера и константу пересчета}
Port[$61]:= Port[$61] and not 3; {Сброс в 0 сигнала на входе
GATE2, выход OUT2 отключаем от динамика через управляющий регистр с адресом 61h}
Port[$43]:= $B6; {Установка режима работы канала 2: 10 — канал 2 + 11 – запись (чтение) младшего, затем старшего байта
+011 – (режим 3 – меандр)
+0 — двоичный формат счета счетного элемента.}
Port[$42]:= $DD; {запись младшего байта константы пересчета}
Port[$42]:= $01; {запись старшего байта константы пересчета}
Port [$61] := Port [$61] or 1; {Запускаем таймер}
for i:=1 to M do begin
while (Port[$61] AND $20) <> 0 do; {пропускаем первый полупериод меандра}
while (Port[$61] AND $20) = 0 do; {пропускаем второй полупериод меандра}
Port[$304]:=$FF; {Запуск АЦП на измерение} asm NOP end;
while (Port[$302]>=$F8) do; {Ждем завершения измерения} U[i]:=PortW[$300];{Фиксируем результат в массиве}
end;
{Выводим результаты в файл} assign(f, 'c:\LR3TMR.txt'); rewrite(f);
for i:=1 to M do begin Ureal:=(U[i]-2048)*0.0025; writeln(f,Ureal:4:2);
end;
close(f);
end.
Программа на Borland С++ для задания №3:
#include <dos.h> #include <stdio.h>
int wait(int count)
{
for(int i=0;i<count;i++) asm nop;
return 0;
}
int main()
{
const int M=1000; //Количество регистрируемых с АЦП значений int U[M]; //Объявление массива для хранения снятых данных float Uvx; //переменная для расчета входного значения в волтах outp(0x302,0xE0); //Устанавливаем РУ, команда outp записывает
один байт
wait(?);
outp(0x61,inp(0x61)&(!0x3)); // Сброс в 0 сигнала на входе
GATE2, выход OUT2 отключаем от динамика через управляющий регистр с адресом 61h
outp(0x43,0xB6); // Установка режима работы канала 2: //10 — канал 2 //+11 – запись (чтение) младшего, затем старшего байта
//+011 – (режим 3 – меандр)
//+0 — двоичный формат счета счетного элемента.
outp(0x42,0xDD); //запись младшего байта константы пересчета
outp(0x42,0x01); //запись старшего байта константы пересчета
outp(0x61,inp(0x61)|0x1); // Запускаем таймер
for(int i=0;i<M;i++)
{
while ((inp(0x61)&0x20)!=0); //пропускаем первый полупериод меандра
while ((inp(0x61)&0x20)==0); //пропускаем второй полупериод меандра
outp(0x304,0xFF); //Запуск АЦП на измерение
asm nop; //Задержка на 1 команду ЦП, чтобы АЦП успел запуститься
while (inp(0x302)>=0xF8); //Ждем завершения измерения U[i]=inpw(0x300); //Считываем значение
}
FILE *f; //Объявляем файл для записи результатов f=fopen("c:\\LR3TMR.txt","w"); //Создаем/перезаписываем файл char str[5]; //объявляем строковую переменную длинной 5
символов
for(i=0;i<M;i++)
{
Uvx=(U[i]-2048)*0.0025; //Переводим измерение в вольты sprintf(str,"%f",Uvx); //Переводим в вещественное число
в строку
fputs(str,f); // Записываем строку в файл fputc('\n',f); //Переводим файл на новую строку
}
fclose(f); //Закрываем файл return 0;
}
