亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? use of a pc printer port for control and data acquisition.htm

?? Parallel Port description of the communication port
?? HTM
?? 第 1 頁 / 共 3 頁
字號:
	*/   
   
	#include <stdio.h>   
	#include <dos.h>        /* required for delay function */   
	   
	#define DATA 0x03bc     /* for the PC I used */   
	#define STATUS DATA+1   
	#define CONTROL DATA+2   
   
	void main(void)   
	{   
	   int in, n;   
   
	   outportb(DATA,0x00); /* turn on all LEDs on Data Port */   
	   outportb(CONTROL, 0x00^0x0b); /* same with Control Port */   
	      
	   /* now turn off each LED on Data Port in turn by positioning a logic   
	   one in each bit position and outputing.   
	   */   
	   for (n=7; n>=0; n++)   
	   {   
	      outportb(DATA, 0x01 << n);   
	      delay(1000);   
	   }   
	   outportb(DATA, 0x00);   
   
	   /* now turnoff each LED on control port in turn   
	   ** note exclusive-or to compensate for hardware inversions   
	   */   
   
	   outportb(CONTROL, 0x08^0x0b);        /* bit 3 */   
	   delay(1000);   
	   outportb(CONTROL, 0x04^0x0b);        /* bit 2 */   
	   delay(1000);   
	   outportb(CONTROL, 0x02^0x0b);        /* bit 1 */   
	   delay(1000);   
	   outportb(CONTROL, 0x01^0x0b);        /* bit 0 */   
	   delay(1000);   
   
	   outportb(CONTROL, 0x00);   
   
	   /* Continuously scan switches and print result in hexadecimal */   
   
	   while(1)   
	   {   
	      in = (inportb(STATUS)^0x80)&0xf8;   
	      /* Note that BUSY (msbit) is inverted and only the   
	      ** five most significant bits on the Status Port are displayed.   
	      */   
	      printf("%x\n", in);   
	   }   
	}   
   
</PRE>
<HR>

<P>
<CENTER>
<H3>F. Interrupts</H3></CENTER>
<P>Again refer to Figure #2-Port assignments. Note that bit 4 on the Control Bit 
is identified as IRQ Enable. Normally, this bit is set to zero. 
<P>However, there are times when interrupts are of great value. An interrupt is 
nothing more than a hardware event which causes your program to momentarily stop 
what it is doing, and jump to a function to do what you desire. When this is 
complete, your program returns to where it left off. 
<P>In using the printer port, if the IRQ Enable is set to a logic one, an 
interrupt occurs when input ACK next goes from a logic one to logic zero. For 
example, you might use input ACK for an intrusion alarm. You might have a 
program running which is continually monitoring temperature. But, when input ACK 
goes low, it interrupts your temperature monitoring and goes to some other code 
you have written to handle an alarm. Perhaps, to fetch the time and date off the 
system clock and write this to an Intrusion File. When done, your program 
continues monitoring temperature. 
<P>Interrupts are treated in detail elsewhere in this manual. 
<P>
<CENTER>
<H3>G. Changing Only Selected Bits</H3></CENTER>
<P>Frequently, when outputting, the programmer is interested in only a portion 
of a byte and it is a burden to remember what all the other bits are. Please 
review the following where bit 2 is brought high for 100ms and then brought low. 
<PRE>     
	int data;     
	...     
	data=data | 0x04;/* bring bit 2 high */     
	outportb(DATA,data);     
	delay(100);     
	data=data &amp; 0xfb; /* bring bit 2 low */     
	outportb(DATA,data);     
</PRE>
<P>Note that variable data keeps track of the current state on the output port. 
Each bit manipulation is performed on data and variable data is then output. 
<P>To bring a specific bit to a logic one, use the OR function to OR that bit 
with a logic one (and all others with a logic zero.) 
<P>To bring a specific bit to a logic zero, AND that bit with a zero (and all 
others with a logic one.) Calculating this value can be tedious. Consider this 
alternative: <PRE>     
	data=data &amp; 0xfb;       /* hard to calculate */     
	data=data &amp; (~0x04);    /* the same but a lot easier */     
