Часть3 (1028412), страница 16
Текст из файла (страница 16)
Она получилась достаточно громоздкой, нобудет Вам полезна, поскольку содержит универсальную программу обработчик прерывания 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;// Подключаем банк=1outportb(BA+0,1);ev =inportb(BA+1);// Чтение мл. байта регистра событий EV[7:0]outport(BA+1,0xFFFF);// Сброс событий EV[15:0]Рябов Владимир Тимофеевич.
Кафедра «Электронные технологии в машиностроении»МГТУ им. Н. Э. Баумана, V_Ryabov@mail.ru47outport(BA+3,0xFFFF);// Сброс событий EV[31:16]// Определяем номера входов, где произошли события и запускаем процедуры реакции на нихfor(k=0, k<8; k++) { if (ev&mask_b[k+1]) ev_cannel[k+1]};outportb (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 - событие – «спад», по остальным – нет событийoutport(BA+7, 0x3F);// Разрешение прерываний по каналам 0..5outport(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-----------------------------------------*/// Банк=1outportb(BA+0,1);for (;;){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]{Рябов Владимир Тимофеевич.
Кафедра «Электронные технологии в машиностроении»МГТУ им. Н. Э. Баумана, V_Ryabov@mail.ru48}gotoxy(1,8); printf(“Клапан 2 выключен”)}Else{gotoxy(1,8);printf(“Клапан 2 включен ”)};}; // ----------------------------------Конец цикла----------------------------------------------//===========================Конец программы==========================На плате необходимо выставить все перемычки, определяющие способ подачи ивид сигнала.
По всем каналам входы выполним витой парой. В какое положение поставить перемычки W12 (соответствует нулевому каналу Di0, рис.6.36) - W19 (соответствуетседьмому каналу Di7) – решите сами. Пусть базовый адрес платы ВА, равный 30016, ужетакже установлен перемычками ВА0…ВА5.Пример получился несколько громоздкий, не была рассмотрена обработка возможных ошибок, возникающих при инициализации и обращении к процедурам обработкипрерываний.Что Вы должны усвоить? Использование прерываний следует применять толькотам, где без этого сложно обойтись.
Основными критериями использования механизмапрерываний являются непредсказуемость момента обнаружения, малое допустимое времязадержки реакции на событие и малое время этой реакции. Подпрограммы обслуживанияпрерываний должны быть краткими не по длине текста, а по времени исполнения.В. Типовая плата дискретного управления: устройство и работаНаиболее функциональны платы дискретного ввода-вывода, например, упоминаемые ранее модули UNIO96/48-5, построенные на программируемых логических матрицах.Их целесообразно использовать для формирования различных широтно и фазоимпульсных сигналов.
Но, такие платы, при встраивания в объект управления, потребуют дополнительных модулей для формирования линий связи.Платы, ориентированные только на дискретное управление обычно способны выдавать сигналы ДУ с частотой не более 200 Гц, т.е. предназначены для простого включенияи выключения элементов (двигателей, клапанов, насосов и т.п). Но благодаря более узкойспециализации эти платы не просто формируют линии связи с объектом, но и сами выполняют функции управления энергетическими потоками.В качестве примера рассмотрим плату DO32, модуль изолированного дискретноговывода на 32 канала, выпускаемый фирмой Fastwell в форм-факторах microPC, PC/104 иAT96 Евромеханика 3U.
Модуль предназначен для коммутации 32 сигналов постоянного напряжения до 60 В при токе нагрузки до 500 мА. Предельные значения напряжений и токовсоставляют 100 В, 5 А. Все каналы изолированы от системы и друг от друга. Напряжениеизоляции до 1500 В. Максимальное время включения и выключения 3 мс. При включениипитания и после аппаратного сигнала RESET все выходы находятся в выключенном состоянии. В модуле имеется возможность считывания состояний выходов (до опторазвязки).
Диапазон рабочих температур от -40 до +85°С.Внешний вид расположения элементов на плате представлен на рис. 6.39. Коммутируемые каналы нагрузки подключаются к разъемам J1, J2 и J3 по одно или двухпроводной схеме вместе с внешним источником питания.Функциональная схема платы представлена на рис. 6. 40. С точки зрения программиста плата представляет из себя два шестнадцати разрядных регистра, побайтно доступных для чтения и записи.
Контроллер шины обеспечивает связь с этими регистрами. Ихбазовый адрес устанавливается перемычками ВА0…ВА5 (см. рис. 6. 39, 6. 40). При программном обращении к регистрам загорается светодиод обращения (рис. 6. 39). Выходырегистров побитно подключены к блоку оптронных развязок Opt. Системный сброс устаРябов Владимир Тимофеевич. Кафедра «Электронные технологии в машиностроении»МГТУ им. Н.