第三种 目的地址为跟自己的组播地址范围相同的数据包。
在以太网的应用当中,如果你希望你的数据包只发给一个网卡,目的地址用对方的网卡地址;
如果你想把数据包发给所有的网卡,目的地址用广播地址;
如果你想把数据包发给一组网卡,目的地址用组播地址。
其他用到的寄存器:
CR---命令寄存器 TSR---发送状态寄存器 ISR---中断状态寄存器
RSR---接收状态寄存器 RCR---接收配置寄存器 TCR---发送配置寄存器
DCR---数据配置寄存器 IMR---中断屏蔽寄存器 NCR---包发送期间碰撞次数
FIFO---环回检测后,查看FIFO内容
CNTR0---帧同步错总计数器
CNTR1---CRC错总计数器
CNTR2---丢包总计数器
PAR0-5---本节点MAC地址
MAR0-7---多播地址匹配
建议:将图形中寄存器名称标注上页号和地址偏移(如:BNRY 0页0x03),打印出此图,看图编程,直观且不容易出错。
备注:收缓冲区、发缓冲区、数据存储区在16K双口RAM里的安排由用户自行决定,只要不引起冲突即可,以下源程序代码实现的只是其中的一种分配方案。
部分源程序清单:
struct ethernet{
unsigned char status; //接收状态
unsigned char nextpage; //下一个页
unsigned int length; //以太网长度,以字节为单位
unsigned int destnodeid[3]; //目的网卡地址
unsigned int sourcenodeid[3]; //源网卡地址
unsigned int protocal; //下一层协议
unsigned char packet[1500]; //包的内容
};
void ne2000init()//ne2000网卡初始化
{
rtl8019as_rst();
reg00=0x21; //选择页0的寄存器,网卡停止运行,因为还没有初始化。
delay_ms(10); //延时10毫秒,确保芯片进入停止模式
//使芯片处于mon和loopback模式,跟外部网络断开
page(0);
reg0a=0x00;
reg0b=0x00;
reg0c=0xE0; //monitor mode (no packet receive)
reg0d=0xE2; //loop back mode
//使用0x40-0x4B为网卡的发送缓冲区,共12页,刚好可以存储2个最大的以太网包。
//使用0x4c-0x7f为网卡的接收缓冲区,共52页。
reg01=0x4C; //Pstart 接收缓冲区范围
reg02=0x80; //Pstop
reg03=0x4C; //BNRY
reg04=0x40; //TPSR 发送缓冲区范围
reg07=0xFF;/*清除所有中断标志位*/
reg0f=0x00;//IMR disable all interrupt
reg0e=0xC8; //DCR byte dma 8位dma方式
page(1); //选择页1的寄存器
reg07=0x4D; //CURR
reg08=0x00; //MAR0
reg09=0x41; //MAR1
reg0a=0x00; //MAR2
reg0b=0x80; //MAR3
reg0c=0x00; //MAR4
reg0d=0x00; //MAR5
reg0e=0x00; //MAR6
reg0f=0x00; //MAR7
initNIC(); //初始化MAC地址和网络相关参数
//将网卡设置成正常的模式,跟外部网络连接
page(0);
reg0c=0xCC; //RCR
reg0d=0xE0; //TCR
reg00=0x22; //这时让芯片开始工作?
reg07=0xFF; //清除所有中断标志位
}
void send_packet(union netcard *txdnet,unsigned int length)//ne2000发包子程序
{//发送一个数据包的命令,长度最小为60字节,最大1514字节需要发送的数据包要先存放在txdnet缓冲区
unsigned char i;
unsigned int ii;
page(0);
if(length<60) length=60;
for(i=0;i<3;i )
txdnet->etherframe.sourcenodeid[i]=my_ethernet_address.words[i];
txd_buffer_select=!txd_buffer_select;
if(txd_buffer_select)
reg09=0x40 ; //txdwrite highaddress
else
reg09=0x46 ; //txdwrite highaddress
reg08=0x00; //read page address low
reg0b=length>>8; //read count high