导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→硬件:这样读8019的接收缓冲区为什么错?[huangyan]

 *第1098篇: 硬件:这样读8019的接收缓冲区为什么错?

  
楼 主:huangyan 2001年11月15日14:51
 硬件:这样读8019的接收缓冲区为什么错?
page(0);
r09=RAM地址高8位;
r08=RAM地址低8位;
r0b=字节计数高8位;
r0a=字节计数低8位;
r00=0x0a;   //读DMA
for(i=0;i<len;i++)
{
  buf[i]=r10;
  c=r10;   //抛弃重复的内容
}

读出来的数是错的. 
正确包如:
00 01 02 03 04 05 06 07 ......

现在读成了:
00 02 04 06 ......

起初我以为是c=r10; 造成的,但后来去掉这句
则变成00 00 02 02 04 04 06 06......

请教各位,是何原因?

  
2楼:leech42 2001年11月15日14:56
 如果buf[]是用外部RAM的话,改成这样子试一下。
  cTemp=r10;
  buf[i]=cTemp;
  
3楼:huangyan 2001年11月15日15:19
 谢谢leech42!不过没用,与外部RAM无关
  
4楼:leech42 2001年11月15日15:36
 昨天我也遇到过这样子的问题,你去我问的问题看一下,也话对你有帮助。
  <a href=http://www.laogu.com/bbs/moredata.asp?id=49&syid=2619 target=_blank>  ;syid=2619  </a>  
  
5楼:huangyan 2001年11月15日16:03
 DCR=0xc8 不过,我忘记了说.....
不好意思,我现在是在PC上试验,准备在PC上调通8019后,再移到单片机上来。这跟PC是否
有关系?
  
6楼:leech42 2001年11月15日16:06
 我也不大清楚,问问老古吧!我是直接在单片机上用的,在单片机上肯定行的。
  
7楼:leech42 2001年11月15日16:09
 不过我觉得在PC机上,DCR不应该是0xc8的吧!
  
8楼:huangyan 2001年11月15日16:20
 谢谢leech42,我觉得真应该请你撮一顿
leech42,有不懂的问题可以email给你吗?
  
9楼:leech42 2001年11月15日16:24
 好啊!不过我也是不大懂的哦!
  
10楼:huangyan 2001年11月15日18:48
 我仔细研究了DCR,可用c8 c9 cb 都不行。真奇怪
  
11楼:leech42 2001年11月15日15:39
 你DCR是怎么设置的呀!
  
12楼:老古 2001年11月15日19:08
 pc里只能用16位dma,一次读入两个字节.
  
13楼:老古 2001年11月15日19:11
 要用8位的话,要割掉跟16位有关的线.
  
14楼:huangyan 2001年11月16日18:58
 老古:今天我换成了单片机,用的是8位,怎么还是不行啊?
  
15楼:老古 2001年11月17日13:41
 看我的新文章.
  
16楼:huangyan 2001年11月17日14:06
 老古,你的新文章在哪里呀,我怎么找不着?
  
17楼:easy 2001年11月17日17:43
 http://www.laogu.com/MY/pci7.htm
  
18楼:huangyan 2001年11月16日20:24
 还是读错,气杀我也!
我读DMA总是少了第偶数字节,如:
正确包:
 FF FF FF FF FF FF 00 D0-F8 09 17 77 08 00 45 00   
 03 54 4D A1 00 00 80 11-67 A7 C0 A8 

而读取的却是:
FF FF FF D0 09 77 00 00 54 A1 00 11 A7 A8

很明显,NIC接收正确,但我读取DMA时错。这是为什么?
请各虾们指点。谢谢
另:我用的是DM9008,但我认真看了9008与8019的说明书,
并没什么区别。

以下是程序.

/* store 类似于 outportb  */
/* take  类似于 inport */


