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

Сафоненко Практикум по интерфейсам последователной передачи 2012

.pdf
Скачиваний:
2
Добавлен:
12.11.2022
Размер:
4.56 Mб
Скачать

Пример программирования

Рассмотрим пример программирования порта на языке C++ в ОС MS-DOS. В этом примере будут представлены режимы работы: дуплексный, полудуплексный, симплексный (в режиме передачи и

врежиме приема данных). Первоначально будет создан класс для отображения данных MyWindow и два объекта класса для ввода и вывода данных InWin и OutWin. Так как возможно, что система использовала до нас вектор прерывания порта, мы сначала сохраним его в переменную (чтобы в конце работы вернуть все назад) и только потом установим наш обработчик прерываний. Чтение и запись

впорты будем производить с помощью функций из dos.h inportb и outportb. Функция inportb возвращает байт данных из указанного порта, а outportb в качестве аргументов получает, помимо адреса порта, байт данных, который необходимо записать в указанный порт. Для получения и изменения векторов прерывания используются функции getvect и setvect из библиотеки dos.h.

#include <dos.h> #include <stdio.h> #include <conio.h>

#define PORT1 0x3F8 /* Базовый адрес для СОМ1*/ #define INTVECT 0x0C

/* */

 

/* COM1 0x3F8

*/

/* COM2 0x2F8

*/

/* COM3 0x3E8

*/

/* COM4 0x2E8

*/

//Объявление классаокна class MyWindow{

int xl,yl; //Координаты левого верхнего угла int xr,yr; //Координаты правого верхнего угла int xcur,ycur; //Позиция курсора

int textc,textb; //Цветовые параметры public:

41

MyWindow(){

//Конструктор класса, параметрыокна по

умолчанию

xl=1;yl=1;xr=1;yr=1;

xcur=1;ycur=1;

textc=LIGHTGRAY;

textb=BLACK;

}

int outsym(unsigned char c){ //Выводсимвола вокно window(xl+1,yl+1,xr-1,yr);

textcolor(textc);

textbackground(textb);

gotoxy(xcur,ycur);

if (c==13){ //символ перевода курсорана новуюстроку cprintf("\r\n");

}

else{

cprintf("%c",c);

}

xcur=wherex();ycur=wherey(); return 0;

}

int changecolor(int c, int b){

//Изменение цветовых параметровокна textc=c;

textb=b; return 0;

}

int changecoord(int x1,int y1, int x2, int y2){ //Изменение координат окна xl=x1;xr=x2;yl=y1;yr=y2;

return 0;

}

42

int clear(void){ //Очисткаокна

window(xl+1,yl+1,xr-1,yr); textcolor(textc);

textbackground(textb);

xcur=0;ycur=0;

clrscr(); return 0;

}

};

class MyWindow InpWin,OutWin; //Создадимдва //объектакласса MyWindow

int bufferin = 0; // Номер символа буфере полученных данных int bufferout = 0;// Номер символа в буфере отправленных данных

char ch;

 

char buffer[1025];

//Буфер

int DTR=0;

//Значение сигналаDTR

//Сохраняем старый обработчик прерываний void interrupt (*oldport1isr)(...);

//Обработчикпрерываний void interrupt PORT1INT(...){

unsigned char c,c1=0;

c1= inportb(PORT1+6); //Чтение

//регистра состояния COM-порта

c = inportb(PORT1+2); //Чтение регистраидентификации //прерываний

if ((c&4)&&!(c&2)){//анализ причины прерываний //входной регистр получил символ

buffer[bufferin] = inportb(PORT1); //Чтение символа bufferin++;

if (bufferin == 1024)//буфер переполнен bufferin = 0;

}else{

//Если сработало прерывание по сигналу DTR

43

if(c1&32){

DTR=1; //DTR установимв единицу (xx1xxxxx)

}else{

DTR=0; //DTR установим в ноль(xx0xxxxx)

}

}

outportb(0x20,0x20); //Стандартное завершение Обработчика прерываний

}

