📄 intrpts.c
字号:
/*
Science & Technology CO.,LTD.
W2-B5 High-Tech Industrial Park, ShenZhen, GuangDong, P.R.C.
Tel: 86-755-6544000
Fax: 86-755-6549140
Zip: 518057
Board: SF93A-0102
Compiler: Turbo C (r) version 1.0, 1.5, 2.0
Turbo C++ (r) version 1.0
Borland C++ (r) version 2.0, 3.0
Last update: Feb 22, 2002
DESCRIPTION
~~~~~~~~~~~
This program sets up the user PIT to generate interrupts at a selected
rate. An interrupt service routine (ISR) is provided that simply
samples from one channel on the ADT600 each time the interrupt is
activated. The value is displayed on the screen as a foreground
process. Although the ISR in this program is trivial, all the
ingredients for powerful interrupt driven data are included.
NOTES
~~~~~
You must change the first two lines in the main function to reflect the
base address and IRQ settings for your ADT600.
*/
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include "ADT600.h"
#include "ADT600.inc"
unsigned char OldIMRMask, /* Interrupt Mask Register storage variable */
IRQ; /* IRQ used to generate interrupts */
int ADValue; /* Value read from A-D converter */
void interrupt (*OldINT) (void); /* Original interrupt storage */
/**********
ClearBitInIMR
This function clears a bit in the 8259 Interrupt controller that will
enable interrupts on the appropriate IRQ line. For example to enable
interrupts from IRQ 3 bit 3 must be cleare. Remember that bits are
numbered 0..7.
**********/
void ClearBitInIMR(unsigned char Bit)
{
unsigned char Twos[8] = { 1, 2, 4, 8, 16, 32, 64, 128};
unsigned char OldIMR, IMR;
OldIMR = inportb(0x21); /* Read in current IMR */
IMR = OldIMR & (255 - Twos[Bit]); /* Clear desired bit */
outportb(0x21, IMR); /* cprintf out new IMR */
}
/**********
SetBitInIMR
This function sets a bit in the 8259 Interrupt controller that will
mask out interrupts on the appropriate IRQ line. For example to disable
interrupts from IRQ 3 bit 3 must be set. Remember that bits are
numbered 0..7.
**********/
void SetBitInIMR(unsigned char Bit)
{
unsigned char Twos[8] = { 1, 2, 4, 8, 16, 32, 64, 128};
unsigned char OldIMR, IMR;
OldIMR = inportb(0x21); /* Read in current IMR */
IMR = OldIMR | Twos[Bit]; /* Set desired bit */
outportb(0x21, IMR); /* cprintf out new IMR */
}
/**********
VectorInterrupt
The VectorInterrupt function is used to assign a new vector for the
designated interrupt.
**********/
void VectorInterrupt(int InterruptNumber, void interrupt (*ISR) ())
{
disable(); /* Don't want int called during revector */
setvect(InterruptNumber, ISR); /* Set the vector */
enable(); /* Reenable interrupts */
}
/**********
NewISR
The NewISR function is called whenever an interrupt is generated on the
specified IRQ. It simply gets a single value from the A-D board. An
ISR is generally quite a bit more complex and one could be placed within
the shell of this function. Do not try to access any functions that use
DOS calls (disk access, screen cprintfs, read keyboard, etc) and do not use
floating point operations in this function. DOS and the Floating Point
Emulator are not reentrant and will cause unexpected happenings if used
inside an interrupt.
Before exiting the function passes the End of Interrupt (EOI) command
to the 8259 interrupt controller. Don't forget the EOI command; it is
required even if your ISR does nothing.
**********/
void interrupt NewISR(void)
{
StartConversion(); /* Start a conversion */
while (ConversionDone() == 0); /* Wait until converted data is ready */
ADValue = ReadData(); /* Transfer data from converter */
outportb(BaseAddress + CLEAR_INT, 0); /* Clear Interrupt on ADT600 */
outportb(0x20, 0x20); /* End of interrupt command to controller */
}
/***********
The ConfigureIRQ procedure saves the startup Interrupt Mask Register (IMR)
and the startup value of the interrupt vector, then sets the interrupt
vector to point at the NewISR procedure. Remember to use the
RestoreStartupIRQ procedure (below) before exiting your program to restore
things to their original state.
***********/
void ConfigureIRQ(unsigned char IRQ)
{
SetIRQStatus(ENABLED);
OldIMRMask = inportb(0x21); /* Save original IMR Mask */
OldINT = getvect(IRQ + 8); /* Save startup vector */
VectorInterrupt(IRQ + 8, NewISR); /* Set New vector */
}
/***********
The RestoreStartupIRQ procedure restores the startup IMR and interrupt
vectors that were saved in the ConfigureIRQ procedure. Do not call this
procedure without first calling the ConfigureIRQ procedure.
***********/
void RestoreStartupIRQ(void)
{
disable(); /* Don't want interrupts occuring
while switching vectors */
outportb(0x21, OldIMRMask); /* Reset IMR to startup value */
VectorInterrupt(IRQ + 8, OldINT); /* Revector original interrupt */
enable(); /* Reenable interrupts */
}
/**********
ProgramTitle
**********/
void ProgramTitle(char St[80])
{
gotoxy(1,1); clreol();
cprintf("ADT600 Sample Program");
gotoxy(80 - strlen(St), 1);
cprintf(St);
}
void main(void)
{
IRQ = 5;
InitializeBoardSettings(0x300, 10.0, BIPOLAR); /* Set base address and volt
range */
clrscr();
ProgramTitle("Interrupt driven sampling.");
gotoxy(1, 25);
cprintf("Press any key to quit. . .");
gotoxy(28,12);
cprintf("Volts: ");
ResetBoard(); /* Reset the board */
ConfigureIRQ(IRQ); /* setup the IRQ */
SetChannel(0); /* Sample from channel 0 */
SetUserClock(100); /* Clock will generate interrupts 100
times a second. */
ClearBitInIMR(IRQ); /* Enable interrupts on specified IRQ */
SetIRQStatus(ENABLED); /* Allow interrupts from ADT600 */
/*
The following loop displays the value read from the A-D board during
the last interrupt. If you have a signal connected to channel 0 on your
board you will see the voltage of that signal displayed. Note that ADValue
is never updated inside of this loop yet its value changes with your signal.
This is because ADValue is updated in the interrupt routine.
*/
while (kbhit() == 0)
{
gotoxy(35, 12);
cprintf("%6.2f", DigitalToSBS(ADValue)); /* display value as volts */
}
getch(); /* Read character from keyboard */
SetIRQStatus(DISABLED);
RestoreStartupIRQ(); /* Restore interrupt system to startup
configuration */
clrscr();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -