单片机  :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();           /* 进入临界区 */

    /* 创建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)
{
    uint32_t data_len = 0;
    struct pbuf *q;
    err_t err;
    ip4_addr_t server_ipaddr, loca_ipaddr;
    static uint16_t server_port, loca_port;
    server_port = TCP_DEMO_PORT;
    netconn_gethostbyname(DEST_MANE,&server_ipaddr);


    while (1)
    {
atk_start:
        g_tcp_clientconn = netconn_new(NETCONN_TCP);                          /* 创建一个TCP链接 */
        err = netconn_connect(g_tcp_clientconn, &server_ipaddr, server_port); /* 连接服务器 */

        if (err != ERR_OK)
        {
            printf("接连失败\r\n");
            netconn_delete(g_tcp_clientconn); /* 返回值不等于ERR_OK,删除g_tcp_clientconn连接 */
        }
        else if (err == ERR_OK)             /* 处理新连接的数据 */
        {
            struct netbuf *recvbuf;
            g_tcp_clientconn->recv_timeout = 10;
            netconn_getaddr(g_tcp_clientconn, &loca_ipaddr, &loca_port, 1);           /* 获取本地IP主机IP地址和端口号 */
            
            lcd_show_string(5, 170, 200, 16, 16, "link succeed", BLUE);
            
            while (1)
            {
                g_temp_rh[0] = 30 + rand() % 10 + 1;                                  /* 温度的数据 */
                g_temp_rh[1] = 54.8 + rand() % 10 + 1;                                /* 湿度的数据 */

                g_tempStr[0] = g_temp_rh[0] / 10 + 0x30;   /* 上传温度 */
                g_tempStr[1] = g_temp_rh[0] % 10 + 0x30;;

                g_humiStr[0] = g_temp_rh[1] / 10 + 0x30;   /* 上传湿度 */
                g_humiStr[1] = g_temp_rh[1] % 10 + 0x30;
                g_len = lwip_onehttp_postpkt(g_buffer, apikey, onenet_id, "temperature", g_tempStr);
                netconn_write(g_tcp_clientconn, g_buffer, g_len, NETCONN_COPY);               /* 发送tcp_server_sentbuf中的数据 */
                g_len = lwip_onehttp_postpkt(g_buffer, apikey, onenet_id, "humidity", g_humiStr);
                netconn_write(g_tcp_clientconn, g_buffer, g_len, NETCONN_COPY);               /* 发送tcp_server_sentbuf中的数据 */
                vTaskDelay(1000);

                if (netconn_recv(g_tcp_clientconn, &recvbuf) == ERR_OK)                   /* 接收到数据*/
                {
                    taskENTER_CRITICAL();                                               /* 进入临界区*/
                    memset(g_tcp_client_recvbuf, 0, TCP_CLIENT_RX_BUFSIZE);               /* 数据接收缓冲区清零*/

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

                        data_len += q->len;

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

                    taskEXIT_CRITICAL();            /* 退出临界区 */
                    data_len = 0;                   /* 复制完成后data_len要清零 */
                    printf("%s\r\n", g_tcp_client_recvbuf);
                    netbuf_delete(recvbuf);
                }
                else /*关闭连接 */
                {
                    netconn_close(g_tcp_clientconn);
                    netconn_delete(g_tcp_clientconn);
                    goto atk_start;
                }
            }
        }
    }
}

实验结果:

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