Clion开发STM32之W5500系列(综合实验)

说明

  1. 此为w5500模块的综合实验测试模块,包含dhcp、dns、ntp
  2. 以上三个模块的驱动参考之前的文章,本篇不做说明.
  3. 使用的开发芯片 stm32f103vet6系列,外设接口使用的spi2

实验内容:

  1. 通过dhcp动态获取ip,
  2. 通过dns解析NTP服务域名的ip
  3. 通过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





测试结果

Clion开发STM32之W5500系列(综合实验)_第1张图片

你可能感兴趣的:(STM32相关驱动,stm32,嵌入式硬件,单片机)