This commit is contained in:
2026-04-23 17:20:51 +08:00
parent 4c4cfa76b4
commit c185b3d8b9
77 changed files with 13811 additions and 24616 deletions
+53 -5
View File
@@ -27,13 +27,14 @@ static void bsp_W5500_Init(void);
static void bsp_W5500_Task(void);
static void Write_SOCK_Data_Buffer(bsp_W5500_Class_t *pW5500_Class, u8 *dat_ptr, u16 size);
static void network_monitor_task(void);
void bsp_W5500_Socket_Set(bsp_W5500_Class_t *pW5500_Class);
bsp_W5500_t W5500 =
{
.Gateway_IP = {192,168,100,1}, /*网关IP地址*/
.Sub_Mask = {255,255,255,0}, /*子网掩码*/
.Phy_Addr = {0x0c,0x29,0xab,0x7c,0x00,0x01}, /*物理地址(MAC)*/
.IP_Addr = {192,168,100,101}, /*本机IP地址*/
.IP_Addr = {192,168,100,201}, /*本机IP地址*/
.Interrupt_Process = bsp_W5500_Interrupt_Process,
@@ -462,7 +463,9 @@ void W5500_Hardware_Reset(void)
*******************************************************************************/
void W5500_Init(void)
{
#define STM32F4_UID_BASE 0x1FFF7A10 // 根据你的芯片系列修改此地址
u16 i = 0;
u32 uid[3] = {0};
Write_W5500_1Byte(MR, RST); // 软件复位W5500,置1有效,复位后自动清0
@@ -479,6 +482,23 @@ void W5500_Init(void)
// 设置物理地址,PHY_ADDR为6字节u8数组,自己定义,用于唯一标识网络设备的物理地址值
// 该地址值需要到IEEE申请,按照OUI的规定,前3个字节为厂商代码,后三个字节为产品序号
// 如果自己定义物理地址,注意第一个字节必须为偶数
//使用单片机UID
uid[0] = *(u32*)(STM32F4_UID_BASE);
uid[1] = *(u32*)(STM32F4_UID_BASE + 4);
uid[2] = *(u32*)(STM32F4_UID_BASE + 8);
pW5500->Phy_Addr[0] = uid[1] >> 8;
pW5500->Phy_Addr[1] = uid[1];
pW5500->Phy_Addr[2] = uid[2] >> 24;
pW5500->Phy_Addr[3] = uid[2] >> 16;
pW5500->Phy_Addr[4] = uid[2] >> 8;
pW5500->Phy_Addr[5] = uid[2];
// 设置本地管理位,并将单播位清零
pW5500->Phy_Addr[0] = (pW5500->Phy_Addr[0] & 0xFE) | 0x02;
Write_W5500_nByte(SHAR, pW5500->Phy_Addr, 6);
// 设置本机的IP地址,IP_ADDR为4字节u8数组,自己定义
@@ -694,10 +714,25 @@ IntDispose:
{
pW5500->W5500_Class[i].TR_Data_State |= BSP_W5500_PORT_DATA_RECEIVE; // 端口接收到一个数据包
}
if (Socket_Flag & IR_TIMEOUT) // Socket连接或数据传输超时处理
{
Write_W5500_SOCK_1Byte(pW5500->W5500_Class[i].SocketPort, Sn_CR, CLOSE); // 关闭端口,等待重新打开连接
pW5500->W5500_Class[i].TR_Data_State = 0; // 网络连接状态0x00,端口连接失败
if (Socket_Flag & IR_TIMEOUT) {
// 1. 清除超时中断标志位 (你的代码已有)
Write_W5500_SOCK_1Byte(pW5500->W5500_Class[i].SocketPort, Sn_IR, Socket_Flag);
// 2. 强制关闭Socket,确保其状态机复位
Write_W5500_SOCK_1Byte(pW5500->W5500_Class[i].SocketPort, Sn_CR, CLOSE);
// 3. (强烈推荐) 增加一小段延时,等待硬件完成关闭操作
HAL_Delay(10);
// 4. 关键修复:重新打开Socket并进入监听模式
// bsp_W5500_Socket_Init 函数用于配置Socket参数
bsp_W5500_Socket_Init(&pW5500->W5500_Class[i]);
// bsp_W5500_Socket_Set 函数会根据配置的模式(TCP Server)调用 Socket_Listen
bsp_W5500_Socket_Set(&pW5500->W5500_Class[i]);
// 5. 清理相关的状态标志位
pW5500->W5500_Class[i].Run_State = 0;
pW5500->W5500_Class[i].TR_Data_State = 0;
}
}
}
@@ -707,6 +742,15 @@ IntDispose:
goto IntDispose;
}
/**
* @brief 设置指定Socket的Keep-Alive间隔
* @param s: Socket端口号 (0~7)
* @param interval_5s: 间隔时间,单位5秒,例如2表示10秒。0表示禁用。
*/
void w5500_set_keepalive(SOCKET s, uint8_t interval_5s)
{
Write_W5500_SOCK_1Byte(s, Sn_KPALVTR, interval_5s);
}
void bsp_W5500_Socket_Set(bsp_W5500_Class_t *pW5500_Class)
{
@@ -718,7 +762,10 @@ void bsp_W5500_Socket_Set(bsp_W5500_Class_t *pW5500_Class)
case BSP_W5500_PORT_RUN_MODE_TCP_SERVER:
{
if (Socket_Listen(pW5500_Class->SocketPort) == TRUE)
{
pW5500_Class->Run_State = BSP_W5500_PORT_RUN_STATE_INIT;
w5500_set_keepalive(pW5500_Class->SocketPort, 2);
}
else
pW5500_Class->Run_State = 0;
}break;
@@ -763,6 +810,7 @@ static void bsp_W5500_Init()
static void bsp_W5500_Task(void)
{
u8 i;
for(i=0;i<BSP_W5500_PORT_NUM;i++)
{
bsp_W5500_Socket_Set(&pW5500->W5500_Class[i]); /*W5500端口初始化配置*/
+1 -1
View File
@@ -654,7 +654,7 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
}
else if (huart->Instance == UART4)
{
bsp_uart_tx_dma_tc_int(&com_uart2);
bsp_uart_tx_dma_tc_int(&com_uart4);
}
else if (huart->Instance == USART6)
{