单片机IWIP NTP实验

单片机 :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 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();
    
    while (1)
    {
        vTaskDelay(5);
    }
}

void lwip_demo(void)
{
    err_t err;
    static struct netconn *udpconn;
    static struct netbuf  *recvbuf;
    static struct netbuf  *sentbuf;
    ip_addr_t destipaddr;
    uint32_t data_len = 0;
    struct pbuf *q;
    lwip_ntp_client_init();
    /* 第一步:创建udp控制块 */
    udpconn = netconn_new(NETCONN_UDP);
    /* 定义接收超时时间 */
    udpconn->recv_timeout = 10;

    if (udpconn != NULL) /* 判断创建控制块释放成功 */
    {
        /* 第二步:绑定控制块、本地IP和端口 */
        err = netconn_bind(udpconn, IP_ADDR_ANY, NTP_DEMO_PORT);
        /* 域名解析 */
        netconn_gethostbyname((char *)(HOST_NAME), &(destipaddr));
        /* 第三步:连接或者建立对话框 */
        netconn_connect(udpconn, &destipaddr, NTP_DEMO_PORT); /* 连接到远端主机 */

        if (err == ERR_OK) /* 绑定完成 */
        {
            while (1)
            {
                sentbuf = netbuf_new();
                netbuf_alloc(sentbuf, 48);
                memcpy(sentbuf->p->payload, (void *)g_ntp_message, sizeof(g_ntp_message));
                err = netconn_send(udpconn, sentbuf); /* 将sentbuf中的数据发送出去 */
                if (err != ERR_OK)
                {
                    printf("发送失败\r\n");
                    netbuf_delete(sentbuf); /* 删除buf */
                }
                netbuf_delete(sentbuf);      /* 删除buf */

                /* 第五步:接收数据 */
                netconn_recv(udpconn, &recvbuf);
                vTaskDelay(1000);     /* 延时1s */
                if (recvbuf != NULL)  /* 接收到数据 */
                {
                    memset(g_ntp_demo_recvbuf, 0, NTP_DEMO_RX_BUFSIZE); /*数据接收缓冲区清零 */

                    for (q = recvbuf->p; q != NULL; q = q->next) /*遍历完整个pbuf链表 */
                    {
                        /* 判断要拷贝到UDP_DEMO_RX_BUFSIZE中的数据是否大于UDP_DEMO_RX_BUFSIZE的剩余空间,如果大于 */
                        /* 的话就只拷贝UDP_DEMO_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据 */
                        if (q->len > (NTP_DEMO_RX_BUFSIZE - data_len)) memcpy(g_ntp_demo_recvbuf + data_len, q->payload, (NTP_DEMO_RX_BUFSIZE - data_len)); /* 拷贝数据 */
                        else memcpy(g_ntp_demo_recvbuf + data_len, q->payload, q->len);

                        data_len += q->len;

                        if (data_len > NTP_DEMO_RX_BUFSIZE) break;          /* 超出TCP客户端接收数组,跳出 */
                    }

                    data_len = 0;                                           /* 复制完成后data_len要清零 */
                    lwip_get_seconds_from_ntp_server(g_ntp_demo_recvbuf,40);   /* 从NTP服务器获取时间 */
                    printf("北京时间:%02d-%02d-%02d %02d:%02d:%02d\r\n",  
                           g_nowdate.year, 
                           g_nowdate.month + 1,
                           g_nowdate.day,
                           g_nowdate.hour + 8,
                           g_nowdate.minute,
                           g_nowdate.second);
                    sprintf((char*)g_lwip_time_buf,"BJ time:%02d-%02d-%02d %02d:%02d:%02d", g_nowdate.year, 
                                                                                               g_nowdate.month + 1,
                                                                                               g_nowdate.day,
                                                                                               g_nowdate.hour + 8,
                                                                                               g_nowdate.minute,
                                                                                               g_nowdate.second);
                    lcd_show_string(5, 170, lcddev.width, 16, 16, (char*)g_lwip_time_buf, RED);
                    
                    netbuf_delete(recvbuf);             /* 删除buf */
                }
                else vTaskDelay(5);                     /* 延时5ms */
            }
        }
        else printf("NTP绑定失败\r\n");
    }
    else printf("NTP连接创建失败\r\n");
}

测试结果: