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

АВМиС - Лабы / 3. таймер / Отчет по AVMIS3

.doc
Скачиваний:
39
Добавлен:
15.09.2014
Размер:
63.49 Кб
Скачать

БГУИР

Кафедра ЭВМ

Отчет по лабораторной работе

Тема: «Управление таймером»

Выполнил:

студент группы 750501 Демидовец А.Г.

Проверил:

к.т.н., доцент __________________ Одинец Д.Н.

Минск

2009

1. Цель работы

Изучение функций системного таймера и закрепление практических навыков работы с ним.

2. Темы для предварительного изучения

  • Структура и назначение портов микросхемы конфигурации и таймера.

  • Установка вектора прерываний.

3. Постановка задачи

Построить модель аналого-цифрового преобразователя (АЦП), которая работает в реальном времени. Процесс, который дискретизируется, моделируется программой (программным блоком), который выполняет циклическое вычисление функции y=F(x), где x - номер итерации. Преобразователь моделируется программой, которая выполняет с заданной частотой (в реальном времени) прерывание процесса, считывание и запоминание текущего значения функции. Запомнить не меньше 80 значений функции. Обеспечить наглядное представление результатов работы "АЦП".

4. Порядок выполнения

Порядок выполнения работы и содержание отчета определены в общих указаниях.

5. Индивидуальные задания

Индивидуальное задание.

  • функция - y=50*sin(x/(10+R))+150;

  • R - в диапазоне 0 - 1;

  • частота - 36.4 Гц.

6. Пример решения задачи

Разработка алгоритма решения

Структура программы

Программа состоит из основной программы и одной функции.

  • void interrupt newtime() - процедура нового обработчика прерывания таймера.

  • void far* read_vect(int in) - функция читает вектор прерывания с номером in и возвращает его значение.

  • void write_vect (int in, void far* h) - функция устанавливает новый вектор прерывания in на новый обработчик этого прерывания по адресу h.

  • int get_function(double x) – функция заданного варианта

Описание переменных и констант

В этой программе применяются две константы:

  • TIMEINT=8 - номер прерывания таймера;

  • NN=100 - максимальное число показаний АЦП.

Переменные, глобальные для всей программы:

  • y - массив показаний АЦП;

  • ny - текущий индекс в массиве показаний;

  • yc - текущее значение функции;

  • kf - счетчик вызовов oldtime (oldtime вызывается каждые второй раз);

  • rr и sr - переменные, которые используются для задания значений регистров общего назначения и сегментных регистров, соответственно при вызове прерывания.

Переменные главной программы:

  • oldtic - старый коэффициент деления;

  • newtic - новый коэффициент деления (применяется для увеличения частоты вызова прерываний таймера);

  • driver - тип графического адаптера;

  • mode - режим графики;

  • errorcode - код результата инициализации графики;

  • x - аргумент заданной функции F(x);

Описание алгоритма программы

Программу можно назвать моделью процесса АЦП. Главная программа постоянно вычисляет значения заданной функции F(x) при переменном аргументе, что имитирует непрерывный сигнал, а обработчик прерывания 8 имитирует преобразователь с постоянным шагом дискретизации по времени. Перед началом работы канал 0 таймера программируется на частоту в 2 раза большую обычной (записью в порт 43h управляющего байта 00110110b=36h, а потом посылкой в порт 40h нового значения коэффициента деления), таким образом, "частота дискретизации" составляет около 36.4 Гц. При поступлении следующего прерывания запоминается текущее значение функции F(x), старый обработчик прерывания oldtime вызывается не при кажндом прерывании, а лишь один раз из двух (переменная kf - счетчик по модулю 2), когда oldtime не вызывается, наш обработчик сам сбрасывает контроллер прерываний посылкой значения 20h в порт 20h. После набора 100 "показаний АЦП" восстанавливается старый вектор обработчика таймера, а результат аналого-цифрового преобразование выводится на терминал в графическом режиме в виде решетчатой функции.

Исходный код программы.

#include <dos.h>

#include <math.h>

#include <stdio.h>

#include <stdlib.h>

#include <graphics.h>

#include <time.h>

#include <conio.h>

#define TIMEINT 8 // Timer interruption

#define NN 100 // Max number of indications

void interrupt (*oldtime)();

void interrupt newtime();

void far* read_vect(int in);

void write_vect(int in, void far* h);

int get_function(double x);

static int y[NN]; // storage of indications

static int gMass[NN]; // Evidence collector

static int gMassIdx;

static int ny; // index in array

static int yc; // current value

static int grCount = 10;

static int kf; // counter of oldtime calls

union REGS rr; // provide access to registers

struct SREGS sr; // segment and base

static int kol; // Counter of oldtime call

void writeGraphic(int del);

void main()

{

unsigned oldtic=65535u;

unsigned newtic=32768u;

int driver;

int mode;

int errorcode;

double x;

textbackground(0);

randomize();

clrscr();textattr(0x01+random(14));

gotoxy(39,12);printf("3");gotoxy(40,11);printf("3");gotoxy(41,11);printf("3");

gotoxy(42,12);printf("3");gotoxy(41,13);printf("3");gotoxy(42,14);printf("3");

gotoxy(41,15);printf("3");gotoxy(40,15);printf("3");gotoxy(39,14);printf("3");

delay(1000);

clrscr();textattr(0x01+random(14));

gotoxy(39,12);printf("2");gotoxy(40,11);printf("2");gotoxy(41,11);printf("2");

gotoxy(42,12);printf("2");gotoxy(41,13);printf("2");gotoxy(40,14);printf("2");

gotoxy(39,15);printf("2");gotoxy(40,15);printf("2");gotoxy(41,15);printf("2");

gotoxy(42,15);printf("2");

delay(1000);

clrscr();textattr(0x01+random(14));

gotoxy(39,13);printf("1");gotoxy(40,12);printf("1");gotoxy(41,11);printf("1");

gotoxy(41,12);printf("1");gotoxy(41,13);printf("1");gotoxy(41,14);printf("1");

gotoxy(41,15);printf("1");

delay(1000);

clrscr();textattr(0x01+random(14));

gotoxy(40,12);printf("G");gotoxy(39,11);printf("G");gotoxy(38,11);printf("G");

gotoxy(37,12);printf("G");gotoxy(37,13);printf("G");gotoxy(37,14);printf("G");

gotoxy(38,15);printf("G");gotoxy(39,15);printf("G");gotoxy(39,14);printf("G");

gotoxy(40,14);printf("G");

textattr(0x00+random(14));

gotoxy(43,11);printf("O");gotoxy(44,11);printf("O");gotoxy(42,12);printf("O");

gotoxy(42,13);printf("O");gotoxy(42,14);printf("O");gotoxy(45,12);printf("O");

gotoxy(45,13);printf("O");gotoxy(45,14);printf("O");gotoxy(43,15);printf("O");

gotoxy(44,15);printf("O");

delay(1000);

driver=3; // EGA, 16 colors

mode=1; // Mode 640*350

initgraph(&driver,&mode,"");

// Check the result of initialization

errorcode = graphresult();

if (errorcode != grOk) // error in graphic mode

{

printf("Graphics error = %s\n", grapherrormsg(errorcode));

printf("Press any key to exit...");

getch();

exit(1);

}

// Programming of channel 0

outportb(0x43,0x36); // managing byte

outportb(0x40,newtic&0x00ff); // low counter's byte

outportb(0x40,newtic>>8); // high counter's byte

ny=-1; // sign that ADC hasn't began yet

// connection to vector

kol = 15;

oldtime=(void (interrupt far*)())read_vect(TIMEINT);

write_vect(TIMEINT,(void far*)newtime);

randomize();

for (x=ny=0; ny<NN; x+=1)

{

yc=get_function(x);

if (ny >= NN)

{

for (ny = 1; ny < NN; ny++)

y[ny - 1] = y[ny];

if (kbhit()) break;

for (gMassIdx = 0; gMassIdx < NN; gMassIdx ++)

gMass[gMassIdx] = y[gMassIdx];

writeGraphic(1500);

writeGraphic(0);

cleardevice();

clearviewport();

ny = NN - 1;

}

}

outportb(0x43,0x36); /* Young counter byte */

outportb(0x40,oldtic&0x00ff); /* Young counter byte */

outportb(0x40,oldtic>>8); /* Old counter byte */

// Restoring the vector

write_vect(TIMEINT,(void far*)oldtime); // Restoring channel

getch();

closegraph();

}

void writeGraphic(int del)

{

setcolor(10);

settextstyle(0,0,2);

outtextxy(15,10,"The graphic:");

setcolor(5);

rectangle(15,40,624,330);

setcolor(14);

for(gMassIdx=0; gMassIdx < NN - 1; gMassIdx++)

{

circle(22+gMassIdx*6,330-gMass[gMassIdx]*1,2);

line(22+gMassIdx*6,330,22+gMassIdx*6,330-gMass[gMassIdx]*1);

}

setcolor(1);

settextstyle(0,0,1);

outtextxy(260,340,"Press any key to exit...");

delay(del);

}

int get_function(double x)

{

return (int)(50*sin(x/(10+random(2)))+150);

}

void interrupt newtime()

{

if (--kf<0)

{

// Call oldtime in second time

(*oldtime)();

kf=1;

}

else // else - reset the controller

outportb(0x20,0x20);

if ((ny>=0) // if ADC has got started

&&(ny<NN)) // and NN of indication aren't collected

y[ny++]=yc; // remember next indication

}

void far* read_vect(int in)

{

rr.h.ah=0x35; rr.h.al=in;

intdosx(&rr,&rr,&sr);

return(MK_FP(sr.es,rr.x.bx));

}

void write_vect(int in, void far* h)

{

rr.h.ah=0x25;

rr.h.al=in;

sr.ds=FP_SEG(h);

rr.x.dx=FP_OFF(h);

intdosx(&rr,&rr,&sr);

}

7. Результаты работы программы

Результат работы представляется в графическом режиме в виде решетчатой функции на экране терминала.

Соседние файлы в папке 3. таймер