CORRALES HERNANDEZ MANUEL ALONSO
BACA SANDOVAL ROBERTO
GARCIA BOCANEGRA CARLOS IVAN
EJEMPLOS DE PROGRAMACION ENTRE PUERTOS Y DISPOSITIVOS
El objetivo básico de una interrupción es ejecutar una función que responda a la petición de un dispositivo de hardware. Un vector interrupción contiene la dirección de esta función. En un sistema basado en el 8086 el primer Kbyte de memoria (desde 00000H a 003FFH) es utilizado como una tabla de vectores de interrupción. Para apuntar a qualquier direccion del mapa de memoria son necesarios cuatro bytes. 16 bits para el desplazamiento y 16 bits para el el segmento. Luego, un Kbyte de memoria permite almacenar 256 vectores de interrupción. Algunos de los 256 vectores de interrupción son utilizados por el sistema, otros estan libres para ser usados por los programas de usuario. Para instalar una rutina de interrupción de usuario es posible utilizar un programa como el del ejemplo.
El programa instala una rutina de interrupción en el canal de interrupción IRQ1, que es el reloj de sistema. Este timer genera una interrupcion 18.2 veces por segundo. En la rutina de servicio de la interrupción, se incrementa una variable global. Cuando esta variable es igual a 18 se presenta en la pantalla. Luego obtendremos un contador de segundos (aprox.).
El primer ejemplo es:
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <bios.h>
#define IMR 0×21
int _key=1;
int global=0;
void interrupt (*_old_int_function)();
char _old_mask;
char _interrupt_mask(int IRQn)
{
char p=1;
p=p< return ~p;
}
void _install_int_function(int IRQn, void interrupt (*_new_int_function)())
{
int inter = IRQn + 8;
_disable(); //disable interrupts
_old_int_function=_dos_getvect(inter); //save the old interrupt vector
_dos_setvect(inter,_new_int_function); //install the new interrupt vector
_old_mask=inportb(IMR); //save the state of the 8259A IMR register
outportb(IMR,_old_mask&_interrupt_mask(IRQn)); //Set new value for IMR register
_enable(); //enable interrupts
}
void _end_interrupt(void)
{
outportb(0×20,0×20);
}
void _Unistall_new_int_function(int IRQn)
{
int inter = IRQn + 8;
_disable(); //disable interrupts
_dos_setvect(inter,_old_int_function); //restore the old interrupt service function
outportb(IMR,_old_mask); //restore the IMR
_enable(); //enable interrupts again
}
void interrupt _new_int_function()
{
_disable(); //disable interrupts
global++; //global count the number of interrupts
that the system has requested
_end_interrupt(); //to tell the system the interrupt service function has finished
_enable(); //enable interrupts again
}
/*********************************************************/
/*Read the keyboard. If “ESC” is pressed the program ends*/
/*********************************************************/
void _keyboard(void)
{
union u_type
{
int a;char b[3];
}
keystroke;
char inkey=0;
if(bioskey(1)==0) return;
keystroke.a=bioskey(0);
inkey=keystroke.b[1];
switch (inkey)
{
case 1: _key=0;
return;
case 11: _key=39;
return;\\ /*_key 0*/
default: _key=15;
return;
}
}
void main(void)
{
int second=0;
clrscr();
cprintf(“Press ‘ESC’ to exit \n \n”);
_install_int_function(0,_new_int_function);
do
{
_keyboard(); //read the keyboard
if (global >=18)
{
second++; //incremented each second
gotoxy(2,2);
cprintf(“Time: %d”,second);
global=0;
}
}
while(_key !=0);
_Unistall_new_int_function(0);
}
Analicemos un segundo ejemplo
Este segundo ejemplo es un poco mas complejo. El puerto paralelo, a parte de controlar dispositivos estilo: impresoras, ZIP, etc … Tambien se puede usar para nuestro proposito utilizando asi sus 8 señales de salidas para por ejemplo controlar 8 relés. Solo controlamos 8 leds haciendo asi un tester del puerto paralelo, para ello utilizamos un CI TTL 74245 de intermediario para los datos de salida D0..D7
El segundo ejemplo es:
#include <stdio.h>
#include <sys/io.h>
#define K 0×378
int main()
{
unsigned char p=0×01;
int sentit=1,i;
if(ioperm(K,3,1))
{
perror(“ioperm”)
exit(1);
}
while(1)
{
for(i=0;i<=7;i++) {
outb(p,K);
if(sentit) {
if(p<128)
p «= 1; // Desplazamos bits hacia la izquierda
} else {
if(p>1)
p »= 1; // Desplazamos bits hacia la derecha
}
usleep(950);
}
if(sentit) {
sentit=0;
} else
sentit=1;
}
if(ioperm(K,3,0)) {
perror(“ioperm”);
exit(1);
}
exit(0);
}