国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Clion開發(fā)STM32之W5500系列(NTP服務(wù)封裝)

這篇具有很好參考價(jià)值的文章主要介紹了Clion開發(fā)STM32之W5500系列(NTP服務(wù)封裝)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

概述

  1. 在w5500基礎(chǔ)庫中進(jìn)行封裝,獲取服務(wù)端的時(shí)間,來校準(zhǔn)本地時(shí)間。
  2. 本次使用的方案是通過ntp獲取時(shí)間+定時(shí)器更新保證時(shí)間準(zhǔn)確。

NTP封裝

頭文件

/*******************************************************************************
 Copyright (c) [scl]。保留所有權(quán)利。
 ******************************************************************************/
#ifndef F1XX_TEMPLATE_W5500_NTP_H
#define F1XX_TEMPLATE_W5500_NTP_H

#include "socket.h"

#define TIMEZONE0 22
#define TIMEZONE8 39
#define TIME_ZONE TIMEZONE8 /*時(shí)區(qū)*/
#define SECS_PERDAY 86400UL /*一天多少秒*/
#define EPOCH    1900      /*起始年份1900*/

/**
 * @memberof delay_ms_cb 毫秒延遲回調(diào)
 * @memberof ntp_server  ntp服務(wù)器ip
 * @memberof ntp_port ntp服務(wù)端口,默認(rèn)為123
 */
struct ntp_conf {
    void (*delay_ms_cb)(uint32_t ms);

    uint8_t ntp_server[4];
    uint16_t ntp_port;
};

/**
 * @memberof year 年
 * @memberof month 月
 * @memberof day  日
 * @memberof hour 小時(shí)
 * @memberof min 分
 * @memberof sec 秒
 */
struct net_date_time {
    uint16_t year;
    uint8_t month;
    uint8_t day;
    uint8_t hour;
    uint8_t min;
    uint8_t sec;
};

void ntp_config_set(struct ntp_conf *cnf);
/**
 *
 * @param s
 * @param dst [out] 獲取時(shí)間
 * @return
 */
bool ntp_date_time_get(SOCKET s, uint32_t wait_ms, struct net_date_time *dst);

/**
 * @brief ntp本地時(shí)間更新
 */
void ntp_date_time_update();

/**
 * 獲取本地時(shí)間(note 需要先執(zhí)行 ntp_date_time_get)
 * @param dst
 * @return
 */
void net_date_time_loc_get(struct net_date_time *dst);

#endif //F1XX_TEMPLATE_W5500_NTP_H

源文件

/*******************************************************************************
 Copyright (c) [scl]。保留所有權(quán)利。
 ******************************************************************************/
#include "w5500_ntp.h"

#define DBG_ENABLE
#define DBG_SECTION_NAME "ntp_module"
#define DBG_LEVEL DBG_LOG

#include "sys_dbg.h"

uint32_t volatile total_sec; /*總秒數(shù)*/
static struct ntp_conf *ntp_conf_ptr = NULL;
static uint8_t ntp_request_msg[48] = {0x23};
static uint8_t cache_buf[SIZE_256B];
static struct net_date_time nt_tm;

static void calc_date_time(uint32_t seconds, struct net_date_time *datetime);

void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx, struct net_date_time *dst);

void ntp_config_set(struct ntp_conf *cnf) {
    // note verify conf param
    ntp_conf_ptr = cnf;
}

struct net_date_time *ntp_date_time_get(SOCKET s, uint32_t wait_ms) {
    uint16_t len = 0;
    if (ntp_conf_ptr == NULL) {
        LOG_E("ntp_config_set not set");
        return NULL;
    }
    if (udp_client_init(s, ntp_conf_ptr->ntp_port)) {
        /*發(fā)送請(qǐng)求包*/
        udp_client_send_simple(s,
                               ntp_conf_ptr->ntp_server, ntp_conf_ptr->ntp_port,
                               ntp_request_msg, sizeof(ntp_request_msg));
        /*wait 10ms*/
        for (int i = 0; i < wait_ms / 2; ++i) {
            if ((len = w5500_socket_rx_size_read(s)) > 0) {
                recvfrom_simple(s, cache_buf, len);
                /*解析數(shù)據(jù)*/
                get_seconds_from_ntp_server(cache_buf, 40, &nt_tm);
                close(s); /*關(guān)閉當(dāng)前socket*/
                return &nt_tm;
            }
            ntp_conf_ptr->delay_ms_cb(2);
        }
    } else {
        LOG_E("udp_client_init err:%d", __LINE__);
    }
    return NULL;
}

void ntp_date_time_update() {
    total_sec += 1;
}

struct net_date_time *net_date_time_loc_get() {
    calc_date_time(total_sec, &nt_tm);
    return &nt_tm;
}

void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx, struct net_date_time *dst) {
    uint32_t seconds = 0;
    uint8_t i = 0;
    for (i = 0; i < 4; i++) {
        seconds = (seconds << 8) | buf[idx + i];
    }
    switch (TIME_ZONE) {
        case 0:
            seconds -= 12 * 3600;
            break;
        case 1:
            seconds -= 11 * 3600;
            break;
        case 2:
            seconds -= 10 * 3600;
            break;
        case 3:
            seconds -= (9 * 3600 + 30 * 60);
            break;
        case 4:
            seconds -= 9 * 3600;
            break;
        case 5:
        case 6:
            seconds -= 8 * 3600;
            break;
        case 7:
        case 8:
            seconds -= 7 * 3600;
            break;
        case 9:
        case 10:
            seconds -= 6 * 3600;
            break;
        case 11:
        case 12:
        case 13:
            seconds -= 5 * 3600;
            break;
        case 14:
            seconds -= (4 * 3600 + 30 * 60);
            break;
        case 15:
        case 16:
            seconds -= 4 * 3600;
            break;
        case 17:
            seconds -= (3 * 3600 + 30 * 60);
            break;
        case 18:
            seconds -= 3 * 3600;
            break;
        case 19:
            seconds -= 2 * 3600;
            break;
        case 20:
            seconds -= 1 * 3600;
            break;
        case 21:
        case 22:
            break;
        case 23:
        case 24:
        case 25:
            seconds += 1 * 3600;
            break;
        case 26:
        case 27:
            seconds += 2 * 3600;
            break;
        case 28:
        case 29:
            seconds += 3 * 3600;
            break;
        case 30:
            seconds += (3 * 3600 + 30 * 60);
            break;
        case 31:
            seconds += 4 * 3600;
            break;
        case 32:
            seconds += (4 * 3600 + 30 * 60);
            break;
        case 33:
            seconds += 5 * 3600;
            break;
        case 34:
            seconds += (5 * 3600 + 30 * 60);
            break;
        case 35:
            seconds += (5 * 3600 + 45 * 60);
            break;
        case 36:
            seconds += 6 * 3600;
            break;
        case 37:
            seconds += (6 * 3600 + 30 * 60);
            break;
        case 38:
            seconds += 7 * 3600;
            break;
        case 39:
            seconds += 8 * 3600;
            break;
        case 40:
            seconds += 9 * 3600;
            break;
        case 41:
            seconds += (9 * 3600 + 30 * 60);
            break;
        case 42:
            seconds += 10 * 3600;
            break;
        case 43:
            seconds += (10 * 3600 + 30 * 60);
            break;
        case 44:
            seconds += 11 * 3600;
            break;
        case 45:
            seconds += (11 * 3600 + 30 * 60);
            break;
        case 46:
            seconds += 12 * 3600;
            break;
        case 47:
            seconds += (12 * 3600 + 45 * 60);
            break;
        case 48:
            seconds += 13 * 3600;
            break;
        case 49:
            seconds += 14 * 3600;
            break;
    }
    total_sec = seconds;
    calc_date_time(seconds, dst);
}

