阅读:1656回复:7
并口一问
并口EPP模式能不能不用握手nWait信号。
我想用软件产生一个比较快的时钟(周期约1.5微秒)用并口输出, 但数据的输出需要外设产生nWait 信号,我的nWait信号已经被我用与其他用途,无法产生nWait信号。这样一来我需要的时钟周期变成了10微秒。 哪为大侠知道怎样不需nWait信号的情况下用软件产生一个比较短的时钟。是不是要通过写驱动才能实现(我是在win98下用C语言直接写如读端口与写端口指令的)。 |
|
沙发#
发布于:2002-10-11 11:14
给你一篇文章,我也遇到同样的问题了!
我们可以交流一下吗? |
|
板凳#
发布于:2002-10-11 11:16
【 以下文字转载自 Electronics 讨论区 】 【 原文由 dongyun 所发表 】 发信人: leu1 (Joe), 信区: Circuit 标 题: EPP编程 发信站: BBS 水木清华站 (Fri Apr 20 18:06:47 2001) EPP编程 由于EPP(IEEE1284标准)是最近新出的标准,因此虽然很多厂商声称支持 EPP,但是实际上众多厂商生产的产品并不兼容。所以很难有一种通用的程序,适用于所有 的产品,这就使EPP编程变得异常困难。以下是一些常见的问题和解决方法。 * 在EPP模式下,可以直接设置Control寄存器的bit5位,使EPP端口进入读状态。 而ECP+EPP模式下是使用ECP仿真EPP模式。以Award的BIOS为例,在ECP+EPP模式下,因为无法设置Control寄存器的bit5(Read Enable)位(即无法使端口变为读状态),因此读写 LPT+3和LPT+4端口操作无效。此时必须先设置ECP的ECR寄存器(base+402H,例如 base=378H,则ECR=77aH) bit7,6,5。设置模式如下: 000 SPP 001 Byte 010 Fast Centronics 011 ECP 100 EPP 101 Reserved 110 Test 111 Config 将ECR设置成\'100\'(即EPP模式),然后在将Control寄存器的bit5置1,端口进入 读状态将ECR设置成\'100\'(即EPP模式),然后在将Control寄存器的bit5置1,端口进入 读状态,此时即可对378H, 37bH, 37cH进行读操作;清除Control寄存器的bit5,即可对 378H,37bH, 37cH进行写操作。例如: C:\\>debug ―i 77a ;查看ECR内容 15 ;高三位为‘001’即处于Byte模式 ―o 77a 34 ;输出34H ―i 77a ; 35 ;读出却是35H,说明bit0是只读的,证明确实处于ECP模式 ―o 77a 95 ;写入95H,即高三位为‘100’,进入EPP模式 ―i 77a ; 95 ;读出95H,说明已进入EPP模式 ―i 37a ;读Control寄存器 CC ;bit5=0 ―o 37a e4 ;bit5置1,端口进入读状态 ―i 37a ; E4 ;确认bit5=1,端口进入读状态 ―i 378 ;此时若2,9脚接地,则378H, 37bH,37cH都应读出7EH 7E ; ―i 37b ; 7E ; ―i 37c ; 7E ; 7E ; * 要想检验并口的模式、端口状态、读写端口等,最好的方法是使用DOS命令: DEBUG。 例如: C:\\>debug ―i 378 ;读入DATA寄存器内容 04 ;内容为04H ―o 378 aa ;向DATA端口写入aaH ―i 378 AA ;DATA寄存器内容变为AAH ―i 379 ;读入状态寄存器内容 7F ;如果发生Timeout,则bit0=1(SMC,AWARD芯片有此功能) ―o 379 1 ;向状态寄存器写入1,可清除bit0 ―i 379 7E ;bit0被清除 ―i 37a ;读出控制寄存器内容 CC ;控制寄存器bit5=0 (Port Read disable) ―o 37a ec ;bit5置1 ―i 37a EC ;bit5被置1(只有在CMOS设为EPP模式时才起作用,否则bit5无法被设置) ―i 378 ;Port Read enable后,外部总线悬浮,电平为高 FF ―i 37b ;读EPP的DATA寄存器(如果此时外部有输入信号,它就可以读出来) ―i 37b ;读EPP的DATA寄存器(如果此时外部有输入信号,它就可以读出来) FF ―i 37c ;读EPP的ADDRESS寄存器FF * EPP是一种软件密集型读写模式,即它可以用一条指令(一个ISA指令周期)实现端口的读写,在汇编语言中指令为INP, OUTP(输入/输出一个字节)。在C语言中用inportb()和outportb()。且在读写过程中,nDataStrobe, nAddressStrobe和nWrite脚会发生 相应的变化。 例如: void EPPReadByte(unsigned short addr,unsigned short *data) { …… LPT=0x378; Status=LPT+1; Control=LPT+2; EPPAddr=LPT+3; EPPData=LPT+4; /*输出地址*/ outportb(Control,0xC4); /*Disable Port Read,以及初始化nDataStrobe, nAddre ssStrobe*/ /*和nWrite */ outportb(EPPAddr,addr);/*Output address to address register,此时 nAddressSt robe*/ robe*/ /*和nWrite管脚变为低电平*/ outportb(Status,1); /*确保Status寄存器的bit0清除*/ /*读入数据*/ outportb(Control,0xE4); /*Enable Port Read*/ *data=inportb(EPPData);/*读入数据,此时nDataStrobe变为低电平nWrite为高 电平 */ outportb(Status,1); /*确保Status寄存器的bit0清除*/ }* 由于各厂家的产品不完全兼容,因此EPP端口的初始化显得非常重要。EPP初始化 需要注意以下几个问题: (1)如何设置EPP模式:一般CMOS中对并口设置会有以下几个选项:SPP( DEFAULT)、EPP、ECP、ECP+EPP。一般而言为防止EPP同Windows发生冲突,推荐选用ECP+EPP模 式(ECP模式是Microsoft提出的)。但是在ECP+EPP下是用ECP模拟EPP,需要在程序中设 置ECR寄存器的高三位为‘100’(EPP模式),否则你无法设置Control端口的bit5,(即 无法读数据)。 因此在使用EPP之前,必须判断端口处于哪种工作模式:可通过判断ECR寄存器 bit0是否是只读的来判断是否处于ECP模式,如果ECR的bit0是只读的,则处于ECP模式;如 果Control寄存器的bit5是只读的,则不是处于EPP模式。 (2)Control端口的初始化:为确保正确对端口进行读写操作,必须对Control端 口进行初始化。主要是对bit5, nDataStrobe, nAddressStrobe, nWrite等4位进行初始化 。bit5置1使数据端口对外呈现高阻态,这时可以对端口进行读操作;反之可对端口进 行写操作。同时nDataStrobe, nAddressStrobe, nWrite等脚应为高电平,但是因为这几 位在C作。同时nDataStrobe, nAddressStrobe, nWrite等脚应为高电平,但是因为这几 位在Control寄存器中为反转位,因此应该置0。总之Control=0xE4(或0x24)表示读状态 (Control=XX100100);Control= 0xC4(或0x04)表示写状态(Control=XX000100)。 (3)Status端口的初始化:首先硬件应保证nWait为低电平,当nDataStrobe或 nAddress有效时(即变为低电平时),nWait应变为高电平,然后再变为低电平(否则会产生 超时错误,Status的bit0被置1)。这可以用一个与非门来实现:nDataStrobe和 nAddressStrobe为与非门的输入,nWait为与非门的输出。另外,为确保在出现Timeout错误时,系 统不至于进入死循环,许多厂商用硬件实现了一个Watchdog,出现Timeout错误时 (>10us未收到nWait下降沿信号),将Status的bit0置1。但有时读写开始时,Status的bit0就 是1。为确保正确读写, Status的bit0必须被清除,清除方法也各不相同。有的只要执 行inport(Status)就可以将bit0清除;有的要执行outportb(Status,1)才能将bit0清除 。(注:清除Status的bit0并不是必须的,只是为了确保万无一失。有时即便 Status的bit0是1,也可以正确读写端口。) * EPP BIOS编程:早期,EPP BIOS标准(IEEE1284.3)刚出时,很多厂家都支持 EPP BIOS。但是由于EPP BIOS标准本身并不完善,再加上真正使用EPP BIOS的产品极少,因 此现在不少厂家的BIOS中没有写入EPP功能(即int 17的AH=0020功能)。这种状态以后 可能会有改观。 综上所述给出使用EPP进行读写的例程: #include\"dos.h\" #include\"stdio.h\" #include\"stdlib.h\" #include\"conio.h\" typedef unsigned short BYTE; typedef unsigned short BYTE; void EPPBegin(int); void EPPReadByte(BYTE,BYTE*); void EPPWriteByte(BYTE,BYTE); void EPPEnd(void); int LPT,Status,Control,Address,Data,ECR; BYTE OldECR; void EPPBegin(int LPTn) { int offset; BYTE value1,value2; switch(LPTn) { case 1: offset=0x08;break; /* offset of LPT1*/ case 2: offset=0x0a;break; /* offset of LPT2*/ case 3: offset=0x0c;break; /* offset of LPT3*/ } LPT=peek(0x40,offset); if(LPT==0) { printf(\"Sorry, on this machine LPT%d does not exist\\n\",LPTn-\'0\'); getch(); exit(0); exit(0); } Status=LPT+1; Control=LPT+2; Address=LPT+3; Data=LPT+4; ECR=LPT+0x402; printf(\"\\nLPT%d detected!\\n\",LPTn); printf(\"DATA port is %xh\\n\",LPT); /* printf(\"STATUS port is %xh\\n\",dport+1); printf(\"CONTROL port is %xh\\n\",dport+2); printf(\"EPP ADDRESS port is %xh\\n\",dport+3); printf(\"EPP DATA port is %xh\\n\",dport+4);*/ OldECR=inportb(ECR); outportb(ECR,0x34); if(inportb(ECR)!=0x35) printf(\"\\nNot ECP mode!\"); else { outportb(ECR,0x95); /* Enable EPP mode under ECP mode */ } outportb(Control,0xe4); /* Set bit5 of Control Port */ if(inportb(Control)&0x20!=0x20) /* If bit5 is readonly */ if(inportb(Control)&0x20!=0x20) /* If bit5 is readonly */ { printf(\"\\nControl=%xH\\nCan\'t enable read port!\",inportb(Control)); printf(\"\\nPlease config the CMOS and setup EPP mode first!\"); getch(); exit(0); } } void EPPReadByte(BYTE addr,BYTE* x) { /* Write addr */ outportb(Control,0xc4); /* disable Read port*/ outportb(Address,addr); if(inportb(Status)&0x01==1) { printf(\"\\nStatus bit0=1, Timeout Error!\"); outportb(Status,1); /* Clear bit0 of Status port*/ } /* Read byte */ outportb(Control,0xe4); /* Enable Read port */ *x=inportb(Data); if(inportb(Status)&0x01==1) { { printf(\"\\nStatus bit0=1, Timeout Error!\"); outportb(Status,1); /* Clear bit0 of Status port*/ } } void EPPWriteByte(BYTE addr,BYTE x) { /* Write addr */ outportb(Control,0xc4); /* disable Read port*/ outportb(Address,addr); if(inportb(Status)&0x01==1) { printf(\"\\nStatus bit0=1, Timeout Error!\"); outportb(Status,1); /* Clear bit0 of Status port*/ } /* Write byte */ outportb(Data,x); if(inportb(Status)&0x01==1) { printf(\"\\nStatus bit0=1, Timeout Error!\"); outportb(Status,1); /* Clear bit0 of Status port*/ } } } void EPPEnd(void) { outportb(ECR,OldECR); outportb(Control,0xCC); } void main() { BYTE i,a[8]; clrscr(); EPPBegin(1); for(i=0x00;i<8;i++) { EPPReadByte(i,&a); printf(\"\\na[%d =%d\",i,a); } EPPEnd(); getch(); } ※ 来源:?BBS 水木清华站 smth.org?[FROM: 202.113.2.136] 心如湖水,波澜不惊 ※ 来源:?哈工大紫丁香 bbs.hit.edu.cn?[FROM: es.hit.edu.cn]-- ※ 转载:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: mpc.hit.edu. |
|
地板#
发布于:2002-10-11 11:17
想和你交流一下,我的qq号码 50348585
|
|
地下室#
发布于:2002-10-11 12:54
直接以 nDstb Inverse , 接回 nwait.
控制好 DELAY 就可以, #你不用 nWAIT, |
|
5楼#
发布于:2002-10-12 18:34
我的号码是9269409,欢迎交个朋友。
不过我现在已改用SPP模式下工作了,因为他不用握手这正是我所需的。 |
|
6楼#
发布于:2004-11-17 12:45
我有个问题,为何我在NT系统下读77aH的数值总是FF,而且不可写?我的BIOS已经设库了ECP+EPP了.
|
|
7楼#
发布于:2004-11-19 08:51
我有个问题,为何我在NT系统下读77aH的数值总是FF,而且不可写?我的BIOS已经设库了ECP+EPP了. 77a应该是控制端口吧 |
|