系列文章:
stm32+lwip(一):使用STM32CubeMX生成项目
ST官方有lwip的例程,下载地址如下:

本文例子参考ST官方给出的例程。
一、准备
ST例程文档关于lwip的介绍如下:

由此可以看到LWIP有三种API,在本文中,使用Raw API。
本文用到的UDP Raw API如下:

二、udp client

1 /**
2 *****************************************************************************
3 * @file udp_client.c
4 * @author Zorb
5 * @version V1.0.0
6 * @date 2018-09-04
7 * @brief udp客户端的实现
8 *****************************************************************************
9 * @history
10 *
11 * 1. Date:2018-09-04
12 * Author:Zorb
13 * Modification:建立文件
14 *
15 *****************************************************************************
16 */
17
18 #include "stm32f4xx_hal.h"
19 #include "lwip.h"
20 #include "udp.h"
21 #include "string.h"
22
23 /* 定义端口号 */
24 #define UDP_REMOTE_PORT 8881 /* 远端端口 */
25 #define UDP_LOCAL_PORT 8880 /* 本地端口 */
26
27 /* udp控制块 */
28 static struct udp_pcb *upcb;
29
30 /******************************************************************************
31 * 描述 : 接收回调函数
32 * 参数 : -
33 * 返回 : 无
34 ******************************************************************************/
35 static void udp_receive_callback(void *arg, struct udp_pcb *upcb,
36 struct pbuf *p, const ip_addr_t *addr, u16_t port)
37 {
38 uint32_t i;
39
40 /* 数据回传 */
41 // udp_send(upcb, p);
42 // udp_sendto(upcb, p, addr, port);
43
44 /* 打印接收到的数据 */
45 printf("get msg from %d:%d:%d:%d port:%d:\r\n",
46 *((uint8_t *)&addr->addr), *((uint8_t *)&addr->addr + 1),
47 *((uint8_t *)&addr->addr + 2), *((uint8_t *)&addr->addr + 3), port);
48
49 if (p != NULL)
50 {
51 struct pbuf *ptmp = p;
52
53 while(ptmp != NULL)
54 {
55 for (i = 0; i < p->len; i++)
56 {
57 printf("%c", *((char *)p->payload + i));
58 }
59
60 ptmp = p->next;
61 }
62
63 printf("\r\n");
64 }
65
66 /* 释放缓冲区数据 */
67 pbuf_free(p);
68 }
69
70 /******************************************************************************
71 * 描述 : 发送udp数据
72 * 参数 : (in)pData 发送数据的指针
73 * 返回 : 无
74 ******************************************************************************/
75 void udp_client_send(char *pData)
76 {
77 struct pbuf *p;
78
79 /* 分配缓冲区空间 */
80 p = pbuf_alloc(PBUF_TRANSPORT, strlen(pData), PBUF_POOL);
81
82 if (p != NULL)
83 {
84 /* 填充缓冲区数据 */
85 pbuf_take(p, pData, strlen(pData));
86
87 /* 发送udp数据 */
88 udp_send(upcb, p);
89
90 /* 释放缓冲区空间 */
91 pbuf_free(p);
92 }
93 }
94
95 /******************************************************************************
96 * 描述 : 创建udp客户端
97 * 参数 : 无
98 * 返回 : 无
99 ******************************************************************************/
100 void udp_client_init(void)
101 {
102 ip_addr_t serverIP;
103 err_t err;
104
105 IP4_ADDR(&serverIP, 192, 168, 2, 194);
106
107 /* 创建udp控制块 */
108 upcb = udp_new();
109
110 if (upcb!=NULL)
111 {
112 /* 配置本地端口 */
113 upcb->local_port = UDP_LOCAL_PORT;
114
115 /* 配置服务器IP和端口 */
116 err= udp_connect(upcb, &serverIP, UDP_REMOTE_PORT);
117
118 if (err == ERR_OK)
119 {
120 /* 注册接收回调函数 */
121 udp_recv(upcb, udp_receive_callback, NULL);
122
123 /* 发送udp数据 */
124 udp_client_send("udp client connected");
125
126 printf("udp client connected\r\n");
127 }
128 else
129 {
130 udp_remove(upcb);
131
132 printf("can not connect udp pcb\r\n");
133 }
134 }
135 }
136
137 /******************************** END OF FILE ********************************/