static void calc_date_time(uint32_t seconds, struct net_date_time *datetime) {
    uint8_t yf = 0;
    uint32_t p_year_total_sec;
    uint32_t r_year_total_sec;
    uint32_t n = 0, d = 0, total_d = 0, rz = 0;
    uint16_t y = 0, r = 0, yr = 0;
    signed long long yd = 0;
    n = seconds;
    total_d = seconds / (SECS_PERDAY);
    d = 0;
    p_year_total_sec = SECS_PERDAY * 365;
    r_year_total_sec = SECS_PERDAY * 366;
    while (n >= p_year_total_sec) {
        if ((EPOCH + r) % 400 == 0 || ((EPOCH + r) % 100 != 0 && (EPOCH + r) % 4 == 0)) {
            n = n - (r_year_total_sec);
            d = d + 366;
        } else {
            n = n - (p_year_total_sec);
            d = d + 365;
        }
        r += 1;
        y += 1;

    }

    y += EPOCH;

    datetime->year = y;

    yd = 0;
    yd = total_d - d;

    yf = 1;
    while (yd >= 28) {

        if (yf == 1 || yf == 3 || yf == 5 || yf == 7 || yf == 8 || yf == 10 || yf == 12) {
            yd -= 31;
            if (yd < 0)break;
            rz += 31;
        }

        if (yf == 2) {
            if (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0)) {
                yd -= 29;
                if (yd < 0)break;
                rz += 29;
            } else {
                yd -= 28;
                if (yd < 0)break;
                rz += 28;
            }
        }
        if (yf == 4 || yf == 6 || yf == 9 || yf == 11) {
            yd -= 30;
            if (yd < 0)break;
            rz += 30;
        }
        yf += 1;

    }

    datetime->month = yf;
    yr = total_d - d - rz;

    yr += 1;

    datetime->day = yr;

    seconds = seconds % SECS_PERDAY;
    datetime->hour = seconds / 3600;
    datetime->min = (seconds % 3600) / 60;
    datetime->sec = (seconds % 3600) % 60;

}

測(cè)試

配置文件(基礎(chǔ))

/*******************************************************************************
 *  Copyright (c) [scl]。保留所有權(quán)利。
 *     本文僅供個(gè)人學(xué)習(xí)和研究使用,禁止用于商業(yè)用途。
 ******************************************************************************/

#include "app_conf.h"
#include "w5500_config.h"

#if APP_CONFIG_W5500
#define DBG_ENABLE
#define DBG_SECTION_NAME "w5500"
#define DBG_LEVEL W5500_DBG_LEVEL

#include "sys_dbg.h"
#include "w5500_dns.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 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外設(shè)*/
    /*W5500 支持 SPI 模式 0 及模式 3..MOSI 和 MISO 信號(hào)無論是接收或發(fā)送,均遵從從最高標(biāo)志位(MSB)到最低標(biāo)志位(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},
                .dns={114, 114, 114, 114},
//                .dns={192, 168, 199, 194},
                .dns_port = 53,
        },
        .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,
        }
};


static void w5500_pre_init(void) {
    /*一般做數(shù)據(jù)加載,此時(shí)系統(tǒng)時(shí)鐘使用的是內(nèi)部時(shí)鐘,如需要使用系統(tǒng)時(shí)鐘的外設(shè)不在此進(jìn)行初始化*/
    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));
}

static void w5500_init(void) {

    w5500_conf.api.msp_init();/*初始化*/
    w5500_conf.net_conf_init();
    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]);
}


static void w5500_after_init(void) {

}

app_init_export(w5500_net_conf, w5500_pre_init, w5500_init, w5500_after_init);
#endif





ntp配置文件(ntp+定時(shí)器6)

/*******************************************************************************
 Copyright (c) [scl]。保留所有權(quán)利。
    @brief NTP CONF
 ******************************************************************************/

#include "app_conf.h"

#define DBG_ENABLE
#define DBG_SECTION_NAME "net_ntp"
#define DBG_LEVEL DBG_LOG

