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