main.c
来自「这是一个用单片机控制网卡传输的程序,集成了TCP/IP协议,使用硬件为89C51」· C语言 代码 · 共 1,752 行 · 第 1/4 页
C
1,752 行
unsigned char count;
unsigned int dataes;
//address=address|0x80;
R8019as_reg00=0xe2;//select 3 page register
//first bit 1
R8019as_reg01=0x8a;//1000 1010 cs=1 ck=0 di=1
R8019as_reg01=0x8e;//1000 1110 cs=1 ck=1 di=1
// set Opcode 1 0 read mode by read timing cycle
R8019as_reg01=0x8a;//1000 1010 cs=1 ck=0 di=1
R8019as_reg01=0x8e;//1000 1110 cs=1 ck=1 di=1
R8019as_reg01=0x88;//1000 1010 cs=1 ck=0 di=0
R8019as_reg01=0x8c;//1000 1110 cs=1 ck=1 di=0
do_93c46(address);//input address
for(count=0;count<16;count++)
{
//out 0
R8019as_reg01=0x88;//1000 1010 cs=1 ck=0 di=0
R8019as_reg01=0x8c;//1000 1110 cs=1 ck=1 di=0
dataes=dataes<<1;
for((dataes&0x01)!=0)
{
dataes=dataes|0x01;
}
}
R8019as_reg01=0x88;//1000 1010 cs=1 ck=0 di=0
R8019as_reg01=0x00;//1000 1110 cs=0 ck=0 di=0 stop read or write of 93c46
return(dataes);
}
//14//
void write_93c46(unsigned char address,unsigned int value)
{
////93c46 commond register:
// 7 6 5 4 3 2 1 0
//eem1 eem0 nc nc eecs eeck eedi eedo
R8019as_reg00=0xe2;//select 3 page
// enable writing mode first bit 1
R8019as_reg01=0x8a;//1000 1010
R8019as_reg01=0x8e;//1000 1110
// set Opcode 0 1 write mode by write timing cycle
R8019as_reg01=0x80;//cs=1 ck=0 di=0
R8019as_reg01=0x8c;// cs=1 ck=1 di=0
R8019as_reg01=0x8a;//cs=1 ck=0 di=1
R8019as_reg01=0x8e;/cs=1 ck=1 di=1
//do_93c46(0x3c);
//R8019as_reg01=0x88;//1000 1000
//R8019as_reg01=0x00;//0000 0000 cs=0
// actual write
//R8019as_reg01=0x8a;//1000 1010
//R8019as_reg01=0x8e;//1000 1110
//address=address|0x40;
do_93c46(address);//write address
do_93c46(value>>8);// write high
do_93c46(value&0xff);//write low
R8019as_reg01=0x88;
R8019as_reg01=0x00;//0000 0000 cs=0
//waite for write finish
R8019as_reg01=0x88;
for(value=0;value<10000;value++)
{if((R8019as_reg01&0x01)!=0)break;
}//可以防止死掉
R8019as_reg01=0x00;
//disable promgramming 1 0000 0000
R8019as_reg01=0x8a;
R8019as_reg01=0x8e;
do_93c46(0x00);
R8019as_reg01=0x88;
R8019as_reg01=0x00;
}
void delay_ms(unsigned char ms_number)
{
unsigned int i;
unsigned char j;
for(j = 0; j < ms_number; j++)
for(i = 0; i < 229; i++);
}
void delay_100ms(unsigned char number)
{
unsigned char i;
for (i = 0; i < number; i++)
{
delay_ms(100);
}
}
void send_char(unsigned char ascii)
{
EA = 0;
comtxdbuf[comtxdwrite] = ascii;
comtxdwrite++;
if(comtxdwrite == com_txd_buffer_size)
comtxdwrite = 0;
if(comtxdbufempty)
{
TI = 1;
}
EA = 1;
}
void send_string(unsigned char code *string)
{
while(*string != 0)
{
send_char(*string);
string++;
}
}
void send_hex(unsigned char senddata)
{
unsigned char ch;
ch = senddata >> 4;
send_char(hex[ch]);
ch = senddata & 0x0F;
send_char(hex[ch]);
}
void send_word(unsigned int asciiword)
{
unsigned char ascii;
ascii = asciiword >> 8;
send_hex(ascii);
ascii = asciiword & 0xff;
send_hex(ascii);
}
void send_long(unsigned long asciilong)
{
send_word(asciilong >> 16);
send_word(asciilong & 0xffff);
}
/*void timer0_init()
{
timer0_mode_16bit;
TH0 = 0;
TL0 = 0;
timer0_run;
}
*/
/*void serial_init()
{
serial_baud_9600; //22.1184 mhz 19200bps
serial_uart_8;
serial_receive_enable;
TI = 1;
}
void interrupt_init(void)
{
timer2_interrupt_disable;
timer0_interrupt_enable;
timer1_interrupt_disable;
int0_interrupt_disable;
// timer0_priority_high;
int1_interrupt_disable;
serial_priority_high;
serial_interrupt_enable;
int0_mode_hightolow;
// int0_priority_low;
}
//NEW (NAME : MyInterrupt_init()
void MyInterrupt_init()
{
interrupt_init();
p1_5 = 0;
IOADDR_Int_IRQC3 = 0x00; //中断3复位
IOADDR_Int_IRQC4 = 0x00; //中断4复位
IOADDR_Int_IRQC5 = 0x00; //中断5复位
IOADDR_Int_IRQC6 = 0x00; //中断6复位
IOADDR_Int_IRQC7 = 0x00; //中断7复位
IOADDR_Int_IRQC2 = 0x00; //中断2复位
// mk=IOADDR_Int_Status; //读取各中断位的状态
p1_5 = 1;
int1_mode_level;
int1_interrupt_enable;
}
*/
unsigned char string_compare(unsigned char code *string,uchar number)
{
//字符串比较,比较给定的字符串和命令缓冲区是否一样
unsigned char i;
unsigned char temp;
for (i = 0; i < number; i++)
{
temp = command_buffer[i];
if(temp != (*string))
{
return(0);
}
string++;
}
return(1);
}
///////////////////主函数流程///////////////////////////////////////////
//using namespace std;
void main()
{int i;
///////定义存储区///////////////
comrxdbuf=0x0000;
comtxdbuf=0x2000;
serrxdbuf=0x4000;
sertxdbuf=0x4400;
//////////////////网卡驱动流程/////////////////////////////////////////
rtl8019as_reset();
serial_init();
rtl8019as_init();
//在RTL8019AS中,用的是16位的模式,也就是总共有64个16位的存储单元.16位方式下,存储地址为0---63 .
//每个地址存储两个字节,低位字节在前,高位字节在后
write_93c46(0x02,0x8A48);//write mac address
write_93c46(0x03,0x35AB);//0x52,0x54,0xAB,0x35,0x48,0x8A(52:54:AB:35:48:8A)
write_93c46(0x04,0x5452);
delay_ms(20);
my_ethernet_address.words[0] =read_93c64(0x02);
my_ethernet_address.words[1] =read_93c64(0x03);
my_ethernet_address.words[2] =read_93c46(0x04);
//readmynodeid_self();
writemynodeid();
//////////////////协议栈处理函数流程//////////////////////////////////////
readmask();
readnetgate();
readmyipadd();
delay_ms(8);
//my_ip_address.dwords=MY_IPADDRESS;//192.168.0.8
// my_ip_address.dwords=MyIPAddress; //me
//gateway_ip_address.dwords=My_GATEWAY;//192.168.0.3
// gateway_ip_address.dwords=MyGateway; //me
//mask_ip_address.dwords=0xffffff00; //255.255.255.0 子网掩码
// mask_ip_address.dwords=MyMask; //me
ping_ip_address.dwords=0x00000000;
send_string("\r\nIP ADDRESS=");
send_word(my_ip_address.words[0]);
send_word(my_ip_address.words[1]);
send_string("\r\nGateWay IP ADDRESS=");
send_long(gateway_ip_address.dwords);
send_string("\r\nNet_mask=");
send_long(mask_ip_address.dwords);
delay_ms(10);
send_string("\r\nC:\>");
while(1)
{process_command();
process_ping();
process_telnet();
process_udp_command();
gateway_arp_request();
for(i=0;i<5;i++)
{ if(check_new_packet())
{
if(rxdnet.etherframe.protocal==0x0806)
{
//表示收到一个arp请求包
if(rxdnet.arpframe.operation==0x0001)
arp_answer();//处理arp数据包
else
if( rxdnet.arpframe.operation==0x0002)
arp_process();
}
else
if(rxdnet.etherframe.protocal == 0x0800)
if((rxdnet.ipframe.verandihl&0xf0) == 0x40)
if(verifyipheadcrc())//仅处理ip v4
{ //表示收到一个ip包
switch(rxdnet.ipframe.protocal)
{
case 1://表示为icmp协议
if(rxdnet.icmpframe.type == 8) //是一个ping的请求包
ping_answer();
else
if(rxdnet.icmpframe.type == 0)
ping_echo(); //是一个ping的应答包
break;
//case 6: //表示是tcp协议
// process_tcp();
// break;
case 0x11: //表示是udp协议
process_udp();
//复制发送buffer的数据给串口发送buffer,启动发送即可
for(sertxdwrite =0; sertxdwrite < rxdnet.udpframe.length ; sertxdwrite++)
{ uint ii=0;
if(ii<rxdnet.udpframe.lengeh-8)
{sertxdbuf(sertxdwrite)=rxdnet.udpframe.udpdata[ii];
ii++;
}
}
serial_init( );
break;
default:;
}
}
}
}
}
void serial(void) interrupt 4
{
unsigned char temp;
bit store_bit;
store_bit=p2_7; //现在只对存贮器操作,不进行IO操作,中断中须有这三句(包括结束后恢复原值)
p2_7=0;
if(TI)
{
TI=0;
if(sertxdread != sertxdwrite)
{
SBUF = sertxdbuf[sertxdread];
sertxdread++;
if(sertxdread == ser_txd_buffer_size)
sertxdread = 0x0000;
sertxdbufempty = 0;
}
else
{
sertxdbufempty = 1;
}
}
if (RI)
{
RI = 0;
temp = SBUF;
//处理自己的串口修改网络配置的命令
if(serrxdread==serrxdwrite) //注意:如果那段用到读指针,用完要清零
{
serrxdbuf[serrxdwrite] = temp;//从0x4000开始
serrxdwrite++;
serrxdbuffull=0;
}
if(serrxdwrite == ser_rxd_buffer_size) //判断是否接受到了1k个字节的数据
{
serrxdwrite=0;
send_string("buffer is full");
serrxdbuffull=1;
}
if( serrxdwrite> ser_rxd_buffer_size)
{
serrxdwrite = ser_rxd_buffer_size; //此时ser_rxd_buffer_size超过1k,所以要恢复成1k,避免意外
}
////////////////////////////////////////////////
/* //屏蔽吊系统原有的串口接受处理
comrxdbuf[comrxdwrite] = temp;
if(!tcpconnect)
{
send_char(temp);
}
comrxdwrite++;
if(comrxdwrite == com_txd_buffer_size)
comrxdwrite = 0;
if(temp == 0x0d)
{
if(!tcpconnect)
{
send_char(0x0a);
}
}
*/
}
p2_7 = store_bit;
}
}
/*
void timer0() interrupt 1
{
//工作在16位定时模式,中断时间为10毫秒中断一次,误差小于千分之1,晶振使用22.1184Mhz
bit store_bit;
store_bit = p2_7; //现在只对存贮器操作,不进行IO操作,中断中须有这三句(包括结束后恢复原值)
p2_7 = 0;
TL0 = 9;
TH0 = 184;
msec++;
// tcp_time_out = 1;//
if(msec == 100)
{
//100分频,就是1秒一次
msec = 0;
sec++;
double_second = 1;
if(sec == 60)
{
sec = 0;//每分钟一次
min++;
if(min == 60)
min = 0;
if(gateway_ip_address_ttl > 0)
gateway_ip_address_ttl = gateway_ip_address_ttl - 1;
if(ping_ip_address_ttl > 0)
ping_ip_address_ttl = ping_ip_address_ttl - 1;
}
}
p2_7=store_bit;
}
*/
}
//软件个部分测试方法和具体步骤。。。。。。。。。。。。。。。。。。
//1,串口测试
//编写小调试程序,通过调试灯验证
//2,服务器测试
//1),调试指示灯部分(单片机,晶振,电源,网卡,
//2) PING,ARP,UDP分级测试
//硬件个部分调试方法和具体步骤....................................
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?