当前位置: 首页 > news >正文

单片机IWIP SOCKET UDP实验

单片机 :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) { BaseType_t lwip_err; char *tbuf; lwip_data_send(); /* 创建发送数据线程 */ memset(&g_local_info, 0, sizeof(struct sockaddr_in)); /* 将服务器地址清空 */ g_local_info.sin_len = sizeof(g_local_info); g_local_info.sin_family = AF_INET; /* IPv4地址 */ g_local_info.sin_port = htons(LWIP_DEMO_PORT); /* 设置端口号 */ g_local_info.sin_addr.s_addr = htons(INADDR_ANY); /* 设置本地IP地址 */ g_sock_fd = socket(AF_INET, SOCK_DGRAM, 0); /* 建立一个新的socket连接 */ tbuf = mymalloc(SRAMIN, 200); /* 申请内存 */ sprintf((char *)tbuf, "Port:%d", LWIP_DEMO_PORT); /* 客户端端口号 */ lcd_show_string(5, 150, 200, 16, 16, tbuf, BLUE); /* 建立绑定 */ bind(g_sock_fd, (struct sockaddr *)&g_local_info, sizeof(struct sockaddr_in)); while (1) { memset(g_lwip_demo_recvbuf, 0, sizeof(g_lwip_demo_recvbuf)); recv(g_sock_fd, (void *)g_lwip_demo_recvbuf, sizeof(g_lwip_demo_recvbuf), 0); lwip_err = xQueueSend(g_display_queue,&g_lwip_demo_recvbuf,0); if (lwip_err == errQUEUE_FULL) { printf("队列Key_Queue已满,数据发送失败!\r\n"); } } }

测试结果:

二、广播实验

主函数

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的任务函数 */ }

demo

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(); /* 进入临界区 */ /* 创建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); } }
/* UDP广播测试 */ void lwip_demo(void) { struct link_socjet_info *socket_info; socket_info = mem_malloc(sizeof(struct link_socjet_info)); socket_info->optval = 1; /* 创建socket UDP通信 */ socket_info->sfd = socket(AF_INET, SOCK_DGRAM, 0); setsockopt(socket_info->sfd, SOL_SOCKET, SO_BROADCAST, &socket_info->optval, sizeof(socket_info->optval)); socket_info->client_addr.sin_family = AF_INET; socket_info->client_addr.sin_port = htons(9090); socket_info->client_addr.sin_addr.s_addr = inet_addr("255.255.255.255"); socket_info->client_addr_len = sizeof(struct sockaddr_in); /* 设置接收和发送缓冲区 */ socket_info->recv.buf = g_lwip_demo_recvbuf; socket_info->recv.size = sizeof(g_lwip_demo_recvbuf); socket_info->send.buf = g_lwip_demo_sendbuf; socket_info->send.size = sizeof(g_lwip_demo_sendbuf); sys_thread_new("lwip_send_thread", lwip_recv_thread, (void *)socket_info, 512, LWIP_SEND_THREAD_PRIO ); while (1) { /* 发送广播数据 */ sendto(socket_info->sfd, socket_info->send.buf, socket_info->send.size, 0, (struct sockaddr *)&socket_info->client_addr, socket_info->client_addr_len); vTaskDelay(1000); } }

测试结果:

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(); /* 开启任务调度 */ }