void Ne2000Init()
{
  set_io(ETH_RST,1);
  delay_20ms();
  set_io(ETH_RST,0);
  delay_20ms();            /* DM9008 RESET */
  
  store(ETH_R00,0x22);     
  store(ETH_R01,0x4c);      /* Pstart 接收缓冲区起始页 */
  store(ETH_R02,0x80);      /* Pstop  接收缓冲区结束页 */
  store(ETH_R03,0x4c);      /* NBRY   已被读取的页 */
  store(ETH_R04,0x45);      /* TPSR   发送缓冲区起始页 */
  store(ETH_R0C,0xcc);      /* RCR    接收配置 0xcc   */
  store(ETH_R0D,0xe0);      /* TCR    接收配置       */
  store(ETH_R0E,0xc8);      /* DCR    DMA数据配置 */
  store(ETH_R0F,0x00);      /* IMR    中断配置  */


  page(1);
  store(ETH_R07,0x4d);      /* CURR 接收指针 */
  store(ETH_R08,0x00);      /* MAR0----MAR7  */
  store(ETH_R09,0x41);
  store(ETH_R0A,0x00);
  store(ETH_R0B,0x80);
  store(ETH_R0C,0x00);
  store(ETH_R0D,0x00);
  store(ETH_R0E,0x00);
  store(ETH_R0F,0x00);
  page(0);
}

/* 从任何一个位置读   8019RAM地址    数据区  字节数 */
void ReadNe2000Ram(uint ram_addr,uchar *buf,int len)
{
  uint ui;
  uchar uc;
  int i;

  page(0);
  ui=(ram_addr & 0xff00)>>8;
  uc=(char)ui;
  store(ETH_R09,uc);   /* Set High address */
  ui=ram_addr & 0x00ff;
  uc=(char)ui;
  store(ETH_R08,uc);   /* Set low address */
  ui=( (len*2) & 0xff00)>>8;  /* len or len*2? */
  uc=(char)ui;
  store(ETH_R0B,uc);  /* Set read counter High */
  ui=( len*2 ) & 0x00ff;      /* len or len*2? */
  uc=(char)ui;
  store(ETH_R0A,uc);  /* Set read counter low */
  store(ETH_R00,0x0a);   /* Read DMA */
  for(i=0;i<len;i++)
  {
    uc=take(ETH_R10);
    buf[i]=uc;
    take(ETH_R10);  /* 抛弃一个,如果不抛弃,则变成
                       FF FF FF FF FF FF D0 D0 09 09
                       77 77 00 00 ....(真是,该来的
                      不来,不该来的却来了)
                    */
  }
}


/* 写8019的RAM     8019RAM地址    数据区  字节数 */
void WriteNe2000Ram(uint ram_addr,uchar *buf,int len)
{
  uint ui;
  uchar uc;
  int i;

  page(0);
  ui=(ram_addr & 0xff00)>>8;
  uc=(char)ui;
  store(ETH_R09,uc);   /* Set High address */
  ui=ram_addr & 0x00ff;
  uc=(char)ui;
  store(ETH_R08,uc);   /* Set low address */
  ui=((len*2) & 0xff00)>>8;     /* len or len*2? */
  uc=(char)ui;
  store(ETH_R0B,uc);  /* Set read counter High */
  ui=(len*2) & 0x00ff;   /* len or len*2? */
  uc=(char)ui;
  store(ETH_R0A,uc);  /* Set read counter low */
  store(ETH_R00,0x12);   /* 00 010 0 10  Write DMA */
  for(i=0;i<len;i++){store(ETH_R10,buf[i]); store(ETH_R10,buf[i]); }
}

/* 读8019已接收但还未被读取的当前页 */
void ReadOnePage(char *buf)
{
  int address;
  uchar c;
  c=take(ETH_R03); /* Get Now BNRY */
  c++;
  address=c;
  address=address<<8;
  ReadNe2000Ram(address,buf,256);
  if(c==RcvBufEnd) c=RcvBufBeg;
  store(ETH_R03,c);  /* BNRY=BNRY+1 */
}

  
19楼:easy 2001年11月16日20:27
 不会吧,有8位的,因为我用8位的方式写DMA,读DMA,完全正确呀
  
20楼:huangyan 2001年11月16日20:44
 easy,你读DMA完全正确? 那帮我看看,问题出在哪里?DCR我有疑问。
DCR的FT1 FT0 用来做什么?

如果设成16位DMA,我把DCR=CD C9 CB,均不行,而且错得更离谱。


>>>>>>对该主题发表你的看法

本主题贴数21,分页: [第1页] [第2页]


[上一篇主题]:硬件:如何用GAL实现分频功能,请给出编码格式

[下一篇主题]:C51编程:C51与TCP/IP