00000026.htm

来自「水木社区 embeded 版精华区 下载」· HTM 代码 · 共 157 行

HTM
157
字号
<?xml version="1.0" encoding="gb2312"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"/><title>单片机与TCP/IP网络 (八)               jacobw </title></head><body><center><h1>BBS 水木清华站∶精华区</h1></center><a name="top"></a>发信人:&nbsp;turbolinux&nbsp;(hoho~神啊,救救我吧...),&nbsp;信区:&nbsp;Embedded&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />标&nbsp;&nbsp;题:&nbsp;单片机与TCP/IP网络&nbsp;(八)&nbsp;<br />发信站:&nbsp;BBS&nbsp;水木清华站&nbsp;(Fri&nbsp;Jul&nbsp;13&nbsp;00:35:57&nbsp;2001)&nbsp;<br />&nbsp;<br /> &nbsp;&nbsp;单片机与TCP/IP网络&nbsp;<br />--版主&nbsp;老古&nbsp;<a href="http://www.laogu.com">http://www.laogu.com</a>&nbsp;<br />&nbsp;<br />(八)网卡初始化&nbsp;<br />&nbsp;<br />&nbsp;<br />------------------------------------------------------------------------&nbsp;<br />--------&nbsp;<br />&nbsp;<br />----&nbsp;完成复位之后,你要对网卡的工作参数进行设置.以使网卡开始工作.&nbsp;<br />先介绍一个子函数&nbsp;<br />#define&nbsp;reg00&nbsp;XBYTE[0xc000]&nbsp;//对应于地址240H&nbsp;为命令寄存器CR地址&nbsp;<br />&nbsp;<br />void&nbsp;page(uchar&nbsp;pagenumber)&nbsp;<br />{&nbsp;uchar&nbsp;data&nbsp;temp;&nbsp;&nbsp;<br />temp=reg00;//command&nbsp;register&nbsp;&nbsp;<br />temp=temp&amp;0x3f;&nbsp;<br />pagenumber=pagenumber&nbsp;&lt;&lt;6;&nbsp;&nbsp;<br />temp=temp&nbsp;|&nbsp;pagenumber;&nbsp;<br />reg00=temp;&nbsp;<br />}&nbsp;<br />作用是选择指定的页,网卡共有4页寄存器,Ne2000兼容的有3页。第四页可以不用&nbsp;<br />。&nbsp;&nbsp;<br />&nbsp;<br />reg00命令寄存器:CR,command&nbsp;register,地址偏移量00H,为一个字节&nbsp;<br />&nbsp;<br />位&nbsp;7&nbsp;6&nbsp;5&nbsp;4&nbsp;3&nbsp;2&nbsp;1&nbsp;0&nbsp;&nbsp;<br />名字&nbsp;PS1&nbsp;PS0&nbsp;RD2&nbsp;RD1&nbsp;RD0&nbsp;TXP&nbsp;STA&nbsp;STP&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;<br />PS1和PS0这两个位用来选择寄存器页,PS1&nbsp;PS0=00时选择寄存器页0,=01时选择寄存&nbsp;<br />器页1,&nbsp;=10时选择寄存器页2,=11时选择寄存器页3.&nbsp;<br />上面的程序的参数为pagenumber,用来指定第几页。&nbsp;<br />temp=reg00&nbsp;;//读入命令寄存器的值。&nbsp;<br />temp=temp&amp;0x3f;//将高2位,即PS1,PS0清0&nbsp;<br />pagenumber=pagenumber&lt;&lt;6;//将低2位移至高端&nbsp;<br />temp=temp|pagenumber,&nbsp;//写入高2位&nbsp;<br />reg00=temp;&nbsp;//设置第几页&nbsp;<br />&nbsp;<br />当然也可以写成更加简单的几句:&nbsp;<br />temp=reg00&amp;0x3f;&nbsp;<br />pagenumber=pagenumber&lt;&lt;6;&nbsp;<br />reg00=temp|pagenumber;&nbsp;&nbsp;<br />&nbsp;<br />但这样对读者来说不好理解。&nbsp;<br />从执行的速度来说,上面的代码也不是最快的。但作者主要讲述原理,而不是探讨&nbsp;<br />最快的实现。&nbsp;<br />--RD2,RD1,RD0这3个位代表要执行的功能。&nbsp;<br />=001&nbsp;读网卡内存&nbsp;<br />=010&nbsp;写网卡内存&nbsp;<br />=011&nbsp;发送网卡数据包&nbsp;<br />=1**&nbsp;完成或结束DMA的读写操作&nbsp;<br />---TXP这个位写入1时发送数据包,发完自动清零&nbsp;<br />---STA,STP这两个位用来启动命令或停止命令&nbsp;<br />=10&nbsp;启动命令&nbsp;<br />=01&nbsp;停止命令&nbsp;<br />&nbsp;<br />下面介绍网卡的初始化子程序:&nbsp;<br />void&nbsp;ne2000init()&nbsp;<br />{&nbsp;reg00=0x22;&nbsp;//选择页0的寄存器,执行命令&nbsp;<br />reg01=0x4c;&nbsp;//寄存器Pstart&nbsp;<br />reg02=0x80;&nbsp;//Pstop&nbsp;<br />reg03=0x4c;&nbsp;//BNRY&nbsp;<br />reg04=0x45;&nbsp;//TPSR&nbsp;<br />reg0c=0xcc;&nbsp;//RCR&nbsp;<br />reg0d=0xe0;&nbsp;//TCR&nbsp;<br />reg0e=0xc8;&nbsp;//DCR&nbsp;数据配置寄存器&nbsp;8位数据dma&nbsp;&nbsp;<br />reg0f=0x00;&nbsp;//IMR&nbsp;disable&nbsp;all&nbsp;interrupt&nbsp;&nbsp;<br />page(1);&nbsp;//选择页1的寄存器&nbsp;<br />reg07=0x4d;&nbsp;//CURR&nbsp;<br />reg08=0x00;&nbsp;//MAR0&nbsp;<br />reg09=0x41;&nbsp;//MAR1&nbsp;<br />reg0a=0x00;&nbsp;//MAR2&nbsp;<br />reg0b=0x80;&nbsp;//MAR3&nbsp;<br />reg0c=0x00;&nbsp;//MAR4&nbsp;<br />reg0d=0x00;&nbsp;//MAR5&nbsp;<br />reg0e=0x00;&nbsp;//MAR6&nbsp;<br />reg0f=0x00;&nbsp;//MAR7&nbsp;<br />}&nbsp;&nbsp;<br />&nbsp;<br />PSTART&nbsp;接收缓冲区的起始页的地址。&nbsp;<br />PSTOP&nbsp;接收缓冲区的结束页地址。(该页不用于接收)&nbsp;<br />BNRY&nbsp;指向最后一个已经读取的页(读指针)&nbsp;<br />CURR&nbsp;当前的接收结束页地址。(写指针)&nbsp;<br />&nbsp;<br />--网卡含有16K字节的RAM,地址为0x4000-0x7fff(指的是网卡上的存储地址,而&nbsp;<br />不是ISA总线的地址,是网卡工作用的存储器),每256个字节称为一页,共有64页&nbsp;<br />。页的地址就是地址的高8位,页地址为0x40--0x7f&nbsp;。这16k的ram的一部分用来存&nbsp;<br />放接收的数据包,一部分用来存储待发送的数据包。当然也可以给用户使用。(例&nbsp;<br />如把网卡设置成使用8K的ram,另外8K的ram就可以用来给单片机作为存储器,但我&nbsp;<br />没有这样做,原因是操作网卡上的ram比较复杂)&nbsp;<br />---在我的程序中使用0x40-0x4B为网卡的发送缓冲区,共12页,刚好可以存储&nbsp;<br />2个最大的以太网包。使用0x4c-0x7f为网卡的接收缓冲区,共52页。因此&nbsp;<br />PSTART=0x4c,PSTOP=0x80(0x80为停止页,就是直到0x7f,是接收缓冲区,不包括&nbsp;<br />0x80)&nbsp;刚开始,网卡没有接收到任何数据包,所以,BNRY设置为指向第一个接收&nbsp;<br />缓冲区的页0x4c)&nbsp;&nbsp;<br />这四个寄存器用于接收的设置。&nbsp;<br />--CURR是网卡写内存的指针。它指向当前正在写的页的下一页。那么初始化它就&nbsp;<br />应该指向0x4c+1=0x4d&nbsp;。网卡写完接收缓冲区一页,就将这个页地址加一,&nbsp;<br />CURR=CURR+1。这是网卡自动加的。当加到最后的空页(这里是0x80,PSTOP)时,&nbsp;<br />将CURR置为接收缓冲区的第一页(这里是0x4c,PSTART),也是网卡自动完成的。&nbsp;<br />当CURR=BNRY时,表示缓冲区全部被存满,数据没有被用户读走,这时网卡将停止&nbsp;<br />往内存写数据,新收到的数据包将被丢弃不要,而不覆盖旧的数据。此时实际上出&nbsp;<br />现了内存溢出。&nbsp;<br />---而BNRR要由用户来操作。用户从网卡读走一页数据,要将BNRY加一,然后再&nbsp;<br />写到BNRY寄存器。&nbsp;当BNRY加到最后的空页(0x80,PSTOP)时,同样要将BNRY变成&nbsp;<br />第一个接收页(PSTART,0x4c)BNRY=0x4c;&nbsp;<br />---CURR和BNRY主要用来控制缓冲区的存取过程,保证能顺次写入和读出)。&nbsp;<br />当CURR=BNRY+1(或当BNRY=0x7f&nbsp;,CURR=0x4c)时,网卡的接收缓冲区里没有数据&nbsp;<br />,表示没有收到数据包。&nbsp;用户通过这个判断知道没有包可以读。当上述条件不成&nbsp;<br />立时,表示接收到新的数据包。然后用户应该读取数据包,直到上述条件成立时,&nbsp;<br />表示所以数据包已经读完,此时停止读取数据包。&nbsp;<br />--TPSR&nbsp;为发送页的起始页地址。初始化为指向第一个发送缓冲区的页,0x40。&nbsp;<br />&nbsp;<br />--RCR&nbsp;接收配置寄存器,设置为使用接收缓冲区,仅接收自己的地址的数据包(&nbsp;<br />以及广播地址数据包)和多点播送地址包,小于64字节的包丢弃(这是协议的规定&nbsp;<br />,设置成接收是用于网络分析),校验错的数据包不接收。&nbsp;<br />--TCR&nbsp;发送配置寄存器,启用crc自动生成和自动校验,工作在正常模式。&nbsp;<br />--DCR&nbsp;数据配置寄存器,设置为使用FIFO缓存,普通模式,8位数据传输模式,&nbsp;<br />字节顺序为高位字节在前,低位字节在后(符合我们的习惯)(如果用16位的单片&nbsp;<br />机,设置成16位的数据总线操作会更快,但80c52是8位总线的单片机)&nbsp;<br />--IMR&nbsp;中断屏蔽寄存器,设置成0x00,屏蔽所有的中断。设置成0xff将允许中断&nbsp;<br />)&nbsp;<br />--MAR0--MAR8是设置多点播送的参数,这点我也不是很清楚,我从电脑读出来&nbsp;<br />是什么数,我也将这8个寄存器设置成这几个数.&nbsp;由于我们不使用多点播送,所以&nbsp;<br />不要紧,只要保证网卡能正常工作就可以了。&nbsp;<br />--PAGE2的寄存器是只读的,所以不可以设置,不用设置,PAGE3的寄存器不是&nbsp;<br />NE2000兼容的,所以也不用设置。&nbsp;&nbsp;<br />&nbsp;<br />(未完)&nbsp;<br />&nbsp;&nbsp;<br />&nbsp;<br />--&nbsp;<br />&nbsp;<br />※&nbsp;来源:·BBS&nbsp;水木清华站&nbsp;smth.org·[FROM:&nbsp;166.111.174.125]&nbsp;<br /><a href="00000025.htm">上一篇</a><a href="javascript:history.go(-1)">返回上一页</a><a href="index.htm">回到目录</a><a href="#top">回到页首</a><a href="00000027.htm">下一篇</a></h1></center><center><h1>BBS 水木清华站∶精华区</h1></center></body></html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?