网站导航: 首页 > 设计参考 > 正文 文章搜索
51单片机RTL8019AS网卡驱动程序
 
文章编号:
081207183718
文章分类: 单片机 51系列
点 击:
...
关 键 词: 8019,网卡,以太网
文章来源:
网络
摘 要:

在以太网的应用当中,如果你希望你的数据包只发给一个网卡,目的地址用对方的网卡地址;
如果你想把数据包发给所有的网卡,目的地址用广播地址;
如果你想把数据包发给一组网卡,目的地址用组播地址。

其他用到的寄存器:
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里的安排由用户自行决定,只要不引起冲突即可,以下源程序代码实现的只是其中的一种分配方案。

部分源程序清单:
 

 
  1. struct ethernet{   
  2.     unsigned char status;          //接收状态   
  3.     unsigned char nextpage;        //下一个页   
  4.     unsigned int  length;          //以太网长度,以字节为单位   
  5.     unsigned int  destnodeid[3];   //目的网卡地址   
  6.     unsigned int  sourcenodeid[3]; //源网卡地址   
  7.     unsigned int  protocal;        //下一层协议   
  8.     unsigned char packet[1500];    //包的内容   
  9. };   
  10.   
  11. void ne2000init()//ne2000网卡初始化   
  12. {   
  13.     rtl8019as_rst();   
  14.   
  15.     reg00=0x21;   //选择页0的寄存器,网卡停止运行,因为还没有初始化。   
  16.     delay_ms(10); //延时10毫秒,确保芯片进入停止模式   
  17. //使芯片处于mon和loopback模式,跟外部网络断开   
  18.     page(0);   
  19.     reg0a=0x00;   
  20.     reg0b=0x00;   
  21.     reg0c=0xE0; //monitor mode (no packet receive)   
  22.     reg0d=0xE2; //loop back mode   
  23. //使用0x40-0x4B为网卡的发送缓冲区,共12页,刚好可以存储2个最大的以太网包。   
  24. //使用0x4c-0x7f为网卡的接收缓冲区,共52页。   
  25.     reg01=0x4C; //Pstart  接收缓冲区范围   
  26.     reg02=0x80; //Pstop   
  27.     reg03=0x4C; //BNRY   
  28.   
  29.     reg04=0x40; //TPSR    发送缓冲区范围   
  30.   
  31.     reg07=0xFF;/*清除所有中断标志位*/  
  32.     reg0f=0x00;//IMR disable all interrupt   
  33.   
  34.     reg0e=0xC8; //DCR byte dma 8位dma方式   
  35.   
  36.     page(1); //选择页1的寄存器   
  37.     reg07=0x4D; //CURR     
  38.     reg08=0x00; //MAR0   
  39.     reg09=0x41; //MAR1   
  40.     reg0a=0x00; //MAR2   
  41.     reg0b=0x80; //MAR3   
  42.     reg0c=0x00; //MAR4   
  43.     reg0d=0x00; //MAR5   
  44.     reg0e=0x00; //MAR6   
  45.     reg0f=0x00; //MAR7    
  46.   
  47.     initNIC(); //初始化MAC地址和网络相关参数   
  48.   
  49. //将网卡设置成正常的模式,跟外部网络连接   
  50.     page(0);   
  51.     reg0c=0xCC; //RCR   
  52.     reg0d=0xE0; //TCR   
  53.     reg00=0x22; //这时让芯片开始工作?   
  54.     reg07=0xFF; //清除所有中断标志位   
  55. }   
  56.   
  57. void send_packet(union netcard *txdnet,unsigned int length)//ne2000发包子程序   
  58. {//发送一个数据包的命令,长度最小为60字节,最大1514字节需要发送的数据包要先存放在txdnet缓冲区   
  59.     unsigned char i;   
  60.     unsigned int ii;   
  61.   
  62.     page(0);   
  63.     if(length<60) length=60;   
  64.     for(i=0;i<3;i++)   
  65.         txdnet->etherframe.sourcenodeid[i]=my_ethernet_address.words[i];   
  66.     txd_buffer_select=!txd_buffer_select;   
  67.     if(txd_buffer_select)   
  68.         reg09=0x40 ;          //txdwrite highaddress   
  69.     else  
  70.         reg09=0x46 ;          //txdwrite highaddress          
  71.     reg08=0x00;    //read page address low   
  72.     reg0b=length>>8;          //read count high   
  73.     reg0a=length&0xFF;        //read count low;   
  74.     reg00=0x12;    //write dma, page0   
  75.       
  76.     for(ii=4;ii<length+4;ii++)   
  77.         reg10=txdnet->bytes.bytebuf[ii];    
  78.   
  79.     for(i=0;i<6;i++){                   //最多重发6次   
  80.         for(ii=0;ii<1000;ii++)          //检查txp为是否为低   
  81.             if((reg00&0x04)==0) break;   
  82.             
  83.         if((reg04&0x01)!=0) break;      //表示发送成功           
  84.     
  85.         reg00=0x3E;   
  86.     }   
  87.     
  88.     if(txd_buffer_select) reg04=0x40;   //txd packet start;    
  89.     else reg04=0x46;          //txd packet start;            
  90.   
  91.     reg06=length>>8;          //high byte counter   
  92.     reg05=length&0xFF;        //low byte counter   
  93.   
  94.     reg00=0x3E;               //to sendpacket;     
  95. }   
  96.   
  97. bit recv_packet(union netcard *rxdnet)//ne2000收包子程序   
  98. {   
  99.     unsigned char i;   
  100.     unsigned int ii;   
  101.     unsigned char bnry,curr;   
  102.       
  103.     page(0);   
  104.     reg07=0xFF;   
  105.     bnry=reg03;               //bnry page have read 读页指针   
  106.     page(1);   
  107.     curr=reg07;               //curr writepoint 8019写页指针   
  108.     page(0);   
  109.     if(curr==0)   
  110.         return 0;             //读的过程出错    
  111.     bnry=bnry++;   
  112.     if(bnry>0x7F) bnry=0x4C;   
  113.     if(bnry!=curr){           //此时表示有新的数据包在缓冲区里   
  114.  //读取一包的前18个字节:4字节的8019头部,6字节目的地址,6字节原地址,2字节协议   
  115.  //在任何操作都最好返回page0   
  116.         page(0);    
  117.         reg09=bnry;           //read page address high   
  118.         reg08=0x00;           //read page address low   
  119.         reg0b=0x00;           //read count high   
  120.         reg0a=18;             //read count low;   
  121.         reg00=0x0A;           //read dma   
  122.         for(i=0;i<18;i++)   
  123.             rxdnet->bytes.bytebuf[i]=reg10;   
  124.         i=rxdnet->bytes.bytebuf[3];     //将长度字段的高低字节掉转   
  125.         rxdnet->bytes.bytebuf[3]=rxdnet->bytes.bytebuf[2];   
  126.         rxdnet->bytes.bytebuf[2]=i;       
  127.         rxdnet->etherframe.length=rxdnet->etherframe.length-4; //去掉4个字节的CRC   
  128.         //表示读入的数据包有效   
  129.         if(((rxdnet->bytes.bytebuf[0]&0x01)==0)||(rxdnet->bytes.bytebuf[1]>0x7F)||(rxdnet->bytes.bytebuf[1]<0x4C)||(rxdnet->bytes.bytebuf[2]>0x06)){   
  130.             //接收状态错误,或者next_page_start错误或者长度错误,将丢弃所有数据包   
  131.             page(1);   
  132.             curr=reg07;       //page1   
  133.             page(0);          //切换回page0   
  134.             bnry=curr-1;   
  135.             if(bnry<0x4C) bnry=0x7F;   
  136.             reg03=bnry;       //write to bnry        
  137.             return 0;   
  138.         }   
  139.         else{//表示数据包是完好的.读取剩下的数据   
  140.             if((rxdnet->etherframe.protocal==0x0800)||(rxdnet->etherframe.protocal==0x0806)){   
  141.             //协议为IP或ARP才接收           
  142.                 reg09=bnry;   //read page address high   
  143.                 reg08=4;      //read page address low   
  144.                 reg0b=rxdnet->etherframe.length>>8;     //read count high   
  145.                 reg0a=rxdnet->etherframe.length&0xFF;   //read count low;   
  146.                 reg00=0x0A;   //read dma   
  147.                 for(ii=4;ii<rxdnet->etherframe.length+4;ii++)   
  148.                     rxdnet->bytes.bytebuf[ii]=reg10;   
  149.             }   
  150.             bnry=rxdnet->bytes.bytebuf[1]-1;//next page start-1   
  151.             if(bnry<0x4C) bnry=0x7F;   
  152.             reg03=bnry;       //write to bnry          
  153.             return 1;         //have new packet   
  154.         }   
  155.     }    
  156.     return 0;   
  157. }   


参考文献:
1。老古网站
2。《单片机与嵌入式系统应用》2001(7-12)合订本第228页《以太网控制器的嵌入式设备网络互连》湖南师范大学 万静华 丁亚军
3。RTL8019AS数据手册


 

 
相关文章:

上一页 12
 
最新开源项目
 
 
  查看更多...  
 
本站相关产品   淘宝网店
 




 
  查看更多...  

 

本站程序由百合电子工作室开发和维护
Copyright @ baihe electric studio
渝ICP备09006681号-4