在CH57x系列微控制器功能框图:
一、DHCP功能概述
动态主机配置协议(DHCP,Dynamic Host Configuration Protocol)是一种基于客户端-服务器架构的网络管理协议,用于自动分配IP地址及其他网络配置参数,允许服务器向客户端动态分配IP地址、子网掩码、网关和DNS服务器等网络配置信息。在CH57x系列微控制器中,通过配置和启动DHCP客户端,可以自动从网络中的DHCP服务器获取这些配置信息,从而简化网络配置过程。
二、DHCP功能实现步骤
1. 初始化网络库:
在使用DHCP功能之前,需要初始化CH57xNET库,配置MAC地址、缓冲区等。
2. 启动DHCP客户端:
调用`CH57xNET_DHCPStart`函数启动DHCP客户端,并设置回调函数处理DHCP事件。
3. 处理DHCP回调:
在DHCP回调函数中,根据DHCP的状态(如成功获取IP地址、失败等)执行相应的操作。例如,成功获取IP地址后,可以打印日志或进行后续网络操作。
程序设计:
#include "main.h"
#include "CH57x_common.h"
#include "uart.h"
#include "time.h"
#include "net_init.h"
__align(4) UINT8 RxBuffer[ MAX_PACKET_SIZE ]; // IN, must even address
__align(4) UINT8 TxBuffer[ MAX_PACKET_SIZE ]; // OUT, must even address
//缓存数据使用
unsigned char main_buffer[main_buffer_len];//缓存数据,全局通用
uint32_t main_len; //全局通用变量
unsigned char *main_str; //全局通用变量
void uart0_data(void);//串口数据处理
char net_phy_state=0;
UINT8 net_dhcp_ip[4]; /* CH579IP地址 */
UINT8 net_dhcp_gw[4]; /* CH579网关 */
UINT8 net_dhcp_mask[4]; /* CH579子网掩码 */
/*******************************************************************************
* Function Name : CH57xNET_DHCPCallBack
* Description : DHCP回调函数
* Input : None
* Output : None
* Return : 执行状态
*******************************************************************************/
UINT8 CH57xNET_DHCPCallBack(UINT8 status,void *arg)
{
UINT8 *p;
if(!status){/* 成功*/
p = arg;
PRINT("DHCP Success\n");
memcpy(net_dhcp_ip,p,4);//获取分配的IP地址
memcpy(net_dhcp_gw,&p[4],4);//获取网关
memcpy(net_dhcp_mask,&p[8],4);//获取子网掩码
printf("IPAddr = %d.%d.%d.%d \r\n",(UINT16)net_dhcp_ip[0],(UINT16)net_dhcp_ip[1],(UINT16)net_dhcp_ip[2],(UINT16)net_dhcp_ip[3]);
printf("GWIPAddr = %d.%d.%d.%d \r\n",(UINT16)net_dhcp_gw[0],(UINT16)net_dhcp_gw[1],(UINT16)net_dhcp_gw[2],(UINT16)net_dhcp_gw[3]);
printf("IPAddr = %d.%d.%d.%d \r\n",(UINT16)net_dhcp_mask[0],(UINT16)net_dhcp_mask[1],(UINT16)net_dhcp_mask[2],(UINT16)net_dhcp_mask[3]);
printf("DNS1: %d.%d.%d.%d\r\n",p[12],p[13],p[14],p[15]);
printf("DNS2: %d.%d.%d.%d\r\n",p[16],p[17],p[18],p[19]);
}
else{/* 产生此中断,CH57xNET库内部会将此socket清除,置为关闭*/
PRINT("DHCP Fail %02x\n",status);
}
return 0;
}
int main()
{
int i;
PWR_UnitModCfg(ENABLE, UNIT_SYS_PLL);//使能PLL(给以太网提供时钟)
DelayMs(3);
// SetSysClock(CLK_SOURCE_HSE_32MHz);/* 外部晶振 PLL 输出32MHz */
uart_init();//初始化串口
net_init();//初始化以太网
time0_init();//初始化定时器
printf("start\r\n");
while(1)
{
CH57xNET_MainTask();/* CH57xNET库主任务函数,需要在主循环中不断调用 */
if(net_phy_state != CH57xInf.PHYStat){//网线连接状态改变
net_phy_state = CH57xInf.PHYStat;
if(net_phy_state==2){//连接
printf("net_phy_connected\r\n");
CH57xNET_DHCPStart(CH57xNET_DHCPCallBack);/* 启动DHCP */
}
else{//断开
printf("net_phy_disconnected\r\n");
CH57xNET_DHCPStop();//关闭DHCP
}
}
}
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] 串口数据处理
* @param None
* @retval None
* [url=home.php?mod=space&uid=157211]@warning[/url] None
* @example
**/
void uart1_data(void)
{
//读取串口接收的数据
if(usart1_idle_flag){
usart1_idle_flag=0;
/*获取模组返回的数据*/
main_len = rbCanRead(&rb_t_usart1_read);
memset(usart1_read_buff_copy,0,rb_t_usart1_read_buff_len);
if(main_len > 0)//如果里面的数据个数大于0
{
rbRead(&rb_t_usart1_read, usart1_read_buff_copy, main_len);
}
}
}
初始化:需要初始化CH57xNET库,配置MAC地址、缓冲区等。
启动DHCP:调用CH57xNET_DHCPStart函数启动DHCP客户端,并设置回调函数处理DHCP事件。
回调处理:在DHCP回调函数中,处理DHCP成功或失败的情况,例如获取到IP地址后,可以打印日志或进行后续网络操作。
处理DHCP交互流程
发现阶段:设备发送DHCP DISCOVER请求IP地址。
提供阶段:服务器返回DHCP OFFER,包含IP、子网掩码、网关等参数。
请求阶段:设备发送DHCP REQUEST确认选择。
确认阶段:服务器返回DHCP ACK,完成IP分配。
超时与重试机制
若未收到响应,设备通过定时器超时后重新发送DHCP DISCOVER,直至成功或达到最大重试次数。
结果:
三、DHCP功能实现中的注意事项
1. 网络稳定性:
确保网络连接稳定,避免因网络波动导致DHCP请求失败。
可以加入看门狗逻辑,防止设备因异常而死机。
2. DHCP服务器配置:
检查DHCP服务器是否正常运行,并确保有足够的IP地址可供分配。
如果网络中使用了DHCP中继,需要检查中继设备是否正常工作。
3. MAC地址处理:
某些路由器可能对MAC地址有特殊要求,可以尝试修改MAC地址的前几字节以避免冲突。
4. 重连机制:
在网络断开或DHCP失败时,需要实现重连机制。这通常涉及关闭原先的Socket、重新初始化网络库(如果需要)、重新启动DHCP客户端等步骤。
5. 错误处理:
在DHCP回调函数中,需要处理各种可能的错误情况,如DHCP服务器无响应、IP地址分配失败等。
四、DHCP功能优化
1. 超时设置:
调整DHCP的超时时间,避免长时间等待。
2. 日志记录:
在DHCP回调函数中加入日志记录功能,方便调试和排查问题。
3. 电源稳定性:
确保设备的电源稳定,避免因电源波动导致网络异常。
|