⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtl8019.c

📁 单片机数据通讯典型应用(光盘内容)
💻 C
字号:
#include <reg51.h>
#include <RTL8019.h>
#include <gnet.h>
void delay_ms(uchar ms_number)
{
    uchar i,j;
    for(j=0;j<ms_number;j++)
		for(i=0;i<90;i++);
}
/******************选择8019寄存器页面子程序************************/
void page(uchar pagenumber)
{
	uchar data temp;
	temp=reg00;
	temp=temp&0x3B ; //注意txp位不能要
	pagenumber=pagenumber <<6;
	temp=temp | pagenumber;
	reg00=temp;

}
/****************************复位网卡子程序************************/

void rtl8019as_rst()
{
	uchar temp;

 //   RST8019=1;
	delay_ms(200);
  //  RST8019=0;

	temp=reg1f;//读网卡的复位端口
	reg1f=temp; //写网卡的复位端口
}

/******************读出网卡的物理地址子程序************************/
//存到my_ethernet_address.bytes[6]里

void ReadRtl8019NodeID(void)
{
	unsigned char data i;
	page(0);
	reg09=0;//RSAR1 网卡上的RAM的起始地址高8位
	reg08=0;//RSAR0 网卡上的RAM的起始地址低8位
	reg0b=0;//RBCR1 要读取的字节数的计数(高8位)
	reg0a=12;//RBCR0 要读取的字节数的计数(低8位)	读取12个字节
	reg00=0x0a;	//读ram
	for (i=0;i<6;i++)
	{
        //my_hwaddr[i]=reg10;
    	//my_hwaddr[i]=reg10;////读取一个重复的字节,这个字节被丢弃
   	}
}
void initNIC()
{
   
	page(1);
	reg01=my_hwaddr[0];
	reg02=my_hwaddr[1];
	reg03=my_hwaddr[2];
	reg04=my_hwaddr[3];
	reg05=my_hwaddr[4];
	reg06=my_hwaddr[5];
	page(0); 

}
void rtl8019as_init()//RTL8019AS网卡初始化
{
    rtl8019as_rst();//重启网卡
    reg00=0x21;   //选择页0的寄存器,网卡停止运行,因为还没有初始化。
    delay_ms(10); //延时10毫秒,确保芯片进入停止模式
//使芯片处于mon和loopback模式,跟外部网络断开
    page(0); //选择第0页寄存器
    reg0a=0x00; //RBCR0
    reg0b=0x00; //RBCR1
    reg0c=0xE0; //RCR,不接受任何数据包
    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; //ISR 清除所有中断标志位
    reg0f=0x05; //IMR开放数据包错误接收中断和数据包无错误接收中断
    reg0e=0xC8; //DCR使用FIFO缓存,普通模式,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启用CRC自动生成和自动校验,工作在正常模式
    reg00=0x22; //这时让芯片开始工作?
    reg07=0xFF; //清除所有中断标志位
}
bit recv_packet(union netcard *rxdnet)//RTL8019AS收包子程序
{
unsigned char i;
unsigned int ii;
unsigned char bnry,curr,isr;
page(0);   //选择第0页寄存器
isr=reg07; //读取ISR寄存器
if((isr&0x04)==4) //判断PXE是否为1 
return 0; //数据包接收错误
  if((isr&0x01)==1)  //判断PRX是否为1
   {  //数据包接收正确
reg07=0xFF;   //清除中断标志位
bnry=reg03;   //读取BNRY寄存器
 page(1);      //选择页面1
 curr=reg07;  //读取CURR寄存器
page(0);      //选择页面0
if(curr==0)
return 0;     //读的过程出错 
    bnry=bnry++;
if(bnry>0x7F)
bnry=0x4C;
if(bnry!=curr) //此时表示有新的数据包在缓冲区里
{   
      //读取一包的前18个字节:4字节的8019头部,6字节目的地址,6字节原地址,2字节协议
page(0); //在任何操作都最好返回page0
reg09=bnry-1; // BNRY寄存器的值写入RSAR1
reg08=0x00;   //  00写入RSAR0
reg0b=0x00;   // 00H写入远程DMA字节计数寄存器RBCR1
reg0a=0x12;     //  #12H写入远程DMA字节计数寄存器RBCR0
reg00=0x0A;     // 启动远程DMA读
for(i=0;i<18;i++) //读取18个字节的数据
rxdnet->bytes.bytebuf[i]=reg10;
i=rxdnet->bytes.bytebuf[3];     //将长度字段的高低字节掉转
rxdnet->bytes.bytebuf[3]=rxdnet->bytes.bytebuf[2];
rxdnet->bytes.bytebuf[2]=i;    
rxdnet->etherframe.length=rxdnet->etherframe.length-4;//去掉4个字节的CRC
//读入的数据包有效
if(((rxdnet->bytes.bytebuf[0]&0x01)==0)
||(rxdnet->bytes.bytebuf[1]>0x7F)
||(rxdnet->bytes.bytebuf[1]<0x4C)
||(rxdnet->bytes.bytebuf[2]>0x06))
{
//接收状态错误,或者next_page_start错误或者长度错误,将丢弃所有数据包
page(1);
curr=reg07;      //page1
 page(0);          //切换回page0
bnry=curr-1;
if(bnry<0x4C) 
bnry=0x7F;
reg03=bnry;      //write to bnry     
return 0;
}
else 
//数据包是完好的.读取剩下的数据
{
//协议为IP或ARP才接收   
if((rxdnet->etherframe.protocal==0x0800)
||(rxdnet->etherframe.protocal==0x0806))        
{
     
reg09=bnry;   // BNRY寄存器的值写入RSAR1
reg08=4;      // 04写入RSAR0
reg0b=rxdnet->etherframe.length>>8; //写入远程DMA字节计数寄存器RBCR1
reg0a=rxdnet->etherframe.length&0xFF;//写入远程DMA字节计数寄存器RBCR0
reg00=0x0A;   //启动远程DMA读
for(ii=4;ii<rxdnet->etherframe.length+4;ii++)
     rxdnet->bytes.bytebuf[ii]=reg10; //从端口10读数据
}
bnry=rxdnet->bytes.bytebuf[1]-1;//
if(bnry<0x4C) 
bnry=0x7F;
reg03=bnry;      
return 1;         
}
} 
    return 0;
  }
  return 0;
}
   //发送一个数据包的命令,长度最小为60字节,最大1514字节需要发送的数据包要先存放在txdnet缓冲区
void send_packet(union netcard *txdnet, unsigned int length)
 {
    unsigned char i;
    unsigned int ii;
    page(0); //选择第0页寄存器
    if (length<60) length=60;
        reg00=0x12;    // 开始远程DMA操作
        for (ii=4;ii<length+4;ii++) //数据通过10H端口写入RTL8019AS
           reg10=txdnet->bytes.bytebuf[ii]; 
        	  reg09=0x40; //RSAR1 写入远程DMA的起始地址高八位
           reg08=0x00;    //RSAR0 写入远程DMA的起始地址高八位
           reg0b=length>>8; //RBCR1 数据包字节长度高八位
           reg0a=length&0xFF;  //RBCR0 数据包长度字节低八位
    for(i=0;i<6;i++){                   //最多重发6次
        for(ii=0;ii<1000;ii++)         
            if((reg00&0x04)==0) //检查TXP为是否为0
 break;
            if((reg04&0x01)!=0) //判断RTX是否为1
 break;      //表示发送成功        
         reg00=0x1E;
    }
}

⌨️ 快捷键说明

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