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 + -
显示快捷键?