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

📄 rtl8019as.c

📁 用AVR单片机和RTL8019实现TCP/IP协议.支持ARP,PING,UDP,TCP,HTML网页显示等功能.
💻 C
字号:
//**********************************
//*版本: Test 1.0
//*作者: XUGUOHONG
//*E-MAIL: KK20Y@YAHOO.COM.CN
//*WEBSITE:microdesign.000webhost.com
//**********************************

#include <rtl8019as.h>
#include <iom162v.h>
//**********************************
//*  系统 MAC地址设定(根据需要修正)
//**********************************
unsigned char SYSMAC[6]={0X00,0X11,0X22,0X33,0X44,0X55};
//**********************************
//*  系统 IP地址设定(根据需要修正)
//**********************************
unsigned char SYSIP[4]={192,168,0,8};

void rtl8019as_init(void);
void int0_init(void);
void int0_neton(void);
void getpacket(void);
void sendpacket(unsigned int);

//*************************
//  RTL8019AS初始化
//*************************
void rtl8019as_init(void)
{
 unsigned char temp;
 rtl8019_rst( );                           // 硬件复位
 write_8019(RSTPORT,read_8019(RSTPORT));   // 软件复位
 delay_ms(20);                             // 复位等待建立
 if( read_8019(ISR)&0b10000000==0)
  {
                                           // 硬件故障处理
  }
 write_8019(CR,0X21);                      // 停止NIC,退出DMA,PAGE0
 delay_ms(20);                             // 等待
 write_8019(DCR,0X58);                     // 数据配置寄存器,
 write_8019(RBCR0,0X00);                   // 远端DMA字节计数寄存器0
 write_8019(RBCR1,0X00);                   // 远端DMA字节计数寄存器1
 write_8019(RCR,0X04);                     // 接收配置寄存器,
 //RING BUFFER中的地址分配
 //每页 256 BYTE
 //最大帧 1518 BYTE 0X05EE
 //TPSR发送起始地址:0x4000
 //      + 0x05EE =  0X45EE
 //PSTART页起始地址:0X4600
 //PSTOP页结束地址:  0X6000
 write_8019(TPSR,0X40);                    // 数据包发送开始页地址
 write_8019(TCR,0X02);                     // 发送配置寄存器,
 write_8019(PSTART,0X46);                  // 
 write_8019(BNRY,0X46);                    //
 write_8019(PSTOP,0X60);                   //
 write_8019(CR,0X61);                      // 选择第2页
 delay_ms(2);
 write_8019(CURR,0X46);
 for(temp=0;temp<6;temp++)
 write_8019(PAR0+temp,SYSMAC[temp]);       // 写入MAC地址
 write_8019(CR,0X21);
 delay_ms(20);
 write_8019(CR,0X22);
 write_8019(ISR,0xFF);                     // 清除中断标志位
 write_8019(IMR,0x11);                     // 中断屏蔽寄存器,置"1"允许相应的位
 write_8019(TCR,0x00);
}

//****************************
//       中断初始化
//****************************
void int0_init()
{
 MCUCR|=(0<<ISC01)|(1<<ISC00);
 GICR|=(1<<INT0);
 asm("sei");
}

//****************************
//       中断处理子程序
//1.中断开始说明有数据包接收
//2.首先,写入读命令
//3.读取前四个字节来计算包长度
//4.根据长度来循环读出数据
//5.在读取的过程中可能在有数据送入,而此时检测不到
//6.读取当前数据后,比较BNRY和CURR判断是否已将所有数据读出
//7.未读完,继续读取
//8.已读完,将BNRY和CURR恢复初值
//****************************
#pragma interrupt_handler int0_neton:iv_INT0
void int0_neton(void)
{
 unsigned char temp;
 unsigned char datah;
 unsigned char datal;
 asm("cli");                                 // 关闭中断                 
 temp= read_8019(ISR);   
 if( (temp&0b00010000)==0b00010000 )        // 是否OVERRUN
 {
   //overrun();                              // OVERRUN处理
    rtl8019as_init( );
    asm("sei");
 }
 else if( (temp&0b00000001)==0b00000001 )        // 数据包是否有错
 {
   getpacket();                              // 接收数据包
 }
 
 // 检测是否在8019缓存中还有其他数据包存在
 // 必须考虑在中断处理中有其他网络数据包接
 // 入而未检测到
 datah=read_8019(BNRY);                    // 检测BNRY是否等于CURR
 write_8019(CR,0x62);                      // BNRY=CURR数据已读完成
 datal=read_8019(CURR);
 write_8019(CR,0x22);
 while(datah<datal)   
 {                       
 getpacket();                              // BNRY!=CURR数据未读完,继续读 
 datah=read_8019(BNRY);                    // 检测BNRY是否等于CURR
 write_8019(CR,0x62);                      // BNRY=CURR数据已读完成
 datal=read_8019(CURR);
 write_8019(CR,0x22);
 }
 
 write_8019(BNRY,0X46);                    // 所有数据读完后,归位
 write_8019(CR,0X61);                      // 选择第2页
 write_8019(CURR,0X46);                    // 所有数据读完后,归位
 write_8019(CR,0X22);
 write_8019(ISR,0xFF); 
 asm("sei");
}

