W5500以太网控制器芯片(三):实现DHCP服务

#W5500以太网控制芯片相关文章链接#

上一篇文章:

W5500以太网控制器芯片(二):ioLibrary库实现TCP客户端

如果要W5500的IP动态分配,则要实现DHCP功能,实现流程如下:

准备工具(和上篇一致):

a、电脑上装一个网络调试工具,做TCP服务器用

b、一个路由器,后面电脑和W5500都要接到路由器上

c、W5500+支持SPI接口的MCU或者SOC

d、官方的ioLibrary库文件


1、移植驱动

除了之前引入的文件,还要将固件库里Internet文件夹下的DHCP文件夹的文件引入你的项目工程中,分别是dhcp.c和dhcp.h

 2、初始化DHCP

(1)此处从NETINFO_STATIC改为NETINFO_DHCP

//Default Network Configuration
wiz_NetInfo gWIZNETINFO = { 
	.mac = {0x00, 0x08, 0xdc,0x00, 0xab, 0xcd},
	.ip = {192, 168, 1, 123},
	.sn = {255,255,255,0},
	.gw = {192, 168, 1, 1},
	.dns = {114,114,114,114},
	.dhcp = NETINFO_DHCP,
};

(2)新增、更改几个函数

/*******************************************************
 * @ brief Call back for ip assing & ip update from DHCP
 *******************************************************/
void my_ip_assign(void)
{
   getIPfromDHCP(gWIZNETINFO.ip);
   getGWfromDHCP(gWIZNETINFO.gw);
   getSNfromDHCP(gWIZNETINFO.sn);
   getDNSfromDHCP(gWIZNETINFO.dns);
   gWIZNETINFO.dhcp = NETINFO_DHCP;
   /* Network initialization */
   network_init();      // apply from dhcp
   printf("DHCP LEASED TIME : %ld Sec.\r\n", getDHCPLeasetime());
}

/************************************
 * @ brief Call back for ip Conflict
 ************************************/
void my_ip_conflict(void)
{
	printf("CONFLICT IP from DHCP\r\n");
   //halt or reset or any...
   while(1); // this example is halt.
}

//网络初始化(DHCP)
void network_init(void)
{
	uint8_t tmpstr[6] = {0,};
	wiz_NetInfo netinfo;

	// Set Network information from netinfo structure
	ctlnetwork(CN_SET_NETINFO, (void*)&gWIZNETINFO);

	// Get Network information
	ctlnetwork(CN_GET_NETINFO, (void*)&netinfo);

	// Display Network Information
	ctlwizchip(CW_GET_ID,(void*)tmpstr);

	if(netinfo.dhcp == NETINFO_DHCP) printf("\r\n=== %s NET CONF : DHCP ===\r\n",(char*)tmpstr);
	else printf("\r\n=== %s NET CONF : Static ===\r\n",(char*)tmpstr);

	printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n",netinfo.mac[0],netinfo.mac[1],netinfo.mac[2],
			netinfo.mac[3],netinfo.mac[4],netinfo.mac[5]);
	printf("SIP: %d.%d.%d.%d\r\n", netinfo.ip[0],netinfo.ip[1],netinfo.ip[2],netinfo.ip[3]);
	printf("GAR: %d.%d.%d.%d\r\n", netinfo.gw[0],netinfo.gw[1],netinfo.gw[2],netinfo.gw[3]);
	printf("SUB: %d.%d.%d.%d\r\n", netinfo.sn[0],netinfo.sn[1],netinfo.sn[2],netinfo.sn[3]);
	printf("DNS: %d.%d.%d.%d\r\n", netinfo.dns[0],netinfo.dns[1],netinfo.dns[2],netinfo.dns[3]);
	printf("===========================\r\n");
}

(3)主函数更改:初始化DHCP服务,分配IP,随后连接远程的TCP服务器

#include "socket.h"	// Just include one header for WIZCHIP
#include "dhcp.h"

#define SOCK_TCPC       0
#define SOCK_TCPS       1
#define SOCK_DHCP       2

