单片机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);
}
}
测试结果:

更多推荐

所有评论(0)