</PRE>
<P>This really isn't very difficult. Assume, you currently have; XXXX XXXX and 
desire XX01 X100. <PRE>     
	data=data &amp; (~0x20) | 0x10 | 0x04 &amp; (~0x02) &amp; (~0x01);     
</PRE>
<P>
<CENTER>
<H3>H. Ports on Newer PC's</H3></CENTER>
<P>A few words about the DIRECTION bit on the Control Port. I have seen PC's 
where this bit may be set to a logic "one" which turns around the Data Port such 
that all of the Data leads are inputs. I have also seen PC's where this worked 
for only the lower nibble of the Data Port and other PC's where it did nothing. 
It is probably best not to use this feature. Rather, leave the DIRECTION bit set 
to logic "zero". 
<P>
<CENTER>
<H3>I. Differences In Printer Ports</H3></CENTER>
<P>The material discussed above is believed to be pretty generic; that is, 
common to all manufacturers. 
<P>You may well ask, "why would they be different. After all, programs such as 
WordPerfect must work on all machines." The answer is that the programmers who 
write such programs as WordPerfect do not get down to this low level of hardware 
detail. Rather, they write to interface with the PC's BIOS. 
<P>The BIOS (Basic Input-Output System) is a ROM built in to the PC which makes 
all PC's appear the same. This is a pretty nice way for each vendor to implement 
their design with a degree of flexibility. 
<P>An example is the port assignments discussed above. This data is read from 
the BIOS ROM when your PC boots up and written to memory locations beginning at 
0040:0008. Thus, the designers of WordPerfect don't worry about the port 
assignments. Rather, they read the appropriate memory location. 
<P>In the same way, they interface with the BIOS for printing. For example, if 
the designers want to print a character, the AH register is set to zero, the 
character to be printed is loaded into AL, the port (LPT1, LPT2, etc) is loaded 
into the DX register. They then execute a BIOS INT 17h. Program control is then 
passed to the BIOS and which performs at the low level of hardware design which 
we are trying to work. The BIOS varies from one hardware design to another; it's 
purpose is to work with the hardware. If inversions are necessary, it is done in 
the BIOS. When the BIOS has completed whatever bit sequencing is required to 
write the character to the printer, control is passed back to the program with 
status information in the AH register. 
<P>
<CENTER>
<H3>J. Summary</H3></CENTER>
<P>In summary, the printer port affords a very simple technique for interfacing 
with external circuitry. Twelve output bits are available, eight on the Data 
Port and four on the lower nibble of the Control Port. Inversions are necessary 
on three of the bits on the Control Port. Five inputs are available on the 
Status Port. One software inversion is necessary when reading these bits. 
<HR>

<P>
<CENTER>
<H2>II. Forcing an Interrupt on the Printer Port.</H2></CENTER>
<P>
<CENTER>
<H3>A. Introduction</H3></CENTER>
<P>This section describes how to use hardware interrupts using the printer port. 
The discussion closely follows programs prnt_int.c and time_int.c 
<P>A hardware interrupt is a capability where a hardware event causes the 
software to stop whatever it is doing and to be redirected to a function to 
handle the interrupt. When done, the program picks up where it left off. Aside 
from loosing time in executing the interrupt service routine, the operation of 
the main program remains unaffected by the interrupt. 
<P>This is quite powerful and although at first, the whole process may appear 
difficult to grasp, it is in fact quite simple. 
<P>Although this discussion focuses on using the interrupt associated with the 
printer port, the same technique may be adapted to exerting interrupts directly 
on the ISA bus. 
<P>
<CENTER>
<H3>B. Interrupt Handler Table</H3></CENTER>
<P>When an interrupt occurs, the PC must know where to go to handle the 
interrupt. 
<P>The original 8088 PC design provided for up to 256 interrupts (0x00 - 0xff). 
This includes both hardware and software interrupts. Each of these 256 interrupt 
types has four bytes in a table beginning at memory location 0x00000. Thus, INT 
0 uses memory locations 0x00000, 0x00001, 0x00002, 0x00003, INT 1 uses the next 
four bytes in the table, etc. Note that INT 8 then uses the four bytes at 
0x0020, INT 9 begins at 0x0024, etc. This 1024 bytes (256x4) is termed the 
interrupt vector table. 
<P>These four bytes contain the address of where the PC is to go to when an 
interrupt occurs. Most of the table is loaded when you boot up the machine. The 
table may be added to or entries modified when you run various applications. 
<P>IBM reserved eight hardware interrupts beginning at INT 0x08 for interrupt 
expansion. These are commonly known as IRQ0 - IRQ7, the IRQ corresponding to the 
lead designations associated with the Intel 8259 which was used to control these 
interrupts. Thus, IRQ 0 corresponds to INT 8, IRQ 1 corresponds to INT 9, etc. 
<P>Exercise. Use debug to examine the interrupt vector table which is assigned 
to IRQ 0 through IRQ 7. <PRE>  
-d 00000:0020 20  
  
	B3 10 3B 0B 73 2C 3B 0B-57 00 70 03 8B 3B 3B 0B  
	ED 3B 3B 0B AC 3A 3B 0B-B7 00 70 03 F4 06 70 00  
  