#define MY_MAX_DHCP_RETRY	3
#define DATA_BUF_SIZE   2048

int main(void)
{
	delay_init();	    	 	//延时函数初始化
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2

	uart_init(115200);	 	//串口初始化
		
	LED_Init();
 
	SPI2_Init();

	/* Critical section callback */
	//reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit);	//注册临界区函数
	reg_wizchip_cris_cbfunc(NULL, NULL); // 注册临界区函数
		
	reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);// 注册片选函数

	/* SPI Read & Write callback function */
	reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte);	//注册读写函数
 
	/* WIZCHIP SOCKET Buffer initialize */
	if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1){
		 printf("WIZCHIP Initialized fail.\r\n");
		 while(1);
	}

	/* PHY link status check */
	do{
		 if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1){
				printf("Unknown PHY Link stauts.\r\n");
		 }
	}while(tmp == PHY_LINK_OFF);
	
	/* Network initialization */
//	network_init();      //使用DHCP屏蔽此处
	
    // must be set the default mac before DHCP started.
    setSHAR(gWIZNETINFO.mac);
	
	DHCP_init(SOCK_DHCP, gDATABUF);
	
	// if you want defiffent action instead defalut ip assign,update, conflict,
	// if cbfunc == 0, act as default.
	reg_dhcp_cbfunc(my_ip_assign, my_ip_assign, my_ip_conflict);
	
   /* Main loop */
	while(1)
	{
		dhcp_test();
		
		delay_ms(100);
		LED1 = 0;
		delay_ms(100);
		LED1 = 1;

	} // end of Main loop
}

uint8_t my_dhcp_retry = 0;

//dhcp测试
void dhcp_test(void)
{
	    uint8_t res= 0;
	
    	switch(DHCP_run())
		{
			case DHCP_IP_ASSIGN:
			case DHCP_IP_CHANGED:
				/* If this block empty, act with default_ip_assign & default_ip_update */
				//
				// This example calls my_ip_assign in the two case.
				//
				// Add to ...
				//
				break;
			case DHCP_IP_LEASED:
				//
				// TO DO YOUR NETWORK APPs.
				loopback_tcpc(SOCK_TCPS, gDATABUF, dest_ip, dest_port);
				break;
			case DHCP_FAILED:
				/* ===== Example pseudo code =====  */
				// The below code can be replaced your code or omitted.
				// if omitted, retry to process DHCP
				my_dhcp_retry++;
				if(my_dhcp_retry > MY_MAX_DHCP_RETRY)
				{
					printf(">> DHCP %d Failed\r\n", my_dhcp_retry);
					my_dhcp_retry = 0;
					DHCP_stop();      // if restart, recall DHCP_init()
					network_init();   // apply the default static network and print out netinfo to serial
				}
				break;
			default:
				break;
		}
}

4、更改完成,上电验证结果

我们原先程序里的 ip是这样的:

//Default Network Configuration
wiz_NetInfo gWIZNETINFO = { 
	.mac = {0x00, 0x08, 0xdc,0x00, 0xab, 0xcd},
	.ip = {192, 168, 1, 123},
	.sn = {255,255,255,0},
	.gw = {192, 168, 1, 1},
	.dns = {114,114,114,114},
	.dhcp = NETINFO_DHCP,
};

使用DHCP服务后,发生了变更:



可以看到,网关10.1.1.1给W5500分配了10.1.1.237作为IP,DHCP服务生效,随后连接上了远程服务器。

现在只要将设备连接到提供DHCP服务的网口上,无论区域网实际的网段是什么,W5500都会分配到一个在该网段下的IP,连接上远程服务器。程序里的IP、网关随便填一个即可,DHCP服务会将其分配好。

需要注意的是:分配IP是根据设备MAC地址的,所以MAC在同一个网段里应是唯一的,否则分配IP可能会出现问题。
 

下一篇:​​​​​​​
W5500以太网控制器芯片(四):实现DNS功能

  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值