说明
- 此为w5500模块的综合实验测试模块,包含dhcp、dns、ntp
- 以上三个模块的驱动参考之前的文章,本篇不做说明.
- 使用的开发芯片 stm32f103vet6系列,外设接口使用的spi2
实验内容:
- 通过dhcp动态获取ip,
- 通过dns解析NTP服务域名的ip
- 通过NTP服务ip获取时间
w5500配置驱动
/*******************************************************************************
* Copyright (c) [scl]。保留所有权利。
* 本文仅供个人学习和研究使用,禁止用于商业用途。
******************************************************************************/
#include "app_conf.h"
#include "w5500_config.h"
#if APP_CONFIG_W5500
#define APP_CONFIG_W5500_DHCP (1) /*W5500 应用层--DHCP*/
#define APP_CONFIG_W5500_DNS (1) /*W5500 应用层--DNS*/
#define APP_CONFIG_W5500_NTP (1) /*W5500 应用层--NTP*/
#define DBG_ENABLE
#define DBG_SECTION_NAME "w5500"
#define DBG_LEVEL W5500_DBG_LEVEL
#include "sys_dbg.h"
#include "w5500_dhcp.h"
#include "w5500_dns.h"
#include "w5500_ntp.h"
#define W5500_CS stm_port_define(B,12)
#define W5500_RST stm_port_define(C,7)
static SPI_HandleTypeDef *w5500_spi = NULL;
static void send_and_rec_bytes(uint8_t *in_dat, uint8_t *out_data, uint16_t len) {
while (HAL_SPI_GetState(w5500_spi) != HAL_SPI_STATE_READY);
HAL_SPI_TransmitReceive(w5500_spi, in_dat, out_data, len, 1000);
while (HAL_SPI_GetState(w5500_spi) != HAL_SPI_STATE_READY);
}
static void send_only(uint8_t *in_data, uint16_t len) {
HAL_SPI_Transmit(w5500_spi, in_data, len, 1000);
}
static void W5500_RST_HIGH(void) { stm_pin_high(W5500_RST); }
static void W5500_RST_LOW(void) { stm_pin_low(W5500_RST); }
static void W5500_CS_LOW(void) { stm_pin_low(W5500_CS); }
static void W5500_CS_HIGH(void) { stm_pin_high(W5500_CS); }
static bool w5500_dhcp_after_init(SOCKET s, uint8_t try_cnt, uint32_t wait_ms);
static bool w5500_dns_after_init(SOCKET s, uint8_t *domain, uint8_t try_cnt, uint32_t wait_ms);
static bool w5500_ntp_after_init(SOCKET s, uint8_t try_cnt, uint32_t wait_ms);
static void W5500_Driver_MspInit(void) {
stm32_pin_mode(W5500_CS, pin_mode_output); /*CS*/
stm32_pin_mode(W5500_RST, pin_mode_output); /*RST*/
stm_pin_low(W5500_RST);
stm_pin_low(W5500_CS);
/*初始化SPI外设*/
/*W5500 支持 SPI 模式 0 及模式 3..MOSI 和 MISO 信号无论是接收或发送,均遵从从最高标志位(MSB)到最低标志位(LSB)的传输序列。*/
bsp_SpiHandleInit(w5500_spi, SPI_BAUDRATEPRESCALER_2, spi_mode_3);
}
module_w5500_t w5500_conf = {
.base_conf={
.socket_num = 4,
.rx_size={4, 4, 4, 4},
.tx_size={4, 4, 4, 4},
},
.net_conf={
.ip={192, 168, 199, 12},
.gw={192, 168, 199, 1},
.sub={255, 255, 255, 0},
},
.driver={
.cs_high = W5500_CS_HIGH,
.cs_low = W5500_CS_LOW,
.rst_high= W5500_RST_HIGH,
.rst_low=W5500_RST_LOW,
.delay = HAL_Delay,
.send_and_rec_bytes = send_and_rec_bytes,
.send_only =send_only
},
.api = {
.msp_init=W5500_Driver_MspInit,
}
};
uint8_t ntp_domain[] = {"ntp.ntsc.ac.cn"}; /*ntp域名*/
static struct dns_conf net_dns_cnf = { /*dns服务配置*/
.dns_server_ip={114, 114, 114, 114},
.dns_port = 53,
.delay_ms_cb = HAL_Delay
};
static struct ntp_conf net_ntp_conf = {
// .ntp_server={114, 118, 7, 163},
.ntp_port = 123,
.delay_ms_cb = HAL_Delay
};
static void w5500_pre_init(void) {
/*一般做数据加载,此时系统时钟使用的是内部时钟,如需要使用系统时钟的外设不在此进行初始化*/
w5500_spi = conv_spi_handle_ptr(handle_get_by_id(spi2_id));
/*初始化资源*/
module_w5500_init(&w5500_conf);
uint32_t uid0 = HAL_GetUIDw0();
uint32_t uid1 = HAL_GetUIDw1();
uint32_t uid2 = HAL_GetUIDw2();
uint8_t mac[6] = {0, uid0 >> 8, uid1, uid1 >> 8, uid2, uid2 >> 8};
memcpy(w5500_conf.net_conf.mac, mac, sizeof(mac));
#if APP_CONFIG_W5500_DHCP /*使用dhcp*/
dhcp_config_registry(&w5500_conf);
w5500_conf.net_conf_init = dhcp_init;/*使用dhcp init*/
#endif
}
static void w5500_init(void) {
w5500_conf.api.msp_init();/*初始化*/
w5500_conf.net_conf_init();
}
static void w5500_after_init(void) {
uint8_t try_cnt;
SOCKET sn = 1;/*使用的socket*/
#if APP_CONFIG_W5500_DHCP
try_cnt = 10;
if (!w5500_dhcp_after_init(sn, try_cnt, 500)) {
LOG_D("w5500_dhcp_after_init try cnt over:%d", try_cnt);
return;
}
#endif
uint8_t ip[4];
w5500_reg_ip_read(ip);
LOG_D("w5500_reg_ip_read:%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
w5500_reg_gw_read(ip);
LOG_D("w5500_reg_gw_read:%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
#if APP_CONFIG_W5500_DNS
try_cnt = 5;
dns_config_set(&net_dns_cnf);
if (!w5500_dns_after_init(sn, ntp_domain, try_cnt, 500)) {
LOG_D("w5500_dns_after_init try cnt over:%d", try_cnt);
return;
}
#endif
#if APP_CONFIG_W5500_NTP
try_cnt = 5;
ntp_config_set(&net_ntp_conf);
if (!w5500_ntp_after_init(sn, try_cnt, 500)) {
LOG_D("w5500_ntp_after_init try cnt over:%d", try_cnt);
return;
}
#endif
}
app_init_export(w5500_net_conf, w5500_pre_init, w5500_init, w5500_after_init);
#if APP_CONFIG_W5500_DHCP
static bool w5500_dhcp_after_init(SOCKET s, uint8_t try_cnt, uint32_t wait_ms) {
for (uint8_t i = 0; i < try_cnt; ++i) {
if (do_dhcp(s, wait_ms)) {
return true;
}
}
return false;
}
#endif
#if APP_CONFIG_W5500_DNS
static bool w5500_dns_after_init(SOCKET s, uint8_t *domain, uint8_t try_cnt, uint32_t wait_ms) {
for (int i = 0; i < try_cnt; ++i) {
if (do_dns(s, domain, net_ntp_conf.ntp_server, wait_ms)) {
LOG_D("dns parse result ip:%d.%d.%d.%d",
net_ntp_conf.ntp_server[0], net_ntp_conf.ntp_server[1],
net_ntp_conf.ntp_server[2], net_ntp_conf.ntp_server[3]
);
return true;
}
}
return false;
}
#endif
#if APP_CONFIG_W5500_NTP
static bool w5500_ntp_after_init(SOCKET s, uint8_t try_cnt, uint32_t wait_ms) {
struct net_date_time *nt_tm = NULL;
for (int i = 0; i < try_cnt; ++i) {
nt_tm = ntp_date_time_get(s, wait_ms);
if (nt_tm != NULL) {
LOG_D("NTP TIME:%d-%02d-%02d %02d:%02d:%02d",
nt_tm->year, nt_tm->month, nt_tm->day,
nt_tm->hour, nt_tm->min, nt_tm->sec
);
HAL_TIM_Base_Start_IT(handle_get_by_id(tim6_id));
return true;
}
}
return false;
}
#endif
#endif
测试结果
文章来源地址https://www.toymoban.com/news/detail-603948.html
文章来源:https://www.toymoban.com/news/detail-603948.html
到了这里,关于Clion开发STM32之W5500系列(综合实验)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!