#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可能会出现问题。 ?
|