Аппаратное обеспечение IBM PC



         

Инициализация асинхронного адаптера - часть 2


#include <stdio.h> #include <conio.h> #include "sysp.h"

void aux_stat(AUX_MODE *mode, int port) {

unsigned long b;

// Запоминаем режим адаптера

mode->ctl_aux.ctl = (char)inp(0x3fb - 0x100 * port);

// Устанавливаем старший бит режима // для считывания текушей скорости передачи

outp(0x3fb - 0x100 * port, mode->ctl_aux.ctl | 0x80);

// Считываем значение регистра делителя

b = inp(0x3f9 - 0x100 * port); b = b << 8; b += inp(0x3f8 - 0x100 * port);

// Преобразуем его в боды

switch (b) { case 1040: b = 110; break; case 768: b = 150; break; case 384: b = 300; break; case 192: b = 600; break; case 96: b = 1200; break; case 48: b = 2400; break; case 24: b = 4800; break; case 12: b = 9600; break; case 6: b = 19200; break; case 3: b = 38400; break; case 2: b = 57600; break; case 1: b = 115200; break; default: b=0; break; }

mode->baud = b;

// Восстанавливаем состояние адаптера

outp(0x3fb - 0x100 * port, mode->ctl_aux.ctl & 0x7f);

}

Прочитав состояние адаптера, вы можете изменить нужные вам поля в структуре AUX_MODE и вызвать функцию aux_init() для изменения параметров адаптера:

/** *.Name aux_init *.Title Инициализация асинхронного адаптера * *.Descr Эта функция инициализирует асинхронные * адаптеры, задавая протокол обмена данными * и скорость обмена данными. * *.Proto int aux_init(AUX_MODE *mode, int port, * int imask); * *.Params AUX_MODE *mode - указатель на структуру, * описывающую протокол и режим работы * порта; * * int port - номер асинхронного адаптера: * 0 - COM1, 1 - COM2 * * int imask - значение для регистра маски * прерываний * *.Return 0 - инициализация выполнена успешно; * 1 - ошибки в параметрах инициализации. * *.Sample aux_test.c **/

#include <stdio.h> #include <conio.h> #include "sysp.h"

int aux_init(AUX_MODE *mode, int port, int imask) {

unsigned div; char ctl;

// Вычисляем значение для делителя

switch (mode->baud) { case 110: div = 1040; break; case 150: div = 768; break; case 300: div = 384; break; case 600: div = 192; break; case 1200: div = 96; break; case 2400: div = 48; break; case 4800: div = 24; break; case 9600: div = 12; break; case 19200: div = 6; break; case 38400: div = 3; break; case 57600: div = 2; break; case 115200: div =1; break; default: return(-1); break; }

// Записываем значение делителя частоты

ctl = inp(0x3fb - 0x100 * port); outp(0x3fb - 0x100 * port, ctl | 0x80);

outp(0x3f9 - 0x100 * port, (div >> 8) & 0x00ff); outp(0x3f8 - 0x100 * port, div & 0x00ff);

// Записываем новое управляющее слово

outp(0x3fb - 0x100 * port, mode->ctl_aux.ctl & 0x7f);

// Устанавливаем регистр управления прерыванием

outp(0x3f9 - 0x100 * port, imask);

return(0);

}




Содержание  Назад  Вперед