单片机IWIP SOCKET TCP实验
2026/6/30 1:11:08 网站建设 项目流程

单片机 :STM32F407
开发板:DMF407电机开发板
平台:keil V5.31

HSE 为8MHZ
HSI为16MHZ

主函数

int main(void) { HAL_Init(); /* 初始化HAL库 */ sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */ delay_init(168); /* 延时初始化 */ usart_init(115200); /* 串口初始化为115200 */ usmart_dev.init(84); /* 初始化USMART */ led_init(); /* 初始化LED */ lcd_init(); /* 初始化LCD */ key_init(); /* 初始化按键 */ my_mem_init(SRAMIN); /* 初始化内部SRAM内存池 */ my_mem_init(SRAMCCM); /* 初始化内部SRAMCCM内存池 */ freertos_demo(); /* 创建lwIP的任务函数 */ }
void freertos_demo(void) { /* start_task任务 */ xTaskCreate((TaskFunction_t )start_task, (const char * )"start_task", (uint16_t )START_STK_SIZE, (void * )NULL, (UBaseType_t )START_TASK_PRIO, (TaskHandle_t * )&StartTask_Handler); vTaskStartScheduler(); /* 开启任务调度 */ }
void start_task(void *pvParameters) { pvParameters = pvParameters; g_lwipdev.lwip_display_fn = lwip_test_ui; lwip_test_ui(1); /* 加载后前部分UI */ while (lwip_comm_init() != 0) { lcd_show_string(30, 110, 200, 16, 16, "lwIP Init failed!!", RED); delay_ms(500); lcd_fill(30, 50, 200 + 30, 50 + 16, WHITE); lcd_show_string(30, 110, 200, 16, 16, "Retrying... ", RED); delay_ms(500); LED1_TOGGLE(); } while (!ethernet_read_phy(PHY_SR)) /* 检查MCU与PHY芯片是否通信成功 */ { printf("MCU与PHY芯片通信失败,请检查电路或者源码!!!!\r\n"); } while ((g_lwipdev.dhcpstatus != 2)&&(g_lwipdev.dhcpstatus != 0XFF)) /* 等待DHCP获取成功/超时溢出 */ { vTaskDelay(5); } taskENTER_CRITICAL(); /* 进入临界区 */ g_display_queue = xQueueCreate(DISPLAYMSG_Q_NUM,200); /* 创建消息Message_Queue,队列项长度是200长度 */ /* 创建lwIP任务 */ xTaskCreate((TaskFunction_t )lwip_demo_task, (const char* )"lwip_demo_task", (uint16_t )LWIP_DMEO_STK_SIZE, (void* )NULL, (UBaseType_t )LWIP_DMEO_TASK_PRIO, (TaskHandle_t* )&LWIP_Task_Handler); /* key任务 */ xTaskCreate((TaskFunction_t )key_task, (const char * )"key_task", (uint16_t )KEY_STK_SIZE, (void * )NULL, (UBaseType_t )KEY_TASK_PRIO, (TaskHandle_t * )&KEYTask_Handler); /* LED测试任务 */ xTaskCreate((TaskFunction_t )led_task, (const char* )"led_task", (uint16_t )LED_STK_SIZE, (void* )NULL, (UBaseType_t )LED_TASK_PRIO, (TaskHandle_t* )&LEDTask_Handler); /* 显示任务 */ xTaskCreate((TaskFunction_t )display_task, (const char* )"display_task", (uint16_t )DISPLAY_STK_SIZE, (void* )NULL, (UBaseType_t )DISPLAY_TASK_PRIO, (TaskHandle_t* )&DISPLAYTask_Handler); vTaskDelete(StartTask_Handler); /* 删除开始任务 */ taskEXIT_CRITICAL(); /* 退出临界区 */ }
void lwip_demo_task(void *pvParameters) { pvParameters = pvParameters; lwip_demo(); /* lwip测试代码 */ while (1) { vTaskDelay(5); } }
void lwip_demo(void) { struct sockaddr_in atk_client_addr; err_t err; int recv_data_len; BaseType_t lwip_err; char *tbuf; lwip_data_send(); /* 创建发送数据线程 */ while (1) { sock_start: g_lwip_connect_state = 0; atk_client_addr.sin_family = AF_INET; /* 表示IPv4网络协议 */ atk_client_addr.sin_port = htons(LWIP_DEMO_PORT); /* 端口号 */ atk_client_addr.sin_addr.s_addr = inet_addr(IP_ADDR); /* 远程IP地址 */ g_sock = socket(AF_INET, SOCK_STREAM, 0); /* 可靠数据流交付服务既是TCP协议 */ memset(&(atk_client_addr.sin_zero), 0, sizeof(atk_client_addr.sin_zero)); tbuf = mymalloc(SRAMIN, 200); /* 申请内存 */ sprintf((char *)tbuf, "Port:%d", LWIP_DEMO_PORT); /* 客户端端口号 */ lcd_show_string(5, 150, 200, 16, 16, tbuf, BLUE); /* 连接远程IP地址 */ err = connect(g_sock, (struct sockaddr *)&atk_client_addr, sizeof(struct sockaddr)); if (err == -1) { printf("连接失败\r\n"); g_sock = -1; closesocket(g_sock); myfree(SRAMIN, tbuf); vTaskDelay(10); goto sock_start; } printf("连接成功\r\n"); lcd_show_string(5, 90, 200, 16, 16, "State:Connection Successful", BLUE); g_lwip_connect_state = 1; while (1) { recv_data_len = recv(g_sock,g_lwip_demo_recvbuf, LWIP_DEMO_RX_BUFSIZE,0); if (recv_data_len <= 0 ) { closesocket(g_sock); g_sock = -1; lcd_fill(5, 89, lcddev.width,110, WHITE); lcd_show_string(5, 90, 200, 16, 16, "State:Disconnect", BLUE); myfree(SRAMIN, tbuf); goto sock_start; } /* 接收的数据 */ lwip_err = xQueueSend(g_display_queue,&g_lwip_demo_recvbuf,0); if (lwip_err == errQUEUE_FULL) { printf("队列Key_Queue已满,数据发送失败!\r\n"); } vTaskDelay(10); } } }