void Duplex(void){

//Дуплексный режим

char c; clrscr();

gotoxy(2,1);cprintf("MODE: Duplex"); gotoxy(10,2);cprintf("Input information:"); gotoxy(10,13);cprintf("Output information:"); //Настройки окна получаемой информации

InpWin.changecoord(1,2,80,12);

InpWin.changecolor(BLUE,LIGHTGRAY);

InpWin.clear();

//Настройки окна переданной информации

OutWin.changecoord(1,13,80,24);

OutWin.changecolor(RED,LIGHTGRAY);

OutWin.clear();

do{

if (bufferin != bufferout){

//Выводимсимвол наэкран ch = buffer[bufferout];

bufferout++;

if (bufferout == 1024) bufferout = 0; InpWin.outsym(ch);

}

if (kbhit()){

//Чтение кода нажатой клавиши

44

c = getch();// имитаторввода данных впорт outportb(PORT1, c);//отсылаем символ OutWin.outsym(c);

}

}while (c!=27); //завершение по клавише <ESC> return;

}

void HDuplex(void)

{

//Полудуплексный режим

char c; clrscr();

gotoxy(2,1);cprintf("MODE: Half-Duplex. Press <ENTER> to begin/end session");

gotoxy(10,2);cprintf("Input information:"); gotoxy(10,13);cprintf("Output information:"); //Настройки окна принятойинформации

InpWin.changecoord(1,2,80,12);

InpWin.changecolor(BLUE,LIGHTGRAY);

InpWin.clear();

//Настройки окна переданной информации

OutWin.changecoord(1,13,80,24);

OutWin.changecolor(RED,LIGHTGRAY);

OutWin.clear();

do{

if(DTR){

//Если установленDTR, то получаем символы do{

if (bufferin != bufferout){ ch = buffer[bufferout]; bufferout++;

if (bufferout == 1024) bufferout = 0;

45

inport(PORT)

InpWin.outsym(ch);

}

}while(DTR); //выполняем цикл покаустановлен

//DTR

}

if (kbhit()){

c = getch();

}

if(c==13){

//Если нажата клавиша <ENTER> начинаем вывод в

//COM-порт

outportb(PORT1+4,0x09); //Включение DTR do{

c=getch();

outportb(PORT1, c);//передать символ в линию OutWin.outsym(c);

}while(c!=13); //<ENTER> – начало/ //окончание ввода

outportb(PORT1+4,0x08); //ВыключениеDTR c=0;

}

}while (c !=27); return;

}

void SimplexM(void)

{

//Симплексный режим: отправка данных char c;

clrscr();

gotoxy(2,1);cprintf("MODE: Simplex (master)"); gotoxy(10,2);cprintf("Input information:"); gotoxy(10,13);cprintf("Output information:"); //Настройки окна получаемой информации

InpWin.changecoord(1,2,80,12);

46

InpWin.changecolor(BLUE,LIGHTGRAY);

InpWin.clear();

//Настройки окна переданной информации

OutWin.changecoord(1,13,80,24);

OutWin.changecolor(RED,LIGHTGRAY);

OutWin.clear();

do{

if (kbhit()){

c = getch(); outportb(PORT1, c); OutWin.outsym(c);

}

//Ввод и отправка введенных символов, до тех //пор, пока не нажат <ESC>

}while (c !=27); return;

}

void SimplexS(void){

//Симплексный режим: получение данных

char c; clrscr();

gotoxy(2,1);cprintf("MODE: Simplex (slave)"); gotoxy(10,2);cprintf("Input information:"); gotoxy(10,13);cprintf("Output information:"); //Настройки окна получаемой информации

InpWin.changecoord(1,2,80,12);

InpWin.changecolor(BLUE,LIGHTGRAY);

InpWin.clear();

//Настройки окна переданной информации

OutWin.changecoord(1,13,80,24);

OutWin.changecolor(RED,LIGHTGRAY);

OutWin.clear();

do{

if (bufferin != bufferout){

47

ch = buffer[bufferout]; bufferout++;

if (bufferout == 1024) bufferout = 0;

InpWin.outsym(ch);

}

if (kbhit())

{

c = getch();

}

}while (c !=27); return;

}