#include "sys_dbg.h"
#include "socket.h"
#include "w5500_ntp.h"

static TIM_HandleTypeDef *ntp_base_timer = NULL;
static struct ntp_conf conf = {
        .ntp_server={114, 118, 7, 163},
        .ntp_port = 123,
        .delay_ms_cb = HAL_Delay
};
struct net_date_time gb_app_time; /*全局使用的時(shí)間*/

static void net_ntp_init() {
    ntp_base_timer = conv_tim_handle_ptr(handle_get_by_id(tim6_id));
    bsp_TimHandleInit(ntp_base_timer, 7199, 9999);/*1s*/
    HAL_TIM_Base_Start_IT(ntp_base_timer);

}

sys_init_export(net_ntp, net_ntp_init);

static void net_ntp_after_init() {


    ntp_config_set(&conf);
    uint8_t try_cnt = 3;
    for (int i = 0; i < try_cnt; ++i) {
        if (ntp_date_time_get(1, 500, &gb_app_time)) {
            HAL_TIM_Base_Start(ntp_base_timer);
            goto exit_ok;
        }
    }
    LOG_W("ntp_date_time_get time out");
    return;
    exit_ok:
    LOG_D("NTP TIME:%d-%02d-%02d %02d:%02d:%02d",
          gb_app_time.year, gb_app_time.month, gb_app_time.day,
          gb_app_time.hour, gb_app_time.min, gb_app_time.sec
    );
}

sys_after_init_export(net_ntp, net_ntp_after_init);

void tim6_PeriodElapsedCallback() {
    ntp_date_time_update();
    net_date_time_loc_get(&gb_app_time);
    LOG_D("NTP TIME:%d-%02d-%02d %02d:%02d:%02d",
          gb_app_time.year, gb_app_time.month, gb_app_time.day,
          gb_app_time.hour, gb_app_time.min, gb_app_time.sec
    );

}