测试结果:

二、服务器实验

主函数

int main(void) { HAL_Init(); /* 初始化HAL库 */ sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */ delay_init(168); /* 延时初始化 */ usart_init(115200); /* 串口初始化为115200 */ usmart_dev.init(84); /* 初始化USMART */ led_init(); /* 初始化LED */ lcd_init(); /* 初始化LCD */ key_init(); /* 初始化按键 */ my_mem_init(SRAMIN); /* 初始化内部SRAM内存池 */ my_mem_init(SRAMCCM); /* 初始化内部SRAMCCM内存池 */ freertos_demo(); /* 创建lwIP的任务函数 */ }
void freertos_demo(void) { /* start_task任务 */ xTaskCreate((TaskFunction_t )start_task, (const char * )"start_task", (uint16_t )START_STK_SIZE, (void * )NULL, (UBaseType_t )START_TASK_PRIO, (TaskHandle_t * )&StartTask_Handler); vTaskStartScheduler(); /* 开启任务调度 */ }
void start_task(void *pvParameters) { pvParameters = pvParameters; g_lwipdev.lwip_display_fn = lwip_test_ui; lwip_test_ui(1); /* 加载后前部分UI */ while (lwip_comm_init() != 0) { lcd_show_string(30, 110, 200, 16, 16, "lwIP Init failed!!", RED); delay_ms(500); lcd_fill(30, 50, 200 + 30, 50 + 16, WHITE); lcd_show_string(30, 110, 200, 16, 16, "Retrying... ", RED); delay_ms(500); LED1_TOGGLE(); } while (!ethernet_read_phy(PHY_SR)) /* 检查MCU与PHY芯片是否通信成功 */ { printf("MCU与PHY芯片通信失败,请检查电路或者源码!!!!\r\n"); } while ((g_lwipdev.dhcpstatus != 2) && (g_lwipdev.dhcpstatus != 0XFF)) /* 等待DHCP获取成功/超时溢出 */ { vTaskDelay(5); } taskENTER_CRITICAL(); /* 进入临界区 */ g_display_queue = xQueueCreate(DISPLAYMSG_Q_NUM,200); /* 创建消息Message_Queue,队列项长度是200长度 */ /* 创建lwIP任务 */ xTaskCreate((TaskFunction_t )lwip_demo_task, (const char* )"lwip_demo_task", (uint16_t )LWIP_DMEO_STK_SIZE, (void* )NULL, (UBaseType_t )LWIP_DMEO_TASK_PRIO, (TaskHandle_t* )&LWIP_Task_Handler); /* key任务 */ xTaskCreate((TaskFunction_t )key_task, (const char * )"key_task", (uint16_t )KEY_STK_SIZE, (void * )NULL, (UBaseType_t )KEY_TASK_PRIO, (TaskHandle_t * )&KEYTask_Handler); /* LED测试任务 */ xTaskCreate((TaskFunction_t )led_task, (const char* )"led_task", (uint16_t )LED_STK_SIZE, (void* )NULL, (UBaseType_t )LED_TASK_PRIO, (TaskHandle_t* )&LEDTask_Handler); /* 显示任务 */ xTaskCreate((TaskFunction_t )display_task, (const char* )"display_task", (uint16_t )DISPLAY_STK_SIZE, (void* )NULL, (UBaseType_t )DISPLAY_TASK_PRIO, (TaskHandle_t* )&DISPLAYTask_Handler); vTaskDelete(StartTask_Handler); /* 删除开始任务 */ taskEXIT_CRITICAL(); /* 退出临界区 */ }
void lwip_demo_task(void *pvParameters) { pvParameters = pvParameters; lwip_demo(); /* lwip测试代码 */ while(1) { vTaskDelay(5); } }
void lwip_demo() { struct sockaddr_in server_addr; /* 服务器地址 */ struct sockaddr_in conn_addr; /* 连接地址 */ socklen_t addr_len; /* 地址长度 */ int err; int length; int sock_fd; char *tbuf; BaseType_t lwip_err; lwip_data_send(); /* 创建一个发送线程 */ sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* 建立一个新的socket连接 */ memset(&server_addr, 0, sizeof(server_addr)); /* 将服务器地址清空 */ server_addr.sin_family = AF_INET; /* 地址家族 */ server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 注意转化为网络字节序 */ server_addr.sin_port = htons(LWIP_DEMO_PORT); /* 使用SERVER_PORT指定为程序头设定的端口号 */ tbuf = mymalloc(SRAMIN, 200); /* 申请内存 */ sprintf((char *)tbuf, "Port:%d", LWIP_DEMO_PORT); /* 客户端端口号 */ lcd_show_string(5, 150, 200, 16, 16, tbuf, BLUE); err = bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); /* 建立绑定 */ if (err < 0) /* 如果绑定失败则关闭套接字 */ { closesocket(sock_fd); /* 关闭套接字 */ myfree(SRAMIN, tbuf); } err = listen(sock_fd, 4); /* 监听连接请求 */ if (err < 0) /* 如果监听失败则关闭套接字 */ { closesocket(sock_fd); /* 关闭套接字 */ } while(1) { g_lwip_connect_state = 0; addr_len = sizeof(struct sockaddr_in); /* 将链接地址赋值给addr_len */ g_sock_conn = accept(sock_fd, (struct sockaddr *)&conn_addr, &addr_len); /* 对监听到的请求进行连接,状态赋值给sock_conn */ if (g_sock_conn < 0) /* 状态小于0代表连接故障,此时关闭套接字 */ { closesocket(sock_fd); } else { lcd_show_string(5, 90, 200, 16, 16, "State:Connection Successful", BLUE); g_lwip_connect_state = 1; } while (1) { memset(g_lwip_demo_recvbuf,0,LWIP_DEMO_RX_BUFSIZE); length = recv(g_sock_conn, (unsigned int *)g_lwip_demo_recvbuf, sizeof(g_lwip_demo_recvbuf), 0); /* 将收到的数据放到接收Buff */ if (length <= 0) { goto atk_exit; } // printf("%s",g_lwip_demo_recvbuf); lwip_err = xQueueSend(g_display_queue,&g_lwip_demo_recvbuf,0); if (lwip_err == errQUEUE_FULL) { printf("队列Key_Queue已满,数据发送失败!\r\n"); } } atk_exit: if (g_sock_conn >= 0) { closesocket(g_sock_conn); g_sock_conn = -1; lcd_fill(5, 89, lcddev.width,110, WHITE); lcd_show_string(5, 90, 200, 16, 16, "State:Disconnect", BLUE); myfree(SRAMIN, tbuf); } } }

测试结果

三、服务器多连接实验

主函数

int main(void) { HAL_Init(); /* 初始化HAL库 */ sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */ delay_init(168); /* 延时初始化 */ usart_init(115200); /* 串口初始化为115200 */ usmart_dev.init(84); /* 初始化USMART */ led_init(); /* 初始化LED */ lcd_init(); /* 初始化LCD */ key_init(); /* 初始化按键 */ my_mem_init(SRAMIN); /* 初始化内部SRAM内存池 */ my_mem_init(SRAMCCM); /* 初始化内部SRAMCCM内存池 */ freertos_demo(); /* 创建lwIP的任务函数 */ }
void freertos_demo(void) { /* start_task任务 */ xTaskCreate((TaskFunction_t )start_task, (const char * )"start_task", (uint16_t )START_STK_SIZE, (void * )NULL, (UBaseType_t )START_TASK_PRIO, (TaskHandle_t * )&StartTask_Handler); vTaskStartScheduler(); /* 开启任务调度 */ }
void start_task(void *pvParameters) { pvParameters = pvParameters; g_lwipdev.lwip_display_fn = lwip_test_ui; lwip_test_ui(1); /* 加载后前部分UI */ while(lwip_comm_init() != 0) { lcd_show_string(30, 110, 200, 16, 16, "lwIP Init failed!!", RED); delay_ms(500); lcd_fill(30, 50, 200 + 30, 50 + 16, WHITE); lcd_show_string(30, 110, 200, 16, 16, "Retrying... ", RED); delay_ms(500); LED1_TOGGLE(); } while (g_lwipdev.dhcpstatus != 2 && g_lwipdev.dhcpstatus != 0xff)/* 等待静态和动态分配完成 */ { vTaskDelay(5); } taskENTER_CRITICAL(); /* 进入临界区 */ g_display_queue = xQueueCreate(DISPLAYMSG_Q_NUM,200); /* 创建消息Message_Queue,队列项长度是200长度 */ /* 创建lwIP任务 */ xTaskCreate((TaskFunction_t )lwip_demo_task, (const char* )"lwip_demo_task", (uint16_t )LWIP_DMEO_STK_SIZE, (void* )NULL, (UBaseType_t )LWIP_DMEO_TASK_PRIO, (TaskHandle_t* )&LWIP_Task_Handler); /* LED测试任务 */ xTaskCreate((TaskFunction_t )led_task, (const char* )"led_task", (uint16_t )LED_STK_SIZE, (void* )NULL, (UBaseType_t )LED_TASK_PRIO, (TaskHandle_t* )&LEDTask_Handler); vTaskDelete(StartTask_Handler); /* 删除开始任务 */ taskEXIT_CRITICAL(); /* 退出临界区 */ }
void lwip_demo_task(void *pvParameters) { pvParameters = pvParameters; lwip_demo(); /* lwip测试代码 */ while (1) { vTaskDelay(5); } }
void lwip_demo(void) { struct client_info *client_fo; struct client_task_info *client_task_fo; struct link_socjet_info *socket_link_info; int sin_size = sizeof(struct sockaddr_in); char client_name[10] = "cli"; char client_num[10]; /* socket连接结构体申请内存 */ socket_link_info = mem_malloc(sizeof(struct link_socjet_info)); /* 设置客户端任务信息 */ client_task_fo = mem_malloc(sizeof(struct client_task_info)); client_task_fo->client_handler = NULL; client_task_fo->client_task_pro = 5; client_task_fo->client_task_stk = 512; /* 创建socket连接 */ if ((socket_link_info->sock_listen = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Socket error\r\n"); return; } /* 初始化连接的服务端地址 */ socket_link_info->listen_addr.sin_family = AF_INET; socket_link_info->listen_addr.sin_port = htons(8088); socket_link_info->listen_addr.sin_addr.s_addr = htonl(INADDR_ANY); memset(&(socket_link_info->listen_addr.sin_zero), 0, sizeof(socket_link_info->listen_addr.sin_zero)); /* 绑定socket和连接的服务端地址信息 */ if (bind(socket_link_info->sock_listen, (struct sockaddr * )&socket_link_info->listen_addr, sizeof(struct sockaddr)) < 0) { printf("Bind fail!\r\n"); goto __exit; } /* 监听客户端的数量 */ listen(socket_link_info->sock_listen, 4); printf("begin listing...\r\n"); while (1) { /* 请求客户端连接 */ socket_link_info->sock_connect = accept(socket_link_info->sock_listen, (struct sockaddr* )&socket_link_info->connect_addr, (socklen_t* )&sin_size); if (socket_link_info->sock_connect == -1) { printf("no socket,waitting others socket disconnect.\r\n"); continue; } lwip_itoa((char *)socket_link_info->sock_connect, (size_t)client_num, 10); strcat(client_name, client_num); client_task_fo->client_name = client_name; client_task_fo->client_num = client_num; /* 初始化连接客户端信息 */ client_fo = mem_malloc(sizeof(struct client_info)); client_fo->socket_num = socket_link_info->sock_connect; memcpy(&client_fo->ip_addr, &socket_link_info->connect_addr, sizeof(struct sockaddr_in)); client_fo->sockaddr_len = sin_size; /* 创建连接的客户端任务 */ xTaskCreate((TaskFunction_t )lwip_client_thread_entry, (const char * )client_task_fo->client_name, (uint16_t )client_task_fo->client_task_stk, (void * )(void*) client_fo, (UBaseType_t )client_task_fo->client_task_pro ++ , (TaskHandle_t * )&client_task_fo->client_handler); if (client_task_fo->client_handler == NULL) { printf("no memery for thread %s startup failed!\r\n",client_task_fo->client_name); mem_free(client_fo); continue; } else { printf("thread %s success!\r\n", client_task_fo->client_name); } } __exit: printf("listener failed\r\n"); /* 关闭这个socket */ closesocket(socket_link_info->sock_listen); vTaskDelete(NULL); /* 删除本任务 */ }

测试结果:

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询