三、组播实验

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 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(); /* 进入临界区 */ /* 创建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 link_socjet_info *socket_info; struct ip_mreq_t *mreq_info; socket_info = mem_malloc(sizeof(struct link_socjet_info)); mreq_info = mem_malloc(sizeof(struct ip_mreq_t)); socket_info->sfd = socket(AF_INET, SOCK_DGRAM, 0); if (socket_info->sfd < 0) { printf("socket failed!\n"); } socket_info->client_addr.sin_family = AF_INET; socket_info->client_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 待与 socket 绑定的本地网络接口 IP */ socket_info->client_addr.sin_port = htons(9999); /* 待与 socket 绑定的本地端口号 */ socket_info->client_addr_len = sizeof(socket_info->client_addr); /* 设置接收和发送缓冲区 */ socket_info->recv.buf = g_lwip_demo_recvbuf; socket_info->recv.size = sizeof(g_lwip_demo_recvbuf); socket_info->send.buf = g_lwip_demo_sendbuf; socket_info->send.size = sizeof(g_lwip_demo_sendbuf); /* 将 Socket 与本地某网络接口绑定 */ int ret = bind(socket_info->sfd, (struct sockaddr*)&socket_info->client_addr, socket_info->client_addr_len); if (ret < 0) { printf(" bind error!\n "); } mreq_info->mreq.imr_multiaddr.s_addr = inet_addr(GROUP_IP); /* 多播组 IP 地址设置 */ mreq_info->mreq.imr_interface.s_addr = htonl(INADDR_ANY); /* 待加入多播组的 IP 地址 */ mreq_info->mreq_len = sizeof(struct ip_mreq); /* 添加多播组成员(该语句之前,socket 只与 某单播IP地址相关联 执行该语句后 将与多播地址相关联) */ ret = setsockopt(socket_info->sfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq_info->mreq,mreq_info->mreq_len); if (ret < 0) { printf("setsockopt failed !"); } else { printf("setsockopt success\n"); } int length = 0; struct sockaddr_in sender; int sender_len = sizeof(sender); sys_thread_new("lwip_send_thread", lwip_send_thread, (void *)socket_info, 512, LWIP_SEND_THREAD_PRIO ); while(1) { length = recvfrom(socket_info->sfd,socket_info->recv.buf,socket_info->recv.size,0,(struct sockaddr*)&sender,(socklen_t *)&sender_len); socket_info->recv.buf[length]='\0'; printf("%s %d : %s\n", inet_ntoa(sender.sin_addr), ntohs(sender.sin_port), socket_info->recv.buf); vTaskDelay(10); } }

测试结果:

http://www.jsqmd.com/news/1092307/

相关文章:

  • AI 自动标记金句,2026年智能切片工作流,5款深度对比
  • 为什么我们的微服务没有用Spring Cloud?
  • 深入解析MSP432评估板硬件设计:从电源架构到PCB布局实战
  • Windows 11系统优化神器:Win11Debloat一键清理与个性化配置指南
  • Context Cache:HarmonyOS PC 下一代上下文系统揭秘
  • 告别Beat Saber管理烦恼:BSManager一站式解决方案
  • Pixelle-Video终极指南:5分钟掌握AI短视频自动生成技巧
  • 解密Transformer:用Excel可视化构建AI模型的突破性方法
  • 小程序制作平台有哪些?模板工具、SaaS平台和行业系统怎么区分
  • VisualCppRedist AIO:3分钟解决Windows软件兼容性难题,游戏玩家和IT管理员都在用的神器
  • Python图形界面开发:从PySide2入门到实战发布
  • Python京东抢购助手:3分钟学会自动抢购,告别手动秒杀烦恼
  • 5大技巧掌握Blender CAD参数化设计:从零到机械精度快速入门
  • 在日常Java开发工作中,迭代着迭代着本地就有一堆分支,批量删除的话有一行命令,如:
  • 从零上手DAC8563:双通道16位DAC在嵌入式系统中的实战配置
  • 从零到一:手把手教你构建欧奈尔RPS曲线实战系统
  • Metabase CVE-2023-38646漏洞深度剖析:从H2数据库特性到RCE实战复现
  • 告别代码恐惧:用Automa插件开启你的浏览器自动化之旅
  • XCOM 2终极模组管理器:AML启动器完全指南
  • MODBUS协议栈的实战解析:从帧结构到代码移植
  • 如何快速掌握Datavines数据质量管理平台:3大核心功能与5步部署指南
  • Cartographer(四)思岚RPLIDAR ROS驱动实战:从常见报错到稳定建图
  • 命令行加密工具enc实战指南:从AES算法到自动化脚本集成
  • 一键修复Windows运行库:VisualCppRedist AIO终极解决方案
  • Java毕设选题推荐:基于 SpringBoot+Vue 的考勤异常报备管理系统 公司月度考勤汇总与薪资关联考勤管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • ENVI兼容性难题:解析USGS新版LANDSAT8 MTL文件的结构差异与一键修复方案
  • Windows 11硬件限制终极破解指南:让任何电脑都能升级的完整解决方案
  • 别把 Product Hunt 当成冷启动:独立开发者真正要找的不是流量,而是对的人
  • 游戏通知系统本地推送与远程通知
  • 抽象管理化技术领域模型与通用语言