//************************************
//      数据包接收子程序
//1. 接收到一个数据包
//2. 处理一个数据包
//3. ***数据包在这里不适合用嵌套来完成检测和读取
//   ***因为这样会占用大量的RAM空间,从而使堆栈益出.
//************************************
void getpacket(void)
{
 unsigned char temp;
 unsigned int counter;
 unsigned char datah;
 unsigned char datal;
 unsigned int RXLEN;                       // 接收数据长度
 unsigned char PAGEHEADER[4];              // 接收数据,头四位数据
 write_8019(CR,0X1A);                      // 发送SEND PACKET命令来接受数据
 for(temp=0;temp<4;temp++)                 // 先读出头四位数据来计算数据包长度
 {
  PAGEHEADER[temp]=read_8019(RDMAPORT);    // 头四个数据先读出
 }
 RXLEN=PAGEHEADER[PACKETLENH];             // 计算数据包大小
 RXLEN=RXLEN<<8;
 RXLEN=RXLEN+PAGEHEADER[PACKETLENL];
 
 for(counter=0;counter<RXLEN;counter++)    // 将数据读入SRAM 62256
 {                                         // 从SRAM地址0X0000开始
  write_62256(counter,read_8019(RDMAPORT));   // 大小64-1518Byte
  //uart_send(read_62256(counter));
 }
 
 temp= read_8019(ISR); 
 while((temp&0b01000000)==0b00000000)       // 检测是否DMA完成
 {
  temp= read_8019(ISR);
 }
 
 //==================================================================
 //===对收到的数据包进行判断选择处理===   // 与协议上层接口
 datah=read_62256(12);                    // 数据包类型判断
 datal=read_62256(13);
 if( (datah==0x08)&&(datal==0x00) )
 {
   ip();
 }
 else if( (datah==0x08)&(datal==0x06) )
 {
   arp();                                // 已完成
 }
 else if( (datah==0x80)&(datal==0x35) )
 {
   //rarp();
 }
 else if( (datah==0x86)&(datal==0xdd) )
 {
   //ipv6();
 }
 else 
 {
  ;
 }
 //================================================================== 
}

//****************************
//      数据包发送子程序
//****************************
void sendpacket(unsigned int TXLEN)
{
 unsigned char temp;
 unsigned int counter;
 write_8019(CR,0X22);
 write_8019(ISR,0xFF);                     // 清除中断标志位  
 write_8019(RSAR0,0X00);                   // MCU写入buffer ring 的起始地址
 write_8019(RSAR1,0X40);
 write_8019(ISR,0xFF);                     // 清除中断标志位
 write_8019(RBCR0,TXLEN);                  // 写入数计数,MCU TO 8019 COUNTER
 write_8019(RBCR1,TXLEN>>8);    
 write_8019(CR,0X12);                      // 执行REMOTEWRTIE指令
 for(counter=0;counter<TXLEN;counter++)
{
 write_8019(RDMAPORT,read_62256(counter));
 //uart_send(read_62256(counter));
}  
 
 temp= read_8019(ISR); 
 while(temp&0b01000000==0b00000000)        // 等待DMA完成
     ;    
 write_8019(ISR,0xFF);                     // 清除中断标志位                
 write_8019(TBCR0,TXLEN);                  // 写入数计数,8019 TO NET COUNTER
 write_8019(TBCR1,TXLEN>>8); 
 write_8019(CR,0X24);                      // 开始MCU TO NET 发送
 temp= read_8019(ISR);                     // 等待数据发送完成
 while(temp&0b00000010==0b00000000)        // 等待数据发送无误结束
 temp= read_8019(ISR);                     // 
 write_8019(ISR,0xFF);                     // 清除中断标志位     
}

⌨️ 快捷键说明

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