</PRE>(Recall that the table allocation for INT 8 begins at 0x0020). 
<P>From this I can see that the address for the interrupt service routine 
associated with IRQ 0 is 0B3B:10B3. For IRQ 7, 0070:06F4. You should be able to 
see the algorithm I used to obtain this. 
<P>Thus, when an IRQ 7 interrupt occurs, we know this corresponds to INT 0x0f 
and the address of the interrupt service routine is located at 0070:06F4. 
<P>Exercise. Use the debugger to examine the interrupt vector table. Then use 
Microsoft Diagnostics (MSD) and examine the IRQ addresses and compare the two. 
<P>
<CENTER>
<H3>C. Modifying the Interrupt Handler Table</H3></CENTER>
<P>Assume, you are going to use IRQ 7. Assume that when an IRQ 7 interrupt 
occurs, you desire your program to proceed to function irq7_int_serv, a function 
which you wrote. In order to do so, you must first modify the interrupt handler 
table. Of course, you may wish to carefully take what is already there in the 
table and save it somewhere and then when you leave your program, put the old 
value back. 
<P>Borland's Turbo C provides functions to do this. <PRE>  
  
	int intlev=0x0f;  
  
	oldfunc = getvect (intlev);  
		/* The content of 0x0f is fetched and saved for future  
		**use. */  
  
	setvect (intlev, irq7_int_serv);  
		/* New address is placed in table. */  
		/* irq7_int_serv is the name of routine and is of type  
		** interrupt far*/  
</PRE>
<P>This may look bad, but, in fact it isn't. Simply get the vector now 
associated with INT 0x0f and save it in a variable named oldfunc. Then set the 
entry associated with INT 0x0f to be the address of your interrupt service 
routine. 
<P>Good programming dictates that once you are done with your program, you would 
restore the entry to what it was; <PRE>  
	setvect(intlev, oldfunc);  
</PRE>
<P>After all, what would you think of WordPerfect, if after running it, you 
couldn't use your modem without rebooting. 
<P>
<CENTER>
<H3>D. Masking</H3></CENTER>
<P>The programmer can mask interrupts. If an interrupt is masked you are saying 
to the PC, "for the moment ignore any IRQ 7 type interrupts". Normally, we don't 
do this. Rather we desire to set the interrupt mask such that IRQ 7 is enabled. 
<P>Port 0x21 is associated with the interrupt mask. To enable a particular IRQ, 
write a zero to that bit location. However, you don't want to disturb any of the 
other bits. <PRE>  
	mask=inportb(0x21) &amp; ~0x80;  
		/* Get current mask.  Set bit 7 to 0.  Leave other bits  
		** undisturbed. */  
	outportb(0x21, mask);  
</PRE>
<P>The user is now ready for IRQ 7 interrupts. Note that each time there is an 
IRQ 7 interrupt, the program is unconditionally redirected to the function 
irq7_int_serv. The user is free to do whatever they like but must tell the PC 
that the interrupt has been processed; <PRE>  
	outportb(0x20, 0x20);  
