Гл5_07 (1031652), страница 15
Текст из файла (страница 15)
Она получилась достаточно громоздкой, нобудет Вам полезна, поскольку содержит универсальную программу обработчик прерывания Read_Event(), запускающую через массив ссылок на процедуры ev_channel[i] нужную,в зависимости от номера канала, в котором произошло событие. Нужно только заранееРябов Владимир Тимофеевич. Кафедра «Электронные технологии в машиностроении»МГТУ им.
Н. Э. Баумана, V_Ryabov@mail.ru46присвоить элементам массива адрес соответствующей процедуры.Кроме того, полезна будет также универсальная процедура InitIRQ(), подключающая Read_Event() к нужному вектору прерывания VECTOR. Исходно в операционной системе по используемому адресу вектора прерывания был записан какой-то другой адресвхода oldhandler (старый обработчик).
Чтобы при возврате в операционную систему можно было продолжить нормальную работу, этот старый адрес следует восстановить.Восстанавливать нормальную работу операционной системы при выходе из программы управления технологической машиной может быть и не нужно делать, когда у насбудет готова отлаженная программа управления, которая будет автоматически загружаться при включении контроллера. Но в процессе отладки без этого сложно обойтись.Начинается она с шапки программы с перечнем подключаемых заголовочных файлов и библиотек: #include <bios.h> и далее.
Программа подключает обработчик прерываний к вектору IRQ5. Базовый Адрес модуля DI32-5 определен как 0x300.#include <bios.h>#include <conio.h>#include <dos.h>#include <stdlib.h>#include <stdio.h>//=================Описание констант и переменных==============================// -----------------------------------------Константы-----------------------------------------------------------------const unsigned short masc_b[8]={1,2,4,8,16,32,64,128}; //Массив масок для ДКconst unsigned short IRQ=5, VECTOR=0x0D, old_IRQ_masc,IRQ_masc=0x20;//Маска пятого прерывания для работы с контроллером прерываний РСconst unsigned int BA=0x300;//Базовый адрес платы//-----------------------Определение типа handler, как ссылки на процедуру-------------------------------typedef void (*handler)( void);handler ev_channel[8]; //Определение массива ссылок на процедуру обработки события// -------------------------Тип channel: для обращения к объекту управления ----------------------------------typedef struct channel{int io_rg;// номер регистра в пространстве ввода-вывода IO,short int num; };//номер бита регистра для ДК или канала мультиплексора АК//------------------------------ Описание каналов связи с объектом управления------------------------------channel Q1, Q2, SA1, SA2, P_H, P_L, KL1_on, KL2_off;// ------oldhandler - ссылка для хранения адреса старого системного обработчика прерываний---void interrupt ( *oldhandler)();// -------------------------------Переменные для подсчета импульсов расхода--------------------------------unsigned long int N_Q1=0, N_Q2=0;//===================== Описание процедур ===============================// ----------Процедура реакции по нулевому каналу, будет хранится в ev_channel[1]-------------------void Channel_0(void);{N_Q1++; gotoxy(1, 1); printf (“Число импульсов расходомера Q1= %d”, N_Q1); }// --------Далее должны быть описаны процедуры реакции на события по остальным каналам//……………………………………………………………………………………………………………../* ------------Процедура обработки прерывания IRQ.
Определяет номер канала, по которому произошло событие и запускает соответствующую реакцию Cannel_0, Cannel_1 из описанных выше, стартовые адреса этих процедур в теле основной программы должны быть присвоены элементам массива указателей на процедуры ev_cannel[8]---------------------------------------------------*/void interrupt Read_Event(void);{char k, ev;outportb(BA+0,1);// Подключаем банк=1ev =inportb(BA+1);// Чтение мл. байта регистра событий EV[7:0]outport(BA+1,0xFFFF);// Сброс событий EV[15:0]outport(BA+3,0xFFFF);// Сброс событий EV[31:16]// Определяем номера входов, где произошли события и запускаем процедуры реакции на нихfor(k=0, k<8; k++) { if (ev&mask_b[k+1]) ev_cannel[k+1]};Рябов Владимир Тимофеевич.
Кафедра «Электронные технологии в машиностроении»МГТУ им. Н. Э. Баумана, V_Ryabov@mail.ru47outportb (0x20, IRQMask);// Снимаем запрос в контроллере прерываний РС}//--------------Процедура настройки и подключения платы к вектору прерывания --------------void InitIRQ(void);{outportb(BA+0, 2);// Банк=1outport(BA+1, 0);// Сброс событий EV[15:0]outport(BA+3, 0);// Сброс событий EV[31:16]//Время антидребезга 3 мксoutportb(BA+5,0);outportb(BA+6,2); //По каналам 7..0 - событие – «спад», по остальным – нет событий// Разрешение прерываний по каналам 0..5outport(BA+7, 0x3F);outport(BA+9, 0);// и запрещение по остальным каналамoutportb(BA+13, IRQ);// Подключение к пятой линии прерыванийold_IRQ_masc= inportb(0x21);// Считать системную маску прерыванийoldhandler = getvect(VECTOR); //Считать адрес входа в старую подпрограммуsetvect(VECTOR, Read_Event); //Записать адрес входа в новую подпрограммуoutportb(0x21,(old_IRQ_masc)&(~IRQMask)); //Размаскировать IRQ5 в}// контроллере прерываний PC.
Символ тильда ~ побитная инверсия//-----------------Процедура возврата в операционную систему из программы--------------------void CleanUp(void){outportb(BA+13,0);// Запретить генерацию прерываний платойoutportb(0x21, old_IRQ_masc);// Установить исходную маску прерыванийsetvect(VECTOR, oldhandler);// Вернуть системную обработку прерываний}//==================== Основная программа ==============================void main(void){unsigned int i;// -----------------Инициализация переменных – каналов связи с объектом управления-------------------Q1->io_rg=BA+1; Q1->num=0; Q2->io_rg=BA+1; Q2->num=1;SA1->io_rg=BA+1; SA1->num=2; SA2->io_rg=BA+1; SA2->num=3;P_H->io_rg=BA+1; P_H->num=4; P_L->io_rg=BA+1; P_L->num=5;KL1_on->io_rg=BA+1; KL1_on->num=6; KL2_off->io_rg=BA+1; KL2_off->num=7;//-----------------------Присвоение ссылкам на процедуры реакции их адресов-----------------------------ev_channe[Q1->num+1]=&Channel_0; ev_channe [Q2->num+1]=&Channel_1;ev_channe[SA1->num+1]=&Channel_2; ev_channe [SA2->num+1]=&Channel_3;ev_channe[P_H->num+1]=&Channel_4; ev_channe [P_L->num+1]=&Channel_5;// ------------------------Установка параметров и инициализация платы DI32-------------------------------InitIRQ();// Настраиваем плату DI32 и инициируем прерывания от нееclrscr(); gotoxy(1,24);//Очистить экран, курсор в первую позицию на 24 строкеprintf("Для выхода нажмите ESC...");/*--Далее идет цикл с выходом по нажатию клавиши ESC, код 11Вh, в котором ожидаемпрерываний и программно фиксируем состояния клапанов 1 и 2-----------------------------------------*/outportb(BA+0,1);// Банк=1for (;;){if ( kbhit()) { i=bioskey(0); if (i== 0x11B){ CleanUp(); return;}}; //Выход из циклаif inportb(BA+1)&masc [KL1_on->num +1]{gotoxy(1,7); printf(“Клапан 1 включен ”)}else {gotoxy(1,7); printf(“Клапан 1 выключен”)};if inportb(BA+1)&masc [KL2_off->num +1]{gotoxy(1,8); printf(“Клапан 2 выключен”)}else {gotoxy(1,8); printf(“Клапан 2 включен ”)};}; // ----------------------------------Конец цикла----------------------------------------------}//===========================Конец программы==========================На плате необходимо выставить все перемычки, определяющие способ подачи ивид сигнала.
По всем каналам входы выполним витой парой. В какое положение поставить перемычки W12 (соответствует нулевому каналу Di0, рис.5.36) - W19 (соответствуетРябов Владимир Тимофеевич. Кафедра «Электронные технологии в машиностроении»МГТУ им.
Н. Э. Баумана, V_Ryabov@mail.ru48седьмому каналу Di7) – решите сами. Пусть базовый адрес платы ВА, равный 30016, ужетакже установлен перемычками ВА0…ВА5.Пример получился несколько громоздкий, не была рассмотрена обработка возможных ошибок, возникающих при инициализации и обращении к процедурам обработкипрерываний.Что Вы должны усвоить? Использование прерываний следует применять толькотам, где без этого сложно обойтись. Основными критериями использования механизмапрерываний являются непредсказуемость момента обнаружения, малое допустимое времязадержки реакции на событие и малое время этой реакции.
Подпрограммы обслуживанияпрерываний должны быть краткими не по длине текста, а по времени исполнения.В. Типовая плата дискретного управления: устройство и работаНаиболее функциональны платы дискретного ввода-вывода, например, упоминаемые ранее модули UNIO96/48-5, построенные на программируемых логических матрицах.Их целесообразно использовать для формирования различных широтно и фазоимпульсных сигналов.