Http://hi.baidu.com/mcu8031/blog/item/c95903138671c625dc540171.html
Microcontroller-driven dm9000 Nic chip (detailed debugging process) [bottom]
4. verify each function in initialization.
Next let's take a look at whether the above initialization function is available. We have written three functions as follows:
Dm9000_init (), sendpacket (), and receivepacket () are saved and named dm9000.c. Now that we want to debug, when
However, there must be output results. Write a serial program based on your processor. These functions are the basis for learning a single-chip microcomputer.
For a detailed introduction, it is necessary to comment out in the function.
Next we will write a main function, create a c file, name it mian. C, and fill in the following function:
Void main (void)
{
Unsigned int I;
Unsigned char C;
Uart0_init (); // initialize the serial port, used for debugging
Dm9000_init (); // initialize the NIC
Print_regs ();/* print the registers in dm9000 through the serial port and display them on the Super Terminal. This function is based on your own
To read the dm9000 register dm9000_reg_read () and print it through the serial port */
}
Write the function, save the file, connect the hardware, and connect the network cable to the computer or lan. The running result is shown in:
Figure 4 display register values
First, check whether each control register has its own written value. Check whether the Status Register is correct.
Check whether the bit [6] In the NSR register is "1". This bit indicates whether the connection is successful. In this example, the NSR value is 40 h, and the numbers in parentheses correspond
In decimal format.
Next we will improve the main function by adding an interrupt receiving function to check whether data can be received.
Void main (void)
{
Unsigned int I;
Unsigned char C;
Uart0_init (); // initialize the serial port, used for debugging
Dm9000_init (); // initialize the NIC
/*************************************** **************************************** */
/* Depending on your processor, connect the int pin of dm9000 to the External Interrupt of the processor and enable the interrupt */
/*************************************** **************************************** */
Sendpacket (60);/* I have already stored ARP REQUEST packets in buffer [], and sent them directly here to receive
ARP response packet. You can first refer to the later mentioned ARP Protocol to store data in buffer [] according to your own machine */
While (1); // wait for interruption
}
Void int_issue (void) // interrupt handler, which needs to be set based on your processor
{
Unsigned int I;
I = receivepacket (buffer); // read data to the buffer.
Int_again:
If (I = 0)
{
Return;
}
Else
{
Print_buffer (); // print all received data
While (1); // stop here for observation. Note: in practice, it is not allowed to stop in the interrupted state.
}
/*************************************** **************************************** *****/
/* Add this section to determine whether other data packets are received during the interruption. Yes. You can do it without adding it */
/* Determine whether the processor is still in the interrupted state based on its own processor. If so, skip this section. */
I = effecepacket (buffer );
If (I! = 0)
{
Goto int_again;
}
/*************************************** **************************************** *****/
}
Compilation and debugging:
Figure 5 data in received packets
This is an ARP response packet that contains the MAC address on my computer and the IP address in the LAN. I am not an important person anyway,
This is not confidential, huh, huh.
If something goes well, the initialization of the dm9000 Nic chip is complete. If a problem occurs, you must first
Check whether the register value is correct. You can print out the registers in the dm9000 to check the problem. If
The value is messy. Check whether the hardware connection and register read/write sequence are correct while ensuring that the serial port program is correct.
.
Iii. Implementation of ARP
1. ARP principles
Address Resolution Protocol (ARP), in the LAN, what is actually transmitted in the network is
Frame. The frame contains the MAC address of the target host. In Ethernet, one must be aware of the need to directly communicate with another host.
The MAC address of the target host. This MAC address is the unique address that identifies Our NIC chip. However, the target MAC address is as follows:
Why? This uses the Address Resolution Protocol we mentioned here. All "Address Resolution" means that the host will
The process of converting a standard IP address to a MAC address. The basic function of ARP is to query the MAC address of the target device through the IP address of the target device.
Address to ensure smooth communication. So before the first communication, we know the IP address of the target machine and want to know the IP address of the target machine.
MAC address, ARP packets (ARP packets) are sent ). Its transmission process is simply: I know the IP address of the target machine,
Then I will send an ARP request to all the machines in the network, with the IP address of the target machine in the request.
After receiving this request, you will be notified of your MAC address. If the target machine does not exist, no one will respond to this request. If the target
When the machine receives the request, it will send an ARP response, which is clearly sent to the requester and has a MAC address in the response. Connect me
At this point, I will know the MAC address of the target machine, and then I can continue communication. Because Mac is used for every communication.
Address.
ARP packets are encapsulated in the Ethernet frame header for transmission, which is the Header Format of arp request packets.
Figure 6 ARP request or response group format for Ethernet
Note that the transmission and storage of Ethernet is in the "big-end format", that is, sending high bytes before sending low bytes. For example, two bytes of data
First, send the 8-bit high and then send the 8-bit low. Therefore, pay attention to the storage sequence when receiving data.
The entire packet is divided into two parts: the Ethernet header and ARP request/response. The following highlights the situation.
"Ethernet Destination Address" field: if an ARP request is sent, enter the broadcast type MAC address FF-FF-FF-FF-FF-FF, meaning
Receive all machines on the network;
Frame Type field: Enter 08-06 to indicate that the next packet is an ARP protocol;
"Hardware type" field: enter to indicate the ethernet address, that is, the MAC address;
"Protocol type" field: Enter 08-00 to indicate the IP address, that is, query the MAC address through the IP address;
"Hardware address length" field: the MAC address length is 6 (in bytes );
"Protocol address length" field: the IP address length is 4 (in bytes );
"Operation Type" field: ARP packet type. 0 indicates ARP request, and 1 indicates ARP response;
"Destination ethernet address" field: if an ARP request is sent, it must be filled with the target machine.
2. ARP processing program
The principle of ARP is very simple. Next we will compile the ARP processing function. Name the new file arp. C and enter the following function:
:
Unsigned char mac_addr [6] = {*,*,*,*,*,*};
Unsigned char ip_addr [4] ={ 192,168 ,*,*};
Unsigned char host_ip_addr [4] = {192,168 ,*,*};
Unsigned char host_mac_addr [6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
Unsigned char buffer [1000];
Uint16 packet_len;
/* Some of these global variables have been defined in the previous file. Note that the "extern" keyword is added before. "
* "Should be modified based on your own machine */
# Define Hon (N) (uint16) (n) & 0xff) <8) | (n) & 0xff00)> 8 ))
/* This macro is used to convert the words (two bytes) stored in the small-end format to the large-end format for storage */
Void arp_request (void) // sends an ARP request packet
{
// Ethernet header
Memcpy (arpbuf-> ethhdr. d_mac, host_mac_addr, 6 );
/* String copy function. The file must contain the header file <string. h>. The parameters are: copy the target pointer, copy the data source pointer, and copy
Number of Bei characters */
Memcpy (arpbuf-> ethhdr. s_mac, mac_addr, 6 );
Arpbuf-> ethhdr. type = Hon (0x0806 );
/* The compiler in the small-end format can be converted to a large-end format using the Hon () Macro. If your compiler is in the large-end format, enter
0x0806 */
/* Is simply filled in according to the protocol format, the following is the same */
// ARP Header
Arpbuf-> hwtype = Hon (1 );
Arpbuf-> protocol = Hon (0x0800 );
Arpbuf-> hwlen = 6;
Arpbuf-> protolen = 4;
Arpbuf-> opcode = Hon (0 );
Memcpy (arpbuf-> SMAC, mac_addr, 6 );
Memcpy (arpbuf-> sipaddr, ip_addr, 4 );
Memcpy (arpbuf-> dipaddr, host_ip_addr, 4 );
Packet_len = 42; // 14 + 28 = 42
Sendpacket (buffer, packet_len );
}
Note: The macro definition and ARP header structure of arpbuf have been mentioned earlier. At the same time, pay attention to the interrupt processing when the function is executed. No
For processing.
It looks easy. The following function can handle ARP requests or ARP responses.
Unsigned char arp_process (void) // ARP receiving function. 1 is returned successfully; otherwise, 0 is returned.
{
// Check whether the ARP packet is damaged. If the packet is damaged, it is discarded and not processed.
If (packet_len <28) // ARP data with a length of 28 bytes is invalid data
{
Return 0;
}
Switch (HON (arpbuf-> opcode ))
{
Case 0: // process ARP requests
If (arpbuf-> dipaddr [0] = ip_addr [0] &
Arpbuf-> dipaddr [1] = ip_addr [1] &
Arpbuf-> dipaddr [2] = ip_addr [2] &
Arpbuf-> dipaddr [3] = ip_addr [3]) // determines whether the IP address is your own and whether to ask the MAC address.
.
{
Arpbuf-> opcode = Hon (2); // set it to ARP response
Memcpy (arpbuf-> DMAc, arpbuf-> SMAC, 6 );
Memcpy (arpbuf-> ethhdr. d_mac, arpbuf-> SMAC, 6 );
Memcpy (arpbuf-> SMAC, mac_addr, 6 );
Memcpy (arpbuf-> ethhdr. s_mac, mac_addr, 6 );
Memcpy (arpbuf-> dipaddr, arpbuf-> sipaddr, 4 );
Memcpy (arpbuf-> sipaddr, ip_addr, 4 );
Arpbuf-> ethhdr. type = Hon (0x0806 );
Packet_len = 42;
Sendpacket (buffer, packet_len); // sends ARP packets
Return 1;
}
Else
{
Return 0;
}
Break;
Case 1: // process ARP response
If (arpbuf-> dipaddr [0] = ip_addr [0] &
Arpbuf-> dipaddr [1] = ip_addr [1] &
Arpbuf-> dipaddr [2] = ip_addr [2] &
Arpbuf-> dipaddr [3] = ip_addr [3]) // determine whether the IP address is a response to itself.
{
Memcpy (host_mac_addr, arpbuf-> SMAC, 6); // Save the MAC address of the server
Return 1;
}
Else
{
Return 0;
}
Break;
Default: // not an ARP Protocol
Return 0;
}
}
It is not difficult to view the two functions according to the ARP Protocol format. So we get two more functions: arp_request () and
Arp_process ().
3. ARP program debugging
Next we will modify the main function and interrupt processing function.
Replace the "sendpacket (60);" statement in the mian () function with the "arp_request ();" statement.
Void int_issue (void) // interrupt handler, which needs to be set based on your processor
{
Unsigned int I;
I = receivepacket (buffer); // read data to the buffer.
If (I = 0)
{
Return;
}
Else
{
I = arp_process ();
If (I = 1) // checks whether the IP address is an ARP protocol.
Print_hostmacaddr (); // print the MAC address of the target machine, that is, use the serial port to print 6 of host_mac_addr []
Bytes
}
}
Save running debugging.
Figure 7 host MAC address
So far, the debugging process of dm9000 has been completed. Later, I also debugged UDP Communication and TCP communication, mainly about the protocol.
After processing, we will not introduce it here. If you are interested, you can refer to the first volume of TCP/IP protocol, which will be of great help. Hope that
The debugging process can provide readers with more or less useful information. You are welcome to discuss it with me.
My email: mengqx25@163.com