</PRE>
<P>Prior to exiting the program, the user should return the system to its 
original state; setting bit 7 of the interrupt mask to logic one and restoring 
the interrupt vector. <PRE>  
	mask=inportb(0x21) | 0x80;  
	outportb(0x21, mask);  
  
	setvect(intlev, oldfunc);  
</PRE>
<P>
<CENTER>
<H3>E. Interrupt Service Routine</H3></CENTER>
<P>In theory, you should be able to do anything in your interrupt service 
routine (ISR). For example, an interrupt might be forced by external hardware 
detecting an intrusion. The ISR might fetch the time off the system clock, open 
a file and write the time and other information to the file, close the file and 
then return to the main program. 
<P>In fact, I have not had good luck in doing this and you will note that my 
interrupt service routines are limited; 
<UL>
  <LI>disable any further interrupts. 
  <LI>set a variable such that in returning to the main program there is an 
  indication that an interrupt occurred. 
  <LI>indicate to the PC that the interrupt was processed; outportb(0x20,0x20); 
  <LI>enable interrupts. </LI></UL>
<P>I think that my problem is that interrupts are turned off during the entire 
ISR which may well preclude a C function which may use interrupts. For example, 
in opening a file, I assume interrupts are used by Turbo C to interface with the 
disk drive. Unlike the IRQ we are discussing, the actual implementation of how C 
handles these interrupts necessary to implement a C function will not be "heard" 
by the PC and the program will appear to bomb. 
<P>My suggestion is that you initially use the technique I have used in writing 
your interrupt service routine. That is, very simple; either setting or 

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美性生活久久| 亚洲色图视频免费播放| 日韩1区2区3区| 91超碰这里只有精品国产| 亚洲成人av一区| 日韩一区二区视频| 日韩高清不卡一区二区三区| 欧美电影免费观看高清完整版在线| 男女男精品视频| 日本一区二区三区高清不卡| 不卡av电影在线播放| 亚洲一区在线观看视频| 欧美一区二区三级| 国产精品1区二区.| 亚洲另类色综合网站| 欧美剧情片在线观看| 久久99国产精品久久| 综合久久国产九一剧情麻豆| 欧美高清视频www夜色资源网| 狠狠色丁香久久婷婷综合_中| 欧美国产一区二区在线观看| 在线观看亚洲专区| 久久不见久久见免费视频7| 日本一二三不卡| 8v天堂国产在线一区二区| 国产激情一区二区三区桃花岛亚洲| 亚洲视频在线一区二区| 欧美一区二区福利在线| 粉嫩av一区二区三区在线播放| 一区二区三区不卡视频| 精品粉嫩超白一线天av| 欧美性一区二区| 国产一区二区三区久久悠悠色av| 一区二区三区欧美| 久久综合网色—综合色88| 欧美无人高清视频在线观看| 狠狠色丁香久久婷婷综合丁香| 亚洲国产精品一区二区www| 精品91自产拍在线观看一区| 91成人免费网站| 国产一区在线观看麻豆| 亚洲成人动漫一区| 亚洲日穴在线视频| 久久精品人人做| 欧美一区二区在线免费播放| 91一区二区在线| 国产盗摄一区二区| 蜜臀久久99精品久久久画质超高清 | 一本一本大道香蕉久在线精品| 欧美aⅴ一区二区三区视频| 亚洲免费在线观看视频| 久久亚洲精品国产精品紫薇| 777欧美精品| 欧美日韩免费视频| 一本在线高清不卡dvd| 国产成人精品亚洲日本在线桃色| 石原莉奈在线亚洲二区| 亚洲精品成人天堂一二三| 国产精品久久久久久久久搜平片| 精品久久国产97色综合| 日韩一区二区电影在线| 欧美日韩一区不卡| 91成人在线精品| 91浏览器入口在线观看| 成人av在线资源| 顶级嫩模精品视频在线看| 国产精品性做久久久久久| 久久福利资源站| 男男视频亚洲欧美| 日韩成人免费电影| 日韩激情一二三区| 日一区二区三区| 日韩精品福利网| 免费三级欧美电影| 蜜桃av一区二区| 另类的小说在线视频另类成人小视频在线 | 久久久一区二区三区捆绑**| 日韩欧美www| 欧美一二三四在线| 日韩欧美中文字幕精品| 欧美岛国在线观看| 欧美videofree性高清杂交| 欧美一区二区在线免费播放| 5858s免费视频成人| 91精品国产一区二区| 91精品国产综合久久久久久漫画| 欧美调教femdomvk| 欧美日韩一区久久| 欧美一区二区福利在线| 精品国产乱码久久久久久老虎| 精品国产伦理网| 国产精品免费看片| 亚洲欧美日韩在线播放| 一片黄亚洲嫩模| 日韩av午夜在线观看| 精品影院一区二区久久久| 国产精品一区一区| 一本色道久久综合亚洲aⅴ蜜桃| 日本道在线观看一区二区| 欧美一区二区三区免费视频| 亚洲精品一区二区三区精华液| 欧美激情一区在线观看| 一区二区三区中文字幕精品精品 | 另类的小说在线视频另类成人小视频在线| 日韩av电影天堂| 国产91露脸合集magnet| 色综合久久88色综合天天| 777色狠狠一区二区三区| 久久久精品天堂| 亚洲国产综合色| 精品一区二区三区欧美| 91亚洲精华国产精华精华液| 欧美日韩精品一区二区三区四区| 精品少妇一区二区三区在线播放| 国产精品麻豆视频| 日韩av一区二区三区四区| 国产凹凸在线观看一区二区| 欧美午夜电影在线播放| 久久久久久免费网| 亚洲黄色性网站| 国产精品一区2区| 欧美日韩国产不卡| 国产清纯在线一区二区www| 亚洲国产毛片aaaaa无费看| 国产伦精品一区二区三区免费迷| 色网站国产精品| 精品少妇一区二区三区在线视频| 日韩毛片视频在线看| 麻豆传媒一区二区三区| 6080日韩午夜伦伦午夜伦| 国产三级精品在线| 三级精品在线观看| 91在线国内视频| 精品福利一二区| 午夜av电影一区| 色婷婷综合久久久| 中文字幕成人av| 韩国毛片一区二区三区| 欧美人狂配大交3d怪物一区| 1000精品久久久久久久久| 麻豆精品国产传媒mv男同 | 亚洲国产精品久久久久秋霞影院| 国产精品系列在线观看| 欧美一区二区私人影院日本| 亚洲精品中文在线| 高清av一区二区| 精品国精品国产| 麻豆精品一二三| 91精品国产综合久久久久久久久久 | 久久激情五月婷婷| 欧洲亚洲精品在线| 亚洲欧美日韩国产手机在线 | 日韩av一级电影| 欧美羞羞免费网站| 亚洲精品视频免费观看| 不卡欧美aaaaa| 中文字幕精品在线不卡| 国产精品18久久久久久久久| 欧美mv日韩mv国产网站app| 免费在线观看视频一区| 在线播放国产精品二区一二区四区| 亚洲在线观看免费视频| 91国在线观看| 亚洲国产精品久久艾草纯爱| 欧美日韩精品一区二区三区| 一区二区三区在线观看动漫| 在线免费观看视频一区| 一区二区在线观看免费| 在线亚洲欧美专区二区| 亚洲精品免费一二三区| 色综合久久综合网| 亚洲综合一区二区三区| 欧美性猛片aaaaaaa做受| 亚洲小说春色综合另类电影| 欧美久久一二区| 日韩精品高清不卡| 精品国产乱码久久久久久闺蜜| 国内精品久久久久影院一蜜桃| 国产女同互慰高潮91漫画| 国产一区三区三区| 国产色产综合产在线视频| 成人性生交大片免费看中文| 最新国产成人在线观看| 色综合色狠狠综合色| 亚洲高清一区二区三区| 欧美一区二区三区性视频| 精品系列免费在线观看| 中文字幕精品综合| 欧美视频一区二区三区四区| 日韩激情一二三区| 国产午夜精品久久久久久免费视 | 日韩精品久久久久久| 精品三级在线看| 不卡区在线中文字幕| 亚洲国产精品麻豆| 亚洲精品在线免费播放| 成人av手机在线观看| 五月婷婷综合在线| 26uuu色噜噜精品一区二区| 成人av免费观看|