环境
STM32CUBEMX 6.15
单片机:STM32F767VIT6
Cube配置
1/启用freertos,并新建一个udp任务。
2/启用ETH,选择接口为RMII,因为LAN8720a支持这个接口,注意引脚与实际硬件要一致。
3/配置LAN8720的复位引脚,任选一个引脚,用于复位芯片。
4/启用lwip,并禁用DHCP,使用手动配置一个IP地址及网关。
至此,芯片配置完成,可以进入到代码编辑了。
代码编辑
1/使用keil进行编辑,首先打开魔术棒,勾选微库
2/在MX_LWIP_Init()函数里面,加入LAN8720的复位代码
至此,应该就可以ping通网络了(我已经把我的电脑网卡地址改为192.168.3.109了)
3/在freertos文件里面,包含如下头文件
#include "lwip/udp.h"
#include "lwip/api.h"
#include "string.h"
4/声明功能函数
static void udp_receive_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p,const ip_addr_t *addr, u16_t port);
void udp_send_data(const char *data, const char *ip_addr, uint16_t port);
5/默认任务,发送数据
6/udp任务,处理数据接收
void StartUdpTask(void const * argument)
{
/* USER CODE BEGIN StartUdpTask */
/* Infinite loop */
osDelay(1000);
struct udp_pcb *upcb;
err_t err;
// 创建UDP控制块
upcb = udp_new();
if (!upcb)
{
// printf("Error creating PCB.\n");
return;
}
// 绑定到本地IP和端口
err = udp_bind(upcb, IP_ADDR_ANY, 1234); // 使用1234端口
if (err != ERR_OK)
{
// printf("Error binding to port. Error: %d\n", err);
udp_remove(upcb);
return;
}
// 设置接收回调函数
udp_recv(upcb, udp_receive_callback, NULL);
// printf("UDP server started on port 1234\n");
// 任务主循环
for(;;)
{
// 可以在这里添加其他处理逻辑
osDelay(1000);
}
/* USER CODE END StartUdpTask */
}
7/在/* USER CODE BEGIN Application /和/ USER CODE END Application */之间,补充UDP的回调函数和发送函数。
// UDP接收回调函数
static void udp_receive_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p,
const ip_addr_t *addr, u16_t port)
{
// 检查是否有数据
if (p != NULL) {
// 打印接收到的数据
// printf("Received %d bytes from %s:%d\n", p->tot_len,
// ipaddr_ntoa(addr), port);
// printf("Data: %s\n", (char*)p->payload);
// 发送响应(可选)
char response[] = "Hello from STM32!";
struct pbuf *resp_pbuf = pbuf_alloc(PBUF_TRANSPORT, strlen(response), PBUF_RAM);
if (resp_pbuf) {
memcpy(resp_pbuf->payload, response, strlen(response));
udp_sendto(pcb, resp_pbuf, addr, port);
pbuf_free(resp_pbuf);
}
// 释放接收到的数据包
pbuf_free(p);
}
}
void udp_send_data(const char *data, const char *ip_addr, uint16_t port)
{
struct udp_pcb *upcb;
err_t err;
struct pbuf *p;
// 创建UDP控制块
upcb = udp_new();
if (!upcb) {
// printf("Error creating PCB.\n");
return;
}
// 解析目标IP地址
ip_addr_t dest_addr;
IP4_ADDR(&dest_addr,
(uint8_t)(ip_addr[0]),
(uint8_t)(ip_addr[1]),
(uint8_t)(ip_addr[2]),
(uint8_t)(ip_addr[3]));
// 分配缓冲区
p = pbuf_alloc(PBUF_TRANSPORT, strlen(data), PBUF_RAM);
if (!p) {
// printf("Error allocating pbuf.\n");
udp_remove(upcb);
return;
}
// 复制数据到缓冲区
memcpy(p->payload, data, strlen(data));
// 发送数据
err = udp_sendto(upcb, p, &dest_addr, port);
if (err != ERR_OK) {
// printf("Error sending data: %d\n", err);
} else {
// printf("Data sent successfully.\n");
}
// 清理
pbuf_free(p);
udp_remove(upcb);
}
测试
连接好网线,打开sscom软件,配置好参数,就可以每秒收到数据China,点击发送后,会反馈Hello from stm32!(注意发送前,先点击“连接”按键).
————————————————
版权声明:本文为CSDN博主「路过羊圈的狼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39649731/article/details/151110845
|
|