使用RT-Thread Studio DIY 迷你桌面時鐘(三)| 獲取NTP時間(at_device軟件包 + netutils軟件包)

尋求更清爽的閱讀體驗,請移步:Mculover666的個人博客

1. 項目進度

桌面Mini時鐘項目用來演示如何使用RT-Thread Stduio開發項目,整個項目的架構如下:

在前兩篇博文中簡單的介紹了RT-Thread Studio一站式工具,基於STM32L431RCT6這個芯片創建工程,並修改時鐘爲使用外部時鐘,以及添加SHT3x軟件包獲取溫溼度傳感器數據。

接下來添加at_device設備ESP8266用於連接網絡,添加netutils軟件包用於獲取NTP時間。

2. 添加ESP8266設備驅動

2.1. 使能libc組件

使用at_device軟件包之前,需要先開啓libc組件:

2.2. 添加at_device軟件包

本項目中使用的是ESP8266設備,其基於AT框架的驅動示例代碼在at_device軟件包中提供。

點擊添加軟件包按鈕,搜索at_device,添加該軟件包:

添加到工程設置之後,右鍵單擊進入該軟件包配置頁面:

配置實際信息:

保存設置,軟件會自動添加at_device軟件包到工程中。

2.3. 開啓lpuart1串口設備

在上一小節配置軟件包的時候,設置的串口設備爲lpuart1,但是目前系統中並沒有設備lpuart1,需要手動在board.h文件中開啓,開啓方法在該文件的註釋中已經說明,如圖:

按照圖中註釋的說明,首先添加使用lpuart1的宏定義,開啓串口:

接下來修改具體lpuart1串口的引腳配置:

接下來爲了後續方便操作控制檯,將sht3x的測試線程先註釋掉:

然後編譯整個項目,下載,查看串口輸出:

可以看到有一個警告,提示 RT_SERIAL_RB_BUFSZ 的值不夠用了,解決方案就是在設置中加大該緩衝區的值:

重新編譯,下載,在串口控制檯中查看網絡是否成功配置:

兩條紅色的日誌打印暫且沒有影響,是因爲使用lpuart的原因,如果換爲使用普通uart,在完全相同的配置下,沒有這兩條信息。

2.4. 測試網絡

再使用下面的命令進行進一步的測試,確保網絡正常能訪問外網:

ifconfig		//使用該命令查看當前網卡配置
ping www.baidu.com	//使用該命令測試外網是否可以ping通

測試結果如下:

3. 添加NTP對時功能

3.1. 添加netutils工具軟件包

netutils軟件包中彙集了 RT-Thread 可用的全部網絡小工具集合,包括NTP工具。

NTP 是網絡時間協議(Network Time Protocol),它是用來同步網絡中各個計算機時間的協議,RT-Thread 上的 NTP 客戶端連接上網絡後,可以獲取當前 UTC 時間,並更新至 RTC 中。

打開配置文件,添加軟件包,搜索NTP之後添加:

右擊軟件包,修改該軟件包的配置:

開啓NTP服務器配置即可:

3.2. 開啓軟件模擬RTC

因爲NTP工具在獲取到網絡時間後,需要同步到本地RTC,所以需要開啓本地模擬RTC功能:

開啓之後保存配置,重新編譯工程,下載,在串口控制檯查看是否可以正常工作。

3.3. 測試NTP工作是否正常

使用NTP工具包自帶的命令進行測試:

ntp_sync	//獲取NTP時間並同步到本地

3.4. 編寫上電自動同步時間代碼

在本項目中,需要上電連接網絡之後,自動獲取NTP時間同步到本地,供後續顯示使用,這段代碼放在main函數中執行。

  • ① 檢測當前網絡是否正常

netdev(network interface device),即網絡接口設備,又稱網卡。每一個用於網絡連接的設備都可以註冊成網卡,爲了適配更多的種類的網卡,避免系統中對單一網卡的依賴,RT-Thread 系統提供了 netdev 組件用於網卡管理和控制。

使用 netdev 網卡功能相關操作函數,需要包含如下頭文件:

#include <arpa/inet.h>         /* 包含 ip_addr_t 等地址相關的頭文件 */
#include <netdev.h>            /* 包含全部的 netdev 相關操作接口函數 */

首先獲取要操作的網卡對象,每個網卡中有唯一的網卡名稱,可以通過網卡名稱獲取網卡對象::

struct netdev *netdev_get_by_name(const char *name);

netdev 網卡提供了一個宏定義用於判斷網卡是否爲 internet_up 狀態,如下:

#define netdev_is_internet_up(netdev)

通過這個宏定義即可判斷當前網絡狀態是否正常,在main函數中添加如下代碼:

//獲取網卡對象
struct netdev* net = netdev_get_by_name("esp0");

//阻塞判斷當前網絡是否正常連接
while(netdev_is_internet_up(net) != 1)
{
   rt_thread_mdelay(200);
}
//提示當前網絡已就緒
rt_kprintf("network is ok!\n");

編譯,下載,效果如下:

  • ② 網絡正常後,獲取NTP時間並同步到本地RTC

要使用NTP工具提供的API,首先包含頭文件:

#include <ntp.h>

接着調用獲取時間並同步的API,原型如下:

time_t ntp_sync_to_rtc(void);

在上面的代碼之後繼續添加NTP對時的代碼:

//NTP自動對時
time_t cur_time;
cur_time = ntp_sync_to_rtc(NULL);
if (cur_time)
{
    rt_kprintf("Cur Time: %s", ctime((const time_t*) &cur_time));
}
else
{
    rt_kprintf("NTP sync fail.\n");
}

編譯,下載,效果如下:

接收更多精彩文章及資源推送,歡迎訂閱我的微信公衆號:『mculover666』。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章