void main(void){ //Основная функция int c;

int c1; textcolor(LIGHTGRAY); textbackground(BLACK); clrscr();

outportb(PORT1 + 1 , 0); //Отключаем прерывания oldport1isr = getvect(INTVECT); //Сохраняем адрес

//старого обработчика

setvect(INTVECT, PORT1INT); //Устанавливаем новый

//обработчик

//Инициализация COM-порта

outportb(PORT1 + 3 , 0x80); //Настройка скорости outportb(PORT1 + 0 , 0x0C); //9600 bps outportb(PORT1 + 1 , 0x00);

outportb(PORT1 + 3 , 0x03); //Окончание настройки outportb(PORT1 + 4 , 0x08); //Выбор линии OUT2 outportb(0x21,(inportb(0x21) & 0xEF)); //Разрешаемпрерывания

процессора

48

/* COM1 (IRQ4) – 0xEF */ /* COM2 (IRQ3) – 0xF7 */ /* COM3 (IRQ4) – 0xEF */ /* COM4 (IRQ3) – 0xF7 */

outportb(PORT1 + 1 , 0x09); //РазрешитьПрерывание по

//событиям готовности данных и DTR do{

window(1,1,80,24);

textcolor(LIGHTGRAY);

textbackground(BLACK);

clrscr();

printf("Choose mode:\n1. Duplex\n2. Half-Duplex\n3. Simplex (master)\n4. Simplex (slave)");

printf("\nPress <ESC> to quit"); c=getch();

switch(c){

case '1':Duplex();break; case '2':HDuplex();break; case '3':SimplexM();break; case '4':SimplexS();break;

}

}while(c!=27);//Завершение по клавише Escape outportb(PORT1 + 1 , 0); //Выключаем прерывания outportb(0x21,(inportb(0x21) | 0x10));

/* COM1 (IRQ4) – 0x10 */ /* COM2 (IRQ3) – 0x08 */ /* COM3 (IRQ4) – 0x10 */ /* COM4 (IRQ3) – 0x08 */

setvect(INTVECT, oldport1isr); //Восстанавливаем

//старый обработчик textbackground(BLACK); clrscr();

return;

}

49

Глава 2. МЕТОДИКА ПРОГРАММИРОВАНИЯ В СРЕДЕ MATLAB

Арбитраж в интерфейсах. Программные и аппаратные механизмы реализации алгоритмов арбитража. Критерии качества интерфейса и сравнительные характеристики методов арбитража передачи

Интерфейс использует буферизацию данных с целью согласования пропускной способности приемника и передатчика. В табл. 4 приведены характеристики современных буферных устройств для схем UART. В первых схемах передатчик имел два байта очереди и один байт имел приемник.

Другой механизм, который позволяет избежать потери данных в случае занятости приемника, предполагает использование сигналов квитирования. С этой целью стандарт предусматривает использование сигналов RTS–CTS, DTR–DSR и систему прерываний.

Интерфейс имеет возможность работать в режиме коммутации пакетов и в режиме коммутации соединений. Выбор и включение типа управления выполняется с помощью свойства FlowControl. Оно позволяет выбрать один из двух методов управления передачей: режим коммутации соединений (hardware– аппаратный, англ.) и коммутации пакетов (software , программный, англ.).

При выборе аппаратного метода, управление происходит с использованием сигналов RTS–CTS, DTR–DSR. Для этого метода необходимо произвести соединение устройств по схеме рис. 9. В этом случае допускается реальный контроль скорости передачи в канале.

Пример: соединим порты по схеме рис. 9 Установим:

>> com1.flowcontrol='hardware';

Бит CTS занят обслуживанием механизма управления передачи. Занять его еще чем-либо невозможно. Устройство, подключенное к порту, может приостанавливать передачу по необходимости, устанавливая бит RTS, при этом бит CTS порта устанавливается в то же значение (так как он соединен с битом RTS устройства) и сигнали-

50

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]