harold
驱动牛犊
驱动牛犊
  • 注册日期2001-08-26
  • 最后登录2002-10-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1656回复:7

并口一问

楼主#
更多 发布于:2002-10-10 11:18
并口EPP模式能不能不用握手nWait信号。
我想用软件产生一个比较快的时钟(周期约1.5微秒)用并口输出,
但数据的输出需要外设产生nWait 信号,我的nWait信号已经被我用与其他用途,无法产生nWait信号。这样一来我需要的时钟周期变成了10微秒。
哪为大侠知道怎样不需nWait信号的情况下用软件产生一个比较短的时钟。是不是要通过写驱动才能实现(我是在win98下用C语言直接写如读端口与写端口指令的)。
mumuliang
驱动牛犊
驱动牛犊
  • 注册日期2002-10-08
  • 最后登录2003-01-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-10-11 11:14
给你一篇文章,我也遇到同样的问题了!
我们可以交流一下吗?
mumuliang
驱动牛犊
驱动牛犊
  • 注册日期2002-10-08
  • 最后登录2003-01-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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.
mumuliang
驱动牛犊
驱动牛犊
  • 注册日期2002-10-08
  • 最后登录2003-01-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-10-11 11:17
想和你交流一下,我的qq号码 50348585
bbear
驱动小牛
驱动小牛
  • 注册日期2002-08-20
  • 最后登录2009-04-16
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-10-11 12:54
直接以 nDstb Inverse , 接回 nwait.
控制好 DELAY 就可以,

#你不用 nWAIT,
harold
驱动牛犊
驱动牛犊
  • 注册日期2001-08-26
  • 最后登录2002-10-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-10-12 18:34
我的号码是9269409,欢迎交个朋友。
不过我现在已改用SPP模式下工作了,因为他不用握手这正是我所需的。
wupaul2001
驱动牛犊
驱动牛犊
  • 注册日期2003-08-14
  • 最后登录2009-09-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-11-17 12:45
我有个问题,为何我在NT系统下读77aH的数值总是FF,而且不可写?我的BIOS已经设库了ECP+EPP了.
fu_tiansweet
驱动老牛
驱动老牛
  • 注册日期2004-01-08
  • 最后登录2009-07-10
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望526点
  • 贡献值0点
  • 好评度281点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-11-19 08:51
我有个问题,为何我在NT系统下读77aH的数值总是FF,而且不可写?我的BIOS已经设库了ECP+EPP了.


77a应该是控制端口吧
游客

返回顶部