本例用到的上位机IP为192.168.2.194,开放端口为8881
STM32的IP为192.168.2.8,开放端口为8880
先将网络调试助手的UDP连接打开,然后给STM32上电。
网络调试助手将会收到如下信息:

然后点击网络调试助手的发送,STM32调试串口输出以下信息:
get msg from 192:168:2:194 port:8881: hello zorb
三、udp server

1 /**
2 *****************************************************************************
3 * @file udp_server.c
4 * @author Zorb
5 * @version V1.0.0
6 * @date 2018-09-04
7 * @brief udp服务端的实现
8 *****************************************************************************
9 * @history
10 *
11 * 1. Date:2018-09-04
12 * Author:Zorb
13 * Modification:建立文件
14 *
15 *****************************************************************************
16 */
17
18 #include "stm32f4xx_hal.h"
19 #include "lwip.h"
20 #include "udp.h"
21
22 /* 定义端口号 */
23 #define UDP_REMOTE_PORT 8881 /* 远端端口 */
24 #define UDP_LOCAL_PORT 8880 /* 本地端口 */
25
26 /******************************************************************************
27 * 描述 : 接收回调函数
28 * 参数 : -
29 * 返回 : 无
30 ******************************************************************************/
31 static void udp_server_receive_callback(void *arg, struct udp_pcb *upcb,
32 struct pbuf *p, const ip_addr_t *addr, u16_t port)
33 {
34 uint32_t i;
35
36 /* 数据回传 */
37 // udp_sendto(upcb, p, addr, port);
38
39 /* 打印接收到的数据 */
40 printf("get msg from %d:%d:%d:%d port:%d:\r\n",
41 *((uint8_t *)&addr->addr), *((uint8_t *)&addr->addr + 1),
42 *((uint8_t *)&addr->addr + 2), *((uint8_t *)&addr->addr + 3), port);
43
44 if (p != NULL)
45 {
46 struct pbuf *ptmp = p;
47
48 while(ptmp != NULL)
49 {
50 for (i = 0; i < p->len; i++)
51 {
52 printf("%c", *((char *)p->payload + i));
53 }
54
55 ptmp = p->next;
56 }
57
58
59 printf("\r\n");
60 }
61
62 /* 释放缓冲区数据 */
63 pbuf_free(p);
64 }
65
66 /******************************************************************************
67 * 描述 : 初始化UDP服务器端
68 * 参数 : 无
69 * 返回 : 无
70 ******************************************************************************/
71 void udp_server_init(void)
72 {
73 struct udp_pcb *upcb;
74 err_t err;
75
76 /* 创建udp控制块 */
77 upcb = udp_new();
78
79 if (upcb)
80 {
81 /* 绑定端口接收,接收对象为所有ip地址 */
82 err = udp_bind(upcb, IP_ADDR_ANY, UDP_LOCAL_PORT);
83
84 if(err == ERR_OK)
85 {
86 /* 注册接收回调函数 */
87 udp_recv(upcb, udp_server_receive_callback, NULL);
88 }
89 else
90 {
91 /* 删除控制块 */
92 udp_remove(upcb);
93
94 printf("can not bind pcb\r\n");
95 }
96 }
97 }
98
99 /******************************** END OF FILE ********************************/

本例用到的上位机IP为192.168.2.194,开放端口为8881
STM32的IP为192.168.2.8,开放端口为8880
先将STM32上电,然后通过网络调试助手发送hello zorb。
STM32调试串口输出以下信息:
get msg from 192:168:2:194 port:8881: hello zorb
四、最后
本文测试了lwip的udp功能,能正常收发,撒花。
该文介绍了如何在STM32微控制器上使用LWIP库进行UDP通信。通过STM32CubeMX生成项目,然后分别展示了UDP客户端和服务器的实现,包括数据发送、接收回调函数的设置,以及在不同设备间进行UDP数据交互的过程。
3321

被折叠的 条评论
为什么被折叠?



