📄 main.c
字号:
create_ip_packet(datalength, ip_address >> 16, ip_address&0xffff, 17);
}
//40//
void process_udp_command()
{
if(udp_count > 0)
{
udp_count--;
if(udp_count > 0)
{
if(ping_ip_address_ttl > 0)
{
//表示ip地址已经解析
udp_request(ping_ip_address.dwords ,port.word);
udp_count=0;
}
else
{
//解析ip地址
arp_request(ping_ip_address.dwords);
}
if(ping_ip_address.dwords==my_ip_address.dwords)
{
//ping的是自己的ip地址
send_string("\r\nCannot connect self");
udp_count=0;
}
}
}
}
/*//41//
void create_ethernet_packet()
{
...
}
*/
//42//
void serial_init()
{
//scon
//SM0 SM1 SM2 REN TB8 RB8 TI RI
TMOD=0x20;//time1 mode2
TL1=0xf4;//bps:9600
TH1=0xf4;
TR1=1;
PCON=0x00;
SCON=0x50;//MODE1 start receive
TI=1;
}
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
void readmyipadd()
{my_ip_address.bytes[0]=Myipaddr[0];
my_ip_address.bytes[1]=Myipaddr[1];
my_ip_address.bytes[2]=Myipaddr[2];
my_ip_address.bytes[3]=Myipaddr[3];
}
void readnetgate()
{gateway_ip_address.bytes[0]=MyNetgate[0];
gateway_ip_address.bytes[1]=MyNetgate[1];
gateway_ip_address.bytes[2]=MyNetgate[2];
gateway_ip_address.bytes[3]=MyNetgate[3];
}
void readmask()
{
mask_ip_address.bytes[0]=MyMaskip[0];
mask_ip_address.bytes[1]=MyMaskip[1];
mask_ip_address.bytes[2]=MyMaskip[2];
mask_ip_address.bytes[3]=MyMaskip[3];
}
//1//
void write_register(unsigned char address_offset,unsigned char value)
{
unsigned char xdata* regbasetemp = R8019as_regbase + address_offset;
bit tempbit;
tempbit = p2_7;
p2_7 = 1;
*regbasetemp = value;
p2_7 = tempbit;
}
//2//
unsigned char read_register(unsigned char addr)
{
unsigned char temp;
unsigned char xdata* regbasetemp = R8019as_regbase + addr;
bit tempbit;
tempbit = p2_7;
p2_7 = 1;
temp = *regbasetemp;
p2_7 = tempbit;
return(temp);
}
//3//
void write_dma_port(unsigned char value)
{
bit tempbit;
tempbit = p2_7;
p2_7 = 1;
R8019as_reg16 = value;
p2_7 = tempbit;
}
//4//
unsigned char read_dma_port()
{
unsigned char temp;
bit tempbit;
tempbit = p2_7;
p2_7 = 1;
temp = R8019as_reg16;
p2_7 = tempbit;
return(temp);
}
//5//
void rtl8019as_page(unsigned char pagenumber)
{
unsigned char data temp;
bit tempbit;
tempbit = p2_7;
p2_7 = 1;
temp = R8019as_reg00;
p2_7 = 0;
temp = temp & 0x3B; //注意不是0x3F ,TXP位在平时一定要置为0.
pagenumber = pagenumber << 6;
temp = temp | pagenumber;
p2_7 = 1;
R8019as_reg00 = temp;
p2_7 = tempbit;
}
//加一函数(从9364中读物理地址和配置信息)
//6//
void readmynodeid_self()
{
my_ethernet_address.bytes[0]= NetCardNode[0];//52:54:AB:35:48:8A
my_ethernet_address.bytes[1]= NetCardNode[1];
my_ethernet_address.bytes[2]= NetCardNode[2];
my_ethernet_address.bytes[3]= NetCardNode[3];
my_ethernet_address.bytes[4]= NetCardNode[4];
my_ethernet_address.bytes[5]= NetCardNode[5];
}
//7//
void writemynodeid()
{
unsigned char wtemp1;
bit tempbit;
tempbit = p2_7;
rtl8019as_page(1);
p2_7 = 0;
wtemp1 = my_ethernet_address.bytes[0];
p2_7 = 1;
R8019as_reg01 = wtemp1;//PAR0,实际地址寄存器:这些寄存器包括以太网节点地址且用来对目标地址数据包进行比较来确定接收或者拒绝接收。
p2_7=0;
wtemp1 = my_ethernet_address.bytes[1];
p2_7 = 1;
R8019as_reg02 = wtemp1;//PAR1
p2_7 = 0;
wtemp1 = my_ethernet_address.bytes[2];
p2_7 = 1;
R8019as_reg03 =wtemp1;//PAR2
p2_7 = 0;
wtemp1 = my_ethernet_address.bytes[3];
p2_7 = 1;
R8019as_reg04 = wtemp1;//PAR3
p2_7 = 0;
wtemp1 = my_ethernet_address.bytes[4];
p2_7 = 1;
R8019as_reg05 = wtemp1;//PAR4
p2_7 =0;
wtemp1 = my_ethernet_address.bytes[5];
p2_7 = 1;
R8019as_reg06 = wtemp1;//PAR5
p2_7 = tempbit;
}
//8//
void send_packet(unsigned int length)
{
//发送一个数据包的命令,长度最小为60字节,最大1514字节需要发送的数据包要先存放在txdnet缓冲区
unsigned char i;
unsigned int ii;
rtl8019as_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)
{
write_register(remote_start_address_register1, 0x40) ;//8019发送buffer第一页
}
else
{
write_register(remote_start_address_register1, 0x46) ;//8019发送buffer第二页
}
write_register(remote_start_address_register0, 0x00); //按页存储
write_register(remote_byte_count_register1, length >> 8);//read count high,远程DMA(单片机端)将要发送的字节数
write_register(remote_byte_count_register0, length & 0xff);//read count low;
write_register(command_register, 0x12);//remote write dma, page0,激活8019传送数据
//for(ii = 4; ii < length+4; ii++)
for(ii = 0; ii < length; ii++)
{
write_dma_port(txdnet.bytes.bytebuf[ii]);//数据传送:单片机发送缓存---〉8019register_16(远程DMA端口)
}
// 以下3句为中止dma的操作,可以不要
write_register(remote_byte_count_register1, 0x00);//read count high 中止DMA操作
write_register(remote_byte_count_register0, 0x00);//read count low;
write_register(command_register, 0x22);//complete dma page 0
//==============
for(i = 0; i < 16; i++)//最多重发16次
{
//write_register(command_register,0x3e);
write_register(command_register,0x1e);//select send packet
for(ii = 0; ii < 1000; ii++)
{//检查txp为是否为低
if((read_register(command_register)&0x04) == 0)
break;
}
if((read_register(transmit_status_register)&0x01)!=0)//表示发送成功
break;
}
write_register(interrupt_status_register,0xff);
/*if(txd_buffer_select)
write_register(transmit_page_start_register, 0x40);//txd packet start;
else
write_register(transmit_page_start_register, 0x46);//txd packet start;
write_register(transmit_byte_count_register1, length >> 8);//high byte counter
write_register(transmit_byte_count_register0, length & 0xff);//low byte counter
write_register(interrupt_status_register, 0xff);
write_register(command_register, 0x3e);//to sendpacket;
*/
}
//9//
void rtl8019as_reset()
{
unsigned char temp;
bit tempbit;
tempbit = p2_7;
p2_7 = 1;
temp = R8019as_reg31;//读网卡的复位端口
R8019as_reg31 = temp; //写网卡的复位端口
p2_7 = tempbit;
}
//10//
void rtl8019as_init()//i write it myself
{
bit tempbit;
tempbit = p2_7;
p2_7 = 1;
R8019as_reg00 = 0x21; //选择页0的寄存器,网卡停止运行,因为还没有初始化。
// R8019as_reg07=0xff;//清除中断寄存器 ISR
R8019as_reg01 = 0x4c; //寄存器Pstart (receive buffer)
R8019as_reg02 = 0x80; //Pstop
R8019as_reg03 = 0x4c; //BNRY
R8019as_reg04 = 0x45; //TPSR
R8019as_reg12 = 0xcc; //RCR
// R8019as-reg12=0xca;//广播包不接受,少于60字节的接受
R8019as_reg13 = 0xe0; //TCR
R8019as_reg14 = 0xc8; //DCR 数据配置寄存器 8位数据dma
R8019as_reg15 = 0x00; //IMR disable all interrupt
p2_7 = 0;
rtl8019as_page(1); //选择页1的寄存器
p2_7 = 1;
R8019as_reg07 = 0x4d; //CURR
R8019as_reg08 = 0x00; //MAR0 清除多播地址
R8019as_reg09 = 0x00; //MAR1
R8019as_reg10 = 0x00; //MAR2
R8019as_reg11 = 0x00; //MAR3
R8019as_reg12 = 0x00; //MAR4
R8019as_reg13 = 0x00; //MAR5
R8019as_reg14 = 0x00; //MAR6
R8019as_reg15 = 0x00; //MAR7
R8019as_reg00 = 0x22;//选择页0寄存器,网卡执行命令。
p2_7 = 0;
// readmynodeid_self(); //不使用93c46
// writemynodeid();
p2_7 = tempbit;
}
//11//
unsigned char check_new_packet()
{
//如果收到一个有效的数据包,返回1,否则返回0
unsigned char i;
unsigned int ii;
rtl8019as_page(0);
bnry = read_register(boundary_register);//bnry page have read 读页指针
rtl8019as_page(1);
curr = read_register(current_page_register);//curr writepoint 8019写页指针
rtl8019as_page(0);
if(curr == 0)
return(0);//读的过程出错
next_page = bnry;
bnry = bnry+1;
if(bnry > 0x7f)
bnry = 0x4c;
if(bnry != curr)
//此时表示有新的数据包在缓冲区里
{
rtl8019as_page(0);
//==============清除错误计数器,可以不做清除
read_register(tally_counter0); //page0 read
read_register(tally_counter1); //page0 read
read_register(tally_counter2); //page0 read
//==============
write_register(remote_start_address_register1, bnry);//read page address
write_register(remote_start_address_register0, 0x00); //read page address
write_register(remote_byte_count_register1, 0x00);//read head count 4+6+6+2=18
write_register(remote_byte_count_register0, 18);//先读头部
write_register(command_register, 0x0a);//read dma,数据发到单片机方向
for(i = 0; i < 18; i++)
{
rxdnet.bytes.bytebuf[i] = read_dma_port();
}
//以下3句为中止dma的操作,可以不要
write_register(remote_byte_count_register1, 0x00);//read count high 中止DMA操作
write_register(remote_byte_count_register0, 0x00);//read count low;
write_register(command_register, 0x22);//complete dma page 0
//==============
//将长度字段的高低字节掉转 使高字节在前
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错误或者长度错误,或者接收状态错误,将丢弃所有数据包
rtl8019as_page(1);
curr = read_register(current_page_register); //page1
rtl8019as_page(0);//切换回page0
bnry = curr -1;
if(bnry < 0x4c)
bnry = 0x7f;
write_register(boundary_register, bnry); //write to bnry
//===================下面这句清除中断状态可以不用
write_register(interrupt_status_register, 0xff);
return(0);
}
else
{//表示数据包是完好的.读取剩下的数据
//============
if((rxdnet.etherframe.protocal == 0x0800) || (rxdnet.etherframe.protocal == 0x0806))
{ //协议为IP或ARP才接收
write_register(remote_start_address_register1, bnry);//read page address high
write_register(remote_start_address_register0, 4); //read page address low
write_register(remote_byte_count_register1, rxdnet.etherframe.length >> 8);//read count high
write_register(remote_byte_count_register0, rxdnet.etherframe.length & 0xff);//read count low;
write_register(command_register, 0x0a);//read dma
for(ii = 4; ii < rxdnet.etherframe.length + 4; ii++)
{
rxdnet.bytes.bytebuf[ii] = read_dma_port();
}//读回数据为除去crc字和头部四个字的包,但是头部没被覆盖,此时整个缓冲区为有效的完整包
write_register(remote_byte_count_register1, 0x00);//read count high 中止DMA操作
write_register(remote_byte_count_register0, 0x00);//read count low;
write_register(command_register, 0x22);//dma complete page0
}
//=========================================
bnry = rxdnet.bytes.bytebuf[1]-1;//next page start-1
if(bnry < 0x4c)
bnry = 0x7f;
write_register(boundary_register, bnry); //write to bnry
write_register(interrupt_status_register,0xff);
return(1);//have new packet
}
}
return(0);
}
//12//
void do_93c46(unsigned char dataes)
{
//串行输入8位数据
//93c46 commond register:
// 7 6 5 4 3 2 1 0
//eem1 eem0 nc nc eecs eeck eedi eedo
unsigned char count;
for(count=0;count<8;count++)
{
if((dataes&0x80!)=0)
//input 1
R8019as_reg01=0x8a;//1000 1010 cs=1 ck=0 di=1
R8019as_reg01=0x8e;//1000 1110 cs=1 ck=1 di=1
else
// input 0
{R8019as_reg01=0x80;//1000 1010 cs=1 ck=0 di=0
R8019as_reg01=0x8c;//1000 1110 cs=1 ck=1 di=0
}
dataes=dataea<<1;
}
//13//
unsigned int read_93c46(unsigned char address)
{
//返回一个16位的数据;
//93c46 commond register:
// 7 6 5 4 3 2 1 0
//eem1 eem0 nc nc eecs eeck eedi eedo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -