📄 eth.c
字号:
/*
*****************************************************************************************************
*
* File name: eth.c
*****************************************************************************************************
*/
#include "..\head\includes.h"
bit txd_buffer_select=0; //选择网卡的发送缓冲区 //用于标识网卡是否收到数据包
xdata union netcard rxdnet; //接收缓冲区
xdata union netcard txdnet; //发送缓冲区
xdata union Ethernet_address my_ethernet_address; //本机的以太网地址 //存放网卡的MAC地址.在初始化网卡时,用该数组里的内容对PAR0~PARA5进行赋值
//当然,在初始化之前一定要从X5045里读出该参数.在调试时,可以先对该数组赋值.
xdata union Ethernet_address gateway_ethernet_address; //网关的以太网地址
xdata union IP_address my_ip_address; //本机的ip地址
xdata union IP_address temp_ip_address; //用于存放临时IP地址
xdata union IP_address gateway_ip_address; //网关的ip地址
xdata union IP_address mask_ip_address; //子网掩码
unsigned int frameindex=0; //IP包的序列号
//unsigned char xdata netRxBuf[MCU_RECV_RAM]; //收发缓冲区实体
//unsigned char xdata *pNetIn,*pNetOut;
/*
*****************************************************************************************************
*FUNC: 选择页面
*NOTE:
*****************************************************************************************************
*/
void page(unsigned char pagenumber)
{
unsigned char data temp;
temp = reg00;
temp = temp&0x3B ; //不改变RD2—RD0,以及最后两位0011 1011
pagenumber = pagenumber << 6;
temp = temp | pagenumber;
reg00 = temp;
}
/*
*****************************************************************************************************
*FUNC: 将网卡软复位
*NOTE:
*****************************************************************************************************
*/
void Rtl8019_Reset(void) //复位网卡
{
// unsigned char data temp;
//对18h进行读写操作
// page(0);
// reg18=temp;
// temp=reg18;
NETRSTPIN = 1;
DelayHMSM(0,0,0,20); // 延时20MS
NETRSTPIN = 0;
}
/*
*****************************************************************************************************
*FUNC: 读出网卡的物理地址
*NOTE:
*****************************************************************************************************
*/
#if 0
void ReadRtl8019NodeID(void)//读出网卡的物理地址存到my_ethernet_address.bytes[6]里
{
unsigned char i;
unsigned char value[6]=0;
page(0);
reg09=0; //读取网卡的ram的地址为0x0000
reg08=0;
reg0b=0;
reg0a=12; //读取12个字节
reg00=0x0a; //读ram
for (i=0;i<6;i++)
{
value[i]=reg10;
value[i]=reg10;
}
}
#endif
/*
*****************************************************************************************************
*FUNC: 设置网卡的MAC地址
*NOTE:
*****************************************************************************************************
*/
void WriteRtl8019NodeID()
{
page(1);
reg01=my_ethernet_address.bytes[0];
reg02=my_ethernet_address.bytes[1];
reg03=my_ethernet_address.bytes[2];
reg04=my_ethernet_address.bytes[3];
reg05=my_ethernet_address.bytes[4];
reg06=my_ethernet_address.bytes[5];
page(0);
}
/*
*****************************************************************************************************
*FUNC: 初始化网卡
*NOTE:
*****************************************************************************************************
*/
void Rtl8019Init(void)
{
Rtl8019_Reset(); //复位8019
reg00=0x21; //使芯片处于停止模式,这时进行寄存器设置 停止模式下,将不会发送和接收数据包
DelayHMSM(0,0,0,20); // 延时20MS //延时500毫秒,确保芯片进入停止模式
page(0);
reg0a=0x00;
reg0b=0x00;
reg0c= 0xe0; //monitor mode (no packet receive)
reg0d= 0xe2; //loop back mode 使芯片处于mon和loopback模式,跟外部网络断开
//使用0x40-0x4B为网卡的发送缓冲区,共12页,刚好可以存储2个最大的以太网包。
//使用0x4c-0x7f为网卡的接收缓冲区,共52页。
reg01=0x4c; //PSTART
reg02=0x80; //PSTOP
reg03=0x4c; //BNRY
reg04=0x40; //TPSR
reg07=0xff; //清除所有中断标志位
reg0f=0x00; //disable all interrupt
reg0e=0xc8; //byte dma 8位dma方式
page(1);
reg07=0x4d; reg08=0x00; reg09=0x00; reg0a=0x00; reg0b=0x00;
reg0c=0x00; reg0d=0x00; reg0e=0x00; reg0f=0x00;
reg00=0x22; //这时让芯片开始工作
//ReadRtl8019NodeID(); //读出网卡的物理地址48位
WriteRtl8019NodeID(); //将网卡地址写入到mar寄存器
page(0);
reg0c=0xcc; //将网卡设置成正常的模式,跟外部网络连接
reg0d=0xe0;
//设置单片机接收缓冲区实体
// pNetIn = netRxBuf;
// pNetOut = netRxBuf;
reg00=0x22; //这时让芯片开始工作
reg07=0xff; //清除所有中断标志位
}
/*
*****************************************************************************************************
*FUNC: 发送一个包
*NOTE: 入参: 指向发送包联合体的指针(netcard *类型),发送字节数
*****************************************************************************************************
*/
void send_packet(union netcard xdata *pTxdnet,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++)
pTxdnet->etherframe.uSourceID[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
reg0a=Length&0xFF; //read count low;
reg00=0x12; //write dma, page0
//加4的原因是8019as的收发包的结构不一样
for(ii=4;ii<Length+4;ii++)
reg10=pTxdnet->bytes.bytebuf[ii];
/* 以下3句为中止dma的操作 */
reg0b=0x00; //read count high 中止DMA操作
reg0a=0x00; //read count low;
reg00=0x22; //complete dma page 0
//下面的循环的作用是保证上一个包已经成功发送。发送完成的标志是REG00的第二位为0,
//发送成功(发送没有错误)的标志是发送状态寄存器(REG04)最后一位为1.读者Mingtree注释.
for(i=0;i<6;i++){ //最多重发6次
for(ii=0;ii<1000;ii++) //检查txp为是否为低
if((reg00&0x04)==0) break;
if((reg04&0x01)!=0) break; //表示发送成功(应该是表示上一个数据包发送成功)
reg00=0x3E;
}
if(txd_buffer_select)
reg04=0x40; //txd packet start;
else reg04=0x46; //txd packet start;
reg06=Length>>8; //high byte counter
reg05=Length&0xFF; //low byte counter
reg00=0x3E; //to sendpacket;
}
/*
*****************************************************************************************************
*FUNC: 接收一个包
*NOTE: 入参: 指向发送包联合体的指针(netcard *类型).接收的包的长度在包首部里
返回值: unsigned char类型的值,0表示没收到包,1表示收到包
*****************************************************************************************************
*/
unsigned char recv_packet(union netcard xdata *pRxdnet)//ne2000收包子程序
{
unsigned char i;
unsigned int ii;
unsigned char bnry,curr;
// unsigned char ucPacket; //收到包的数目,最多收208个包,所以可以用一个字节
// unsigned char bPacket; //表示是否还有包
// unsigned char xdata *pTemp;
// bPacket = TRUE;
page(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -