PostHeaderIcon Διασύνδεση της τυποποιημένης παράλληλης θύρας - Χρησιμοποιώντας την διακοπή της παράλληλης θύρας (IRQ)

Ευρετήριο Άρθρου
Διασύνδεση της τυποποιημένης παράλληλης θύρας
Ιδιότητες υλικού
Centronics
Διευθύνσεις θυρών
καταχωρητες λογισμικού· -· τυποποιημένης παράλληλης θύρας (SSP)
Αμφίδρομες θύρες
Χρησιμοποίηση της παράλληλης θύρας για την εισαγωγή· 8· μπιτ
Nibble Mode
Χρησιμοποιώντας την διακοπή της παράλληλης θύρας (IRQ)
Επιλογή λειτουργίας(mode) από το BIOS
Χαρακτηριστικά επιλογής λειτουργίας
Όλες οι Σελίδες

Χρησιμοποιώντας την διακοπή της παράλληλης θύρας (IRQ)

Η Λειτουργία IRQ (Interrupt ReQuest) της παράλληλης θύρας δεν χρησιμοποιείται για την εκτύπωση κάτω από το DOS ή τα Windows. Οι πρόωρες εκδόσεις OS-2 τους χρησιμοποίησαν, αλλά όχι πια. Οι διακοπές είναι καλές κατά τη διασύνδεση συσκευών ελέγχου όπως οι συναγερμοί υψηλής θερμοκρασίας κ.λπ..., όπου δεν ξέρετε πότε πρόκειται να ενεργοποιηθεί. Είναι αποδοτικότερο να υπάρχει ένα αίτημα διακοπής παρά το λογισμικό να διαβάζει τη θύρα τακτικά για να δει εάν κάτι έχει αλλάξει. Αυτό είναι ακόμα πιο αξιοπρόσεχτο εάν χρησιμοποιείτε τον υπολογιστή σας για άλλες διεργασίες, όπως με ένα πολλαπλών καθηκόντων(multitasking) λειτουργικό σύστημα.

Το interrupt της παράλληλης θύρας είναι κανονικά IRQ5 ή IRQ7 αλλά μπορεί να είναι κάτι άλλο εάν αυτά είναι σε χρήση. Μπορεί επίσης να είναι δυνατό οι διακοπές να είναι τελείως εκτός λειτουργίας στην κάρτα, εάν η κάρτα χρησιμοποιείτε μόνο για εκτύπωση. Η διακοπή της παράλληλης θύρας μπορεί να τεθεί εκτός λειτουργίας και να επιτραπεί χρησιμοποιώντας το bit 4 του Control Register,  "Enable IRQ Via Ack Line".  Μόλις επιτραπούν οι διακοπές, μια διακοπή θα εμφανιστεί όταν πάμε από μια χαμηλή σε μια υψηλή μετάβαση (rising edge) του nACK. Εντούτοις όπως πάντα, μερικές κάρτες μπορούν να προκαλέσουν την διακοπή στην από υψηλή σε χαμηλή μετάβαση.

Ο ακόλουθος κώδικας είναι ένας Interrupt ελεγκτής πολικότητας, ο οποίος χρησιμεύει ως δύο πράγματα. Θα καθορίσει ποια πολικότητα η παράλληλη θύρα σας χρησιμοποίει για τις διακοπές, δίνοντας σας επίσης ένα παράδειγμα για το πώς να χρησιμοποιήσετε την διακοπή της παράλληλης θύρας. Ελέγχει εάν η διακοπή σας παράγεται στην αύξουσα ή πίπτουσα άκρη της γραμμής nACK. Για να το χρησιμοποιήσετε συνδέστε απλά ένα καλώδιο σε μια από  τις γραμμές Data (pin 2 έως 9) στο pin nAck (pin 10). Ο ευκολότερος τρόπος να γίνει αυτό είναι να γεφυρωθεί με ένα καλώδιο από το DATA7 (pin 9) στο ack (pin 10) σε έναν αρσενικό DB25 συνδετήρα.

 

/*            WWW   - http://www.senet.com.au/~cpeacock */

#include <dos.h>
#define PORTADDRESS  0x378    /* Enter Your Port Address Here  */
#define IRQ  7     /*  IRQ Here  */
#define DATA PORTADDRESS+0
#define STATUS PORTADDRESS+1
#define CONTROL PORTADDRESS+2
#define PIC1 0x20
#define PIC2 0xA0

int interflag; /* Interrupt Flag */
int picaddr;      /* Programmable Interrupt Controller (PIC) Base Address */

void interrupt   (*oldhandler)();
void interrupt parisr()      /* Interrupt Service Routine   (ISR)    */
{
interflag = 1;
outportb(picaddr,0x20); /* End of Interrupt (EOI) */
}

void main(void)
{
int c;
int intno;        /* Interrupt Vector Number  */
int picmask;     /* PIC's Mask  */
/*  Calculate Interrupt Vector,  PIC Addr & Mask.   */
if   (IRQ >= 2  &&  IRQ <= 7)  
intno  = IRQ  + 0x08;
picaddr = PIC1;
picmask = 1;
picmask = picmask << IRQ;

if   (IRQ  >= 8  && IRQ  <= 15)  
intno = IRQ  + 0x68;
picaddr = PIC2;
picmask = 1;
picmask = picmask  <<   (IRQ-8);

if (IRQ < 2 || IRQ > 15)

printf("IRQ Out of Range"); exit();

outportb(CONTROL, inportb(CONTROL)  & 0xDF);  /* Make sure port is in Forward Direction  */
outportb(DATA,0xFF);
oldhandler = getvect(intno);  /* Save Old Interrupt Vector */
setvect(intno,  parisr);         /* Set New Interrupt Vector Entry  */
outportb(picaddr+1,inportb(picaddr+1) & (0xFF - picmask)); /* Un-Mask Pic */
outportb(CONTROL,   inportb(CONTROL)   |   0x10);   /*  Enable Parallel Port IRQ's */

clrscr();
printf("Parallel Port Interrupt Polarity Tester");
printf("IRQ %d  : INTNO %02X  : PIC Addr 0x%X  : Mask 0x%02X",IRQ,intno,picaddr,picmask); interflag = 0;  /* Reset Interrupt Flag */
delay(10);
outportb(DATA,0x00);   /* High to Low Transition  */
delay(10);             /* Wait  */
if  (interflag  == 1)  printf("Interrupts Occur on High to Low Transition of ACK.");
else

outportb(DATA,0xFF); /* Low to High Transition */
delay(10);             /* wait */
if  (interflag  == 1)  printf("Interrupts Occur on Low to High Transition of ACK. \n");
else printf("No Interrupt Activity Occurred.    IRQ Number,  Port Address and Wiring.");
}
outportb(CONTROL,   inportb(CONTROL)   & 0xEF);    /* Disable Parallel Port IRQ's  */
outportb(picaddr+1,inportb(picaddr+1)  | picmask);  /* Mask Pic */
setvect(intno,   oldhandler);  /* Restore old Interrupt Vector Before Exit */
}

Tην ώρα του compile, ο ανωτέρω κώδικας μπορεί να παραγάγει μερικά warnings, condition always true,condition always false, unreachable code κ.λπ.... Αυτά είναι εντάξει. Αυτά παράγονται καθώς μερικές από τις condition structures του τεστ του IRQ που χρησιμοποιείτε, καθώς το IRQ ορίζεται ως μια σταθερά, μερικές εκβάσεις δεν θα γίνουν ποτέ. Ενώ θα ήταν καλύτερη η εφαρμογη μιας preprocessor οδηγίας, αυτό το πρόγραμμα είναι έτσι ώστε να μπορείτε να χρησιμοποιήσετε τον κώδικα στα προγράμματά σας. Καθώς μπορούν να χρησιμοποιήθουν «διακόπτες» (arguments) γραμμών εντολής, για την εισαγωγή δεδομένων κ.λπ... αντί ενός καθορισμένου IRQ.

Για να καταλάβει κάποιος αυτό το παράδειγμα, πρέπει να έχει μια βασική γνώση και να καταλαβαίνει τα interrupts και τα Interrupt Service Routine (ISR).

Το πρώτο μέρος της ρουτίνας mainline υπολογίζει το Interrupt διάνυσμα, το PIC Addr & mask προκειμένου να χρησιμοποιηθεί η διακοπή της παράλληλης θύρας. Αφότου έχει οργανωθεί η Interrupt Service Routine (ISR) και ο Programmable Interrupt Controller (PIC), πρέπει να επιτρέψουμε τα interrupt's στην παράλληλη θύρα. Αυτό γίνεται με τη ρύθμιση του bit  4 του Control Register της παράλληλης θύρας με την εντολή

outportb(CONTROL, inportb (CONTROL);


Πριν ενεργοποιηθούν οι διακοπές, γράψαμε 0xFF στην παράλληλη θύρα για να θέσουμε τις 8 γραμμές δεδομένων σε μια γνωστή κατάσταση. Σε αυτό το σημείο του προγράμματος, όλες οι γραμμές δεδομένων πρέπει να είναι υψηλές. Η interrupt service routine θέτει απλά μια σημαία  (interflag),  κατά συνέπεια μπορούμε να καθορίσουμε πότε ένα IRQ εμφανίζεται. Είμαστε τώρα σε θέση να γράψουμε 0x00 στη θύρας δεδομένων, το οποίο προκαλεί μια υψηλή σε χαμηλή μετάβαση της  γραμμης nAck της παράλληλης θύρας καθώς είναι συνδεμενη σε μια Data Line της θύρας.

Εάν η διακοπή εμφανίζεται στην υψηλή σε χαμηλή μετάβαση, η σημαία διακοπης (interflag)  πρέπει να τεθεί σε 1. Εξετάζουμε τώρα αυτό, και εάν είναι έτσι, το πρόγραμμα ενημερώνει το χρήστη. Εντούτοις εάν δεν γινει 1, καμία διακοπή δεν έχει εμφανιστεί ακόμα. Γράφουμε τώρα 0xFF στη Data Port, το οποίο θα προκαλέσει μια χαμηλή σε υψηλή μετάβαση στη γραμμή nAck και θα ελέγξει τη σημαία διακοπής πάλι. Εάν είναι 1, η διακοπής εμφανίζεται στη χαμηλή σε υψηλή μετάβαση.
Εντούτοις εάν η σημαία δεν είναι 1 ακόμα, αυτό θα σήμαινε ότι η διακοπή δεν δουλεύει. Σιγουρευτείτε για το IRQ σας και ότι η διεύθυνση βάσεων είναι σωστή και ελέγξτε επίσης την καλωδίωση.



 

Παρακαλώ κάντε πρώτα login για να μπορείτε να κανετε σχολια.