void tim6_it_msp_init(void) {
    HAL_NVIC_SetPriority(TIM6_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(TIM6_IRQn);
}

void tim6_it_msp_de_init(void) {
    HAL_NVIC_DisableIRQ(TIM6_IRQn);
}

void TIM6_IRQHandler(void) {
    HAL_TIM_IRQHandler(ntp_base_timer);
}

結(jié)果

Clion開發(fā)STM32之W5500系列(NTP服務(wù)封裝),STM32相關(guān)驅(qū)動(dòng),stm32,嵌入式硬件,單片機(jī)文章來源地址http://www.zghlxwxcb.cn/news/detail-600565.html

到了這里,關(guān)于Clion開發(fā)STM32之W5500系列(NTP服務(wù)封裝)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Clion開發(fā)STM32之HAL庫USART封裝(基礎(chǔ)庫)

    引用參考: Clion開發(fā)STM32之HAL庫GPIO宏定義封裝(最新版)

    2024年02月14日
    瀏覽(19)
  • Clion開發(fā)STM32之HAL庫I2C封裝(基礎(chǔ)庫)

    引用參考: Clion開發(fā)STM32之HAL庫GPIO宏定義封裝(最新版)

    2024年02月13日
    瀏覽(52)
  • Clion開發(fā)STM32之ESP8266系列(四)

    Clion開發(fā)STM32之ESP8266系列(四)

    上一篇: Clion開發(fā)STM32之ESP8266系列(三) 實(shí)現(xiàn)esp8266需要實(shí)現(xiàn)的函數(shù) 串口3中斷函數(shù)的自定義(這里沒有使用HAL提供的) 封裝esp8266服務(wù)端的代碼和測(cè)試 核心配置頭文件(添加一些宏定義) sys_core_conf.h文件中 源碼 對(duì)應(yīng)的串口3中斷函數(shù)的編寫 頭文件 源文件 本次設(shè)置esp8266模塊的IP為

    2024年02月08日
    瀏覽(52)
  • STM32開發(fā) | Clion搭建STM32開發(fā)環(huán)境

    STM32開發(fā) | Clion搭建STM32開發(fā)環(huán)境

    做嵌入式開發(fā)的人對(duì)STM32這個(gè)平臺(tái)應(yīng)該都是非常熟悉的,在國內(nèi)尤其流行,很多產(chǎn)品里面都是基于這個(gè)平臺(tái)做的方案。多數(shù)人在開發(fā)STM32的時(shí)候用的都是 Keil 這個(gè)老牌IDE,很大一部分原因是因?yàn)榇蠖鄶?shù)人最初是從51單片機(jī)學(xué)習(xí)過來的,51就是基于Keil去開發(fā)的,然后遷移到STM32的

    2023年04月12日
    瀏覽(25)
  • STM32+Clion多線程開發(fā)

    STM32+Clion多線程開發(fā)

    目錄 創(chuàng)建多線程 freertos.c main.cpp main_app.h 二值信號(hào)量 相關(guān)API介紹 (1) osSemaphoreCreate (2)osSemaphoreDelete (3)osSemaphoreRelease (4)osSemaphoreWait 實(shí)際使用 創(chuàng)建信號(hào)量(freertos.c) 在頭文件中外部引用(freertos_inc.h) main.c 關(guān)于clion使用printf,參考【教程】手把手教你用Clion進(jìn)行STM32開

    2024年03月15日
    瀏覽(33)
  • 【使用W5500實(shí)現(xiàn)UDP、TCP通信】

    一、W5500介紹 W5500是一個(gè)集成的以太網(wǎng)模塊,這個(gè)模塊上攜帶TCP/IP協(xié)議,控制器只需要通過SPI協(xié)議讀寫其寄存器便可以以網(wǎng)絡(luò)的方式進(jìn)行數(shù)據(jù)交互。 W5500模塊自帶10個(gè)引腳,但由于使用其官方庫,只需使用六個(gè)引腳便可以進(jìn)行數(shù)據(jù)交互,這六個(gè)引腳分別為:VCC、GND、MISO、MOSI、

    2023年04月08日
    瀏覽(15)
  • STM32CubeMX聯(lián)合CLion開發(fā)環(huán)境搭建

    STM32CubeMX聯(lián)合CLion開發(fā)環(huán)境搭建

    1.1 STM32CubeMX STM32CubeMX是一種圖形化配置工具,用于為STM32微控制器生成啟動(dòng)代碼和初始化配置。它可以幫助簡(jiǎn)化STM32項(xiàng)目的初始化過程,并提供了一種可視化的方式來配置引腳、時(shí)鐘、外設(shè)和中斷等。HAL(Hardware Abstraction Layer)庫是STMicroelectronics提供的一種高級(jí)API層,用于編寫

    2024年02月11日
    瀏覽(30)
  • STM32同步NTP服務(wù)器時(shí)間

    STM32同步NTP服務(wù)器時(shí)間

    目錄 一、NTP ?二、報(bào)文解析 三、代碼 獲取時(shí)間的方式有很多: GPS授時(shí) 、 無卡CDMA授時(shí) 和 網(wǎng)絡(luò)授時(shí) 等,NTP是通過Internet或局域網(wǎng),從NTP服務(wù)器獲取時(shí)間。 NTP時(shí)間服務(wù)器是用于局域網(wǎng)服務(wù)器時(shí)間同步使用的,可以保證局域網(wǎng)所有的服務(wù)器與時(shí)間服務(wù)器的時(shí)間保持一致,SP-SS

    2024年02月10日
    瀏覽(28)
  • Clion開發(fā)STM32之驅(qū)動(dòng)開發(fā)(ST7735S篇)

    ST7735S數(shù)據(jù)手冊(cè) 字庫頭文件(module_st7735s_font.h) 頭文件(module_st7735s.h) 源文件(module_st7735s.c) 實(shí)現(xiàn)對(duì)應(yīng)的驅(qū)動(dòng)接口 測(cè)試單元

    2024年02月07日
    瀏覽(70)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包