嵌入式里的時間魔法:RTC 與 BKP 深度拆解

文章目錄

  • RTC實時時鐘與BKP
    • Unix時間戳
    • UTC/GMT
    • 時間戳轉換
    • 時間戳轉換
    • BKP簡介
    • BKP基本結構
        • 1. 電池供電模塊(VBAT 輸入)
        • 2. 侵入檢測模塊(TAMPER 輸入)
        • 3. 時鐘輸出模塊(RTC 輸出)
        • 4. 內部寄存器組
    • RTC簡介
      • RTC時鐘源
    • RTC框圖
        • 1. 硬件架構與區域劃分
        • 2. 預分頻器與時鐘處理
        • 3. 計數計時與中斷邏輯
        • 4. 低功耗與待機特性
    • RTC基本結構
    • 硬件電路
        • 1. 備用電池供電電路
        • 2. 外部低速晶振(LSE)電路
        • 3. 引腳功能與復用
        • 4. 硬件設計規范
    • RTC操作注意事項
        • 1. 使能 BKP 和 RTC 訪問(時鐘與權限)
        • 2. 讀取 RTC 前等待 RSF(Registers Synchronized Flag) 同步標志
        • 3. 寫入 RTC 前進入配置模式(CNF 位 Configuration Flag)
        • 4. 寫操作等待 RTOFF(RTC Register Transfer Ongoing Flag) 位(前次寫結束)
    • BKP 庫函數介紹
    • 實時時鐘
      • RCC有關庫函數
      • RTC有關庫函數
      • 實時時鐘代碼編寫步驟

RTC實時時鐘與BKP

Unix時間戳

可以使用time.h,頭文件中的函數將 時間戳轉化為各種類型的時間。
在這里插入圖片描述

UTC/GMT

UTC(協調世界時)

  1. 定義與計時基準
    • 原子鐘(銫 - 133 原子振蕩周期) 為計時基礎,1 秒定義為 “銫 - 133 原子基態的兩個超精細能級之間躍遷所對應的輻射的 9192631770 個周期的持續時間”,精度極高(上千萬年誤差約 1 秒)。
    • 引入 閏秒機制:當原子鐘計時與地球自轉(因地球自轉變慢導致的計時偏差)相差超過 0.9 秒 時,通過在 UTC 時間中插入或刪除 1 秒(如出現 23:59:60 或跳過 23:59:59),消除與地球自轉的誤差,確保時間與晝夜同步(如 2023 年未添加閏秒,最近一次閏秒為 2016 年 12 月 31 日)。
  2. 與 GMT 的關系
    • GMT(格林尼治標準時間) 是基于地球自轉的天文時間 時間長之后會出現誤差(以格林尼治天文臺為基準),而 UTC 是更嚴謹的原子時標準
    • 生活場景中可視為等同:兩者在實際應用中(如手機、電腦的時區設置)差異可忽略,例如 東八區時間 既表示為 UTC+8 也表示為 GMT+8,均指比 UTC/GMT 早 8 小時的時間(如北京時間)。

在這里插入圖片描述

時間戳轉換

時間戳轉換

BKP簡介

  • 含義與用途 :BKP 即 backup registers,是備份寄存器,可存儲用戶自定義數據。
  • 電源特性 :當 VDD 主電源切斷,由 VBAT 備用電池供電,系統喚醒、復位時數據不復位。VDD 供電電壓 2.0 - 3.6 伏,VBAT 供電電壓 1.8 - 3.6 伏。
  • 引腳定義 :VDD 相關引腳為系統主電源,正常使用時接 3.3 伏電源;VBAT 為備用電池供電引腳,使用 BKP 和 RTC 需接備用電池,電池負極與主電源負極共地。若沒有外部電池,建議 VBT 引腳接到 VDD 并連接 100 納法濾波電容。
  • 額外功能 :Temper 引腳侵入事件可清除備份寄存器內容,用于設備防拆(將該引腳與設備外殼相連當外殼被破壞時,會給引腳一個信號,該引腳將寄存器中數據清空);可輸出 RTC 校準時鐘、鬧鐘脈沖或秒脈沖,外部設備可測量校準時鐘校準 RTC 誤差;存儲 RTC 時鐘校準計數器,配合校準時鐘輸出功能校準 RTC。
  • 存儲容量 :中容量和小容量設備里為 20 個字節,大容量和互聯型設備里為 84 個字節。

BKP基本結構

1. 電池供電模塊(VBAT 輸入)
  • 電源特性:BKP 位于后備區域,VDD(2.0-3.6V)主電源掉電后,自動切換為 VBAT(1.8-3.6V)備用電池供電,確保數據不丟失(系統復位、喚醒時數據保持)。
  • 電路設計:無外部電池時,VBAT 可接 VDD 并串聯 100nF 濾波電容(圖中未體現具體電路,但邏輯上支持 VBAT 與 VDD 的電源切換)。
2. 侵入檢測模塊(TAMPER 輸入)
  • 防拆功能:TAMPER 引腳檢測到侵入事件(電平跳變)時,自動清除 BKP 數據寄存器內容(圖中 “侵入檢測” 模塊直接對應此功能,用于設備安全防護,如防拆鎖設計)。
3. 時鐘輸出模塊(RTC 輸出)
  • 功能復用:BKP 可輸出 RTC 的校準時鐘、鬧鐘脈沖或秒脈沖(圖中 “時鐘輸出” 模塊與會議中 “BKP 額外功能” 的時鐘輸出特性一致,支持外部設備校準 RTC 誤差)。
4. 內部寄存器組
  • 數據寄存器(DRx)
    • 容量差異
      • 中 / 小容量芯片(如 STM32F103C8T6):10 個 16 位寄存器(DR1-DR10),共 20 字節(圖中 DR1-DR10 明確標注)。
      • 大容量 / 互聯型芯片:42 個 16 位寄存器(DR1-DR42),共 84 字節(圖中 “大容量和互聯型” 擴展部分,與會議內容匹配)。
    • 存儲特性:寄存器數據在 VDD 掉電后由 VBAT 維持,屬于掉電保持型存儲器。
  • 控制 / 狀態 / 校準寄存器
    • 控制寄存器:配置侵入檢測使能、時鐘輸出模式等(如 TAMPER 觸發使能)。
    • 狀態寄存器:反映侵入事件狀態(如 TAMPER 觸發標志)。
    • RTC 時鐘校準寄存器:存儲 RTC 校準計數器,配合時鐘輸出功能校準 RTC 計時誤差(圖中單獨列出,對應會議中 “存儲 RTC 時鐘校準計數器” 的描述)。

RTC簡介

后面將RTC框圖時,會對下面的簡介進行一一驗證。

RTC時鐘源

  • 可以看到RTC時鐘選擇器 來 進行RTC時鐘選擇,有三種時鐘源。
    • HSE 外部高速時鐘 為8Mhz,要產生1hz的頻率,要先進行128分頻之后才能進行,時鐘傳輸。因為時鐘頻率太大了。
    • LSE外部低速時鐘, 可以說就是為了RTC,設計的時鐘,始終頻率為32.768KHz,是2的次方倍,后面進行時鐘分頻好操作。(一般會選擇使用)
    • LSI 40Khz,也可是為RTC提供時鐘源,但是主要為看門狗外設提供時鐘源。

RTC框圖

1. 硬件架構與區域劃分
  • 后備區域(灰色模塊)
    • 包含預分頻器(RTC_PRL/RTC_DIV)和計數計時單元(RTC_CNT/RTC_ALR)待機時由 VBAT 供電(持續計時),與 APB1 接口(待機斷電)分離,確保主電源掉電后 RTC 獨立運行(匹配會議中 “VDD 斷電后 VBAT 供電繼續走時” 的特性)。
  • APB1 接口:用于軟件配置(如預分頻值、鬧鐘時間),待機時斷電(降低功耗)。
2. 預分頻器與時鐘處理
  • RTCCLK 分頻:通過RTC_PRL(重裝值)和RTC_DIV(余數計數)將輸入時鐘(如 32.768kHz LSE)分頻為1Hz(TR_CLK),驅動 32 位計數器(RTC_CNT)遞增(“20 位可編程預分頻器適配輸入時鐘”,實現秒級計時)。
3. 計數計時與中斷邏輯
  • 32 位計數器(RTC_CNT):存儲 Unix 秒數,溢出周期約 2106 年(觸發RTC_Overflow中斷, “溢出中斷” 的硬件源)。
  • 鬧鐘比較(RTC_ALR):與 RTC_CNT 匹配時觸發RTC_Alarm中斷,可以喚醒待機設備(通過WKP_STDBY邏輯, “鬧鐘喚醒設備退出待機模式”)。
  • 中斷使能(RTC_CR)
    • SECIE(秒中斷)、OWIE(溢出中斷)、ALRIE(鬧鐘中斷)分別控制三類中斷,經 NVIC 處理( “中斷輸出使能和 NVIC 部分” 的硬件實現)。
4. 低功耗與待機特性
  • 后備區域供電:預分頻器和計數計時單元在待機時持續供電(VBAT),確保計時不中斷;APB1 接口、RTC_CR、NVIC 待機時斷電。

RTC基本結構

? 預分頻器中余數寄存器是一個自減設置的,就是來一個時鐘就會計數值減一,當當減到0,會產生一個時鐘信號向后傳遞,PRl重裝值,設置周期,記滿多少次向后產生一個時鐘,當余數寄存器減到0,會將重裝寄存器中的數據重裝到自己的寄存器中,繼續計數。

硬件電路

1. 備用電池供電電路
  • 簡單連接:VBAT 直接接 3V 紐扣電池(如 CR2032),負極與主電源共地。
  • 推薦連接:通過二極管(D1/D2)隔離主電源(VDD)與備用電池(VBAT),并聯 0.1μF 電容(C3)防電流倒灌,確保 VDD 掉電后 VBAT 獨立供電(圖中推薦電路,“防止電源倒灌,提升可靠性”)。
2. 外部低速晶振(LSE)電路
  • 32.768kHz 晶振:連接 OSC32_IN(PC14)和 OSC32_OUT(PC15),兩端并聯 10pF 電容(C1/C2)到地(“LSE 為 RTC 首選時鐘源,精度高,主電源掉電后 VBAT 供電持續工作”)。
  • 作用:提供 1Hz 秒脈沖(經 15 位自然分頻,32768=2^15),驅動 RTC 32 位計數器,實現高精度計時(“20 位可編程預分頻器適配輸入時鐘”,LSE 無需復雜分頻計算)。
3. 引腳功能與復用
  • VBAT 引腳(PC13)
    • 復用為 TAMPER(侵入檢測,觸發時清除 BKP 數據)、RTC 時鐘輸出(秒脈沖 / 鬧鐘信號)或 GPIO(“BKP 額外功能” 的硬件載體,如防拆檢測、時鐘校準輸出)。
  • OSC32 引腳(PC14/PC15):專屬 RTC 時鐘輸入,連接 LSE 晶振( LSE 是 RTC 的核心時鐘源)。
4. 硬件設計規范
  • 電源濾波:VBAT(0.1μF)、LSE 晶振(10pF)均需濾波電容,抑制電源噪聲。
  • 二極管隔離:推薦電路中的 D1/D2(如 1N4148)確保主備電源互不影響,VBAT 在 VDD 掉電后自動接管供電。

RTC操作注意事項

后面進行代碼編寫時會著重強調。

1. 使能 BKP 和 RTC 訪問(時鐘與權限)
  • 硬件保護機制
    BKP 和 RTC 位于后備區域,默認受保護(防止誤操作)。使能 PWR/BKP 時鐘(PWREN/BKPEN)確保模塊供電,DBP(Disable Backup Protection)位解鎖訪問權限,避免非授權代碼篡改掉電保持數據(如 BKP 存儲的校準參數、RTC 計時狀態),保障數據完整性(尤其在主電源掉電后 VBAT 供電的敏感場景)。
2. 讀取 RTC 前等待 RSF(Registers Synchronized Flag) 同步標志
  • 時鐘域異步性
    RTC(RTCCLK,如 32.768kHz)與 APB1 總線(PCLK1,高頻)異步。RSF=1 表示 RTC 寄存器(如 CNT 秒計數)已與 APB1 接口同步,確保讀取時數據最新(避免因時鐘不同步導致時間戳錯誤,如讀取到未更新的秒數),保證計時精度。
3. 寫入 RTC 前進入配置模式(CNF 位 Configuration Flag)
  • 運行時保護
    RTC 正常運行時(CNF=0),計數 / 分頻 / 鬧鐘寄存器為只讀(防止運行中誤寫,如秒計數器遞增時寫入導致計時混亂)。進入配置模式(CNF=1)后,RTC 暫停計時邏輯(“凍結” 時鐘),確保寫入操作(如設置初始時間、鬧鐘)的原子性,避免中間狀態錯誤(如預分頻值半寫入導致頻率偏差)。
4. 寫操作等待 RTOFF(RTC Register Transfer Ongoing Flag) 位(前次寫結束)
  • 寄存器更新時序
    RTC 寄存器屬于 RTCCLK 域,寫入后需時間同步到硬件(如預分頻器重裝)。RTOFF=1 表示前次寫操作完成(值已生效),避免流水線寫操作的競態條件(如連續寫 CNT 和 ALR 時,確保 CNT 先更新,ALR 基于新值比較),保證配置與計時邏輯的一致性,提升系統可靠性(尤其在低功耗場景下,待機喚醒后 RTC 狀態恢復的穩定性)。

BKP 庫函數介紹

函數名功能參數返回值說明
BKP_DeInit恢復 BKP 模塊寄存器至復位默認值初始化前重置配置,確保干凈的工作狀態
BKP_TamperPinLevelConfig配置侵入檢測引腳的有效觸發電平uint16_t BKP_TamperPinLevel(如 BKP_TamperPinLevel_High/Low設定侵入檢測(Tamper)的觸發條件(高 / 低電平)
BKP_TamperPinCmd使能 / 禁止侵入檢測功能FunctionalState NewStateENABLE/DISABLE控制是否啟用侵入檢測(用于系統安全監測)
BKP_ITConfig使能 / 禁止 BKP 模塊的中斷FunctionalState NewState開啟 / 關閉 BKP 相關中斷(如侵入檢測中斷),配合中斷處理函數使用
BKP_RTCOutputConfig配置 RTC_OUT 引腳的輸出信號源uint16_t BKP_RTCOutputSource(如校準時鐘、鬧鐘脈沖、秒脈沖)將 RTC 時鐘信號輸出到外部(如示波器、時鐘模塊),擴展 RTC 功能
BKP_SetRTCCalibrationValue設置 RTC 校準值uint8_t CalibrationValue(-128~+127,補償晶振誤差)調整 RTC 時鐘精度,補償晶振頻率偏移
BKP_WriteBackupRegister寫入備份寄存器(掉電保持)uint16_t BKP_DR(寄存器編號,如BKP_DR1),uint16_t Data(16 位數據)存儲關鍵數據(如系統配置、掉電前狀態),主電源掉電后由備用電池保持
BKP_ReadBackupRegister讀取備份寄存器數據uint16_t BKP_DRuint16_t(寄存器存儲的值)恢復掉電前保存的數據(如系統重啟后讀取配置)
BKP_GetFlagStatus獲取 BKP 模塊的標志位狀態FlagStatusSET/RESET輪詢檢查事件(如侵入檢測是否觸發)
BKP_ClearFlag清除 BKP 模塊的標志位處理標志位后清除(避免重復響應,如侵入檢測標志)
BKP_GetITStatus獲取 BKP 模塊的中斷狀態ITStatusSET/RESET檢查是否有未處理的中斷(用于中斷服務函數)
BKP_ClearITPendingBit清除 BKP 模塊的中斷掛起位中斷處理后清除掛起位,防止重復進入中斷

實時時鐘

RCC有關庫函數

函數名功能描述調用時機注意事項
RCC_LSE_Configure配置并啟動外部低速時鐘(LSE)(如 32.768kHz 晶振)。初始化 RTC 前,需手動開啟 LSE 時鐘LSE 默認關閉,需調用此函數啟動;啟動后需等待LSE_READY標志位為 1。
RCC_LSI_Command配置并啟動內部低速時鐘(LSI)(約 40kHz,用于備份時鐘)。當 LSE 不起振時(如實驗調試場景)可作為 LSE 的替代時鐘源,用于應急或測試。
RTC_CLK_Configure選擇 RTC 的時鐘源(如 LSE/LSI),配置時鐘源數據選擇器。啟動 LSE/LSI 后,配置 RTC 時鐘源時需與RTC_CLK_Command配合使用,先配置時鐘源,再使能時鐘。
RTC_CLK_Command使能 RTC 時鐘(在配置完時鐘源后調用)。配置完RTC_CLK_Configure必須調用此函數才能激活 RTC 時鐘。
RCC_GetFlagStatus獲取時鐘標志位狀態(如LSE_FLAG),判斷時鐘是否穩定啟動。調用RCC_LSE_Configure需循環等待LSE_READY標志位為 1,確保 LSE 時鐘穩定工

RTC有關庫函數

函數名功能描述調用時機注意事項
模式切換函數
RTC_EnterConfigMode進入 RTC 配置模式(置CRL寄存器的CNF位為 1)。需修改 RTC 寄存器(如預分頻器、計數器)前必須先進入配置模式,否則無法寫入寄存器!
RTC_ExitConfigMode退出 RTC 配置模式(清CRL寄存器的CNF位為 0)。完成 RTC 寄存器配置后配置完成后需立即退出,避免誤操作。
數據操作函數
RTC_GetCounter讀取 RTC 計數器(CNT)的值,即當前時間(單位:秒)。需要獲取實時時間時直接返回計數器值,需自行轉換為時分秒格式。
RTC_SetCounter設置 RTC 計數器初始值(如設置初始時間)。初始化 RTC 時配置初始時間需先進入配置模式(調用RTC_EnterConfigMode)。
RTC_SetPrescaler配置預分頻器(PRL寄存器),設置計數器時鐘頻率(通常為 1Hz)。初始化 RTC 時配置分頻系數分頻值計算公式:PRL = LSE頻率/1Hz - 1(如 LSE=32768Hz 時,PRL=32767)。
RTC_SetAlarm設置 RTC 鬧鐘值(ALR寄存器)。需要配置鬧鐘功能時需配合中斷配置(RTC_ITConfig)使用。
RTC_GetDivider讀取預分頻器余數寄存器(DIV),獲取亞秒級精度時間(如毫秒)。需要更高時間精度時(如調試)CNT計數間隔為 1 秒,DIV寄存器用于記錄余數,可計算更細粒度時間。
等待與同步函數
RTC_WaitForLastTask等待上次 RTC 寫操作完成(循環檢測RTF標志位)。每次寫操作(如設置計數器、預分頻器)后防止寄存器操作未完成時進行下一次寫操作,避免數據錯誤!
RTC_WaitForSynchro等待 RTC 時鐘同步完成(循環檢測RSF標志位)。配置時鐘源或初始化 RTC 時確保 RTC 時鐘與時鐘源同步,避免計時誤差。
中斷與標志位函數
RTC_ITConfig配置 RTC 中斷(如鬧鐘中斷、溢出中斷)。需要啟用中斷功能時需結合中斷控制器(NVIC)配置。
[其他標志位函數](如檢查同步狀態、中斷標志等,會議未詳細列出,需結合具體寄存器操作)狀態監控或錯誤處理時需參考官方庫函數文檔或寄存器定義。

實時時鐘代碼編寫步驟

配置時鐘源 -》選擇時鐘源信號 -》配置預分頻器參數 -》配置計數器等

  • 開啟 LSE 時鐘 :調用 RCC 里的 LSE config 函數,參數用 RCC LSE on 啟動外部 LSE 晶振,通過 while 循環調用 RCC get flag status 函數等待 LSE ready 標志位(等待時鐘開啟完成)。
  • 選擇時鐘源 :調用 RCC RTC c LK config 函數,選擇 RCC RTCCLK source LSE,再調用 RCC RTC CRK command 函數使能時鐘。
  • 等待操作 :調用等待同步和等待上一次寫入操作完成的函數,防止時鐘不同步造成 bug。
  • 配置預分頻器 :調用 RTC set prescaler 函數,分頻系數為 32768 - 1,寫入后調用 RTC 等待函數確保操作完成,庫函數自帶進入和退出配置模式代碼。
  • 設置初始時間 :調用 RTC set counter 函數,使用 PPT 里 2023 年 1 月 1 日的秒數設定初始時間,寫入后調用等待函數。

在這里插入圖片描述

RTC相關代碼

// MyRTC.c #include "stm32f10x.h"                  // Device header
#include <time.h>
//創建一個數組,將要寫入的時間存儲到數組中,這里設置的為0時區時間
uint16_t Time[] = {2013, 1, 1, 15, 59, 55};
void MyRTC_SetTime(void);//會出現復位 重新初始化的問題 只要BKP沒有掉電就不用初始化
void RTC_Init(void)
{//使能部分代碼,開啟時鐘 PWR 和 BKPRCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);//pwr 使能對bkp 和 rtc的數據訪問PWR_BackupAccessCmd(ENABLE);if(BKP_ReadBackupRegister(BKP_DR1) != 0xAAaa){//使用lse 時鐘源 配置RCC_LSEConfig(RCC_LSE_ON);//開啟時鐘要等待開啟完成 轉化完成會置標志位while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);//選擇時鐘源RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//開啟RTC時鐘開關RCC_RTCCLKCmd(ENABLE);//下面對RTC進行操作//等待時鐘同步RTC_WaitForSynchro();//每一次進行寫操作時,要進行判斷上一個字節是否寫入完成RTC_WaitForLastTask();//設置分頻器數據//分頻后的頻率 = 時鐘源頻率 / (預分頻系數)RTC_SetPrescaler(32768 - 1);//等待數據寫入完成RTC_WaitForLastTask();//設置計數值 這里是初始化所以就是初始值MyRTC_SetTime();//等待數據寫入完成RTC_WaitForLastTask();BKP_WriteBackupRegister(BKP_DR1, 0xAAaa);}else{//使用lse 時鐘源 配置RCC_LSEConfig(RCC_LSE_ON);//開啟時鐘要等待開啟完成 轉化完成會置標志位while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);//選擇時鐘源RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//開啟RTC時鐘開關RCC_RTCCLKCmd(ENABLE);//下面對RTC進行操作//等待時鐘同步RTC_WaitForSynchro();//每一次進行寫操作時,要進行判斷上一個字節是否寫入完成RTC_WaitForLastTask();}}//實現寫時間的函數
void MyRTC_SetTime(void)
{time_t time_cnt;struct tm time_data;//將要設置的時間寫入結構體中time_data.tm_year = Time[0] - 1900;time_data.tm_mon = Time[1] - 1;time_data.tm_mday = Time[2];time_data.tm_hour = Time[3];time_data.tm_min = Time[4];time_data.tm_sec = Time[5];//將結構體中數據轉化為時間戳time_cnt = mktime(&time_data);//將獲取的秒計數進行 計數器設置//設置計數值 這里是初始化所以就是初始值RTC_SetCounter(time_cnt);//等待數據寫入完成RTC_WaitForLastTask();}//實現讀取時間函數
//讀取秒計數,將秒計數轉化為結構體將,結構體中數據按順序存儲到數組中
void MyRTC_GetData(void)
{time_t time_cnt;struct tm time_data;//將得到的0時區的時間轉化為東8區時間time_cnt = RTC_GetCounter() + 8 * 60 * 60;time_data = *localtime(&time_cnt);Time[0] = time_data.tm_year + 1900;Time[1] = time_data.tm_mon + 1;Time[2] = time_data.tm_mday;Time[3] = time_data.tm_hour;Time[4] = time_data.tm_min;Time[5] = time_data.tm_sec;
}

主函數實現代碼

//main.c#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"int main(void)
{OLED_Init();RTC_Init();OLED_ShowString(1, 1, "Date:XXXX-XX-XX");OLED_ShowString(2, 1, "Time:XX:XX:XX");OLED_ShowString(3, 1, "CNT :");OLED_ShowString(4, 1, "DIV :");while(1){MyRTC_GetData();							//RTC讀取時間,最新的時間存儲到MyRTC_Time數組中OLED_ShowNum(1, 6, Time[0], 4);		//顯示MyRTC_Time數組中的時間值,年OLED_ShowNum(1, 11, Time[1], 2);		//月OLED_ShowNum(1, 14, Time[2], 2);		//日OLED_ShowNum(2, 6, Time[3], 2);		//時OLED_ShowNum(2, 9, Time[4], 2);		//分OLED_ShowNum(2, 12, Time[5], 2);		//秒OLED_ShowNum(3, 6, RTC_GetCounter(), 10);	//顯示32位的秒計數器OLED_ShowNum(4, 6, RTC_GetDivider(), 10);	//顯示余數寄存器}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82969.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82969.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82969.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

STC8H系列 驅動步進電機

STC8H 驅動步進電機 一、引言二、硬件設計三、軟件設計Step_Motor2.c文件Step_ Motor2.h文件 一、引言 眾所周知STC8H系列有兩個PWM&#xff0c;分別為PWMA和PWMB外設模塊&#xff0c;我全都用上&#xff0c;豈不是就有兩個帶動電機的脈沖信號&#xff1f;&#xff01;哈哈哈哈…

Python高階函數:從入門到精通

目錄 Python高階函數詳解&#xff1a;從概念到高級應用引言&#xff1a;函數式編程的魅力一、高階函數基礎概念1.1 什么是高階函數1.2 Python中的一等函數 二、內置高階函數詳解2.1 map函數&#xff1a;數據轉換利器2.2 filter函數&#xff1a;數據篩選專家2.3 reduce函數&…

騰訊開源視頻生成工具 HunyuanVideo-Avatar,上傳一張圖+一段音頻,就能讓圖中的人物、動物甚至虛擬角色“活”過來,開口說話、唱歌、演相聲!

騰訊混元團隊提出的 HunyuanVideo-Avatar 是一個基于多模態擴散變換器&#xff08;MM-DiT&#xff09;的模型&#xff0c;能夠生成動態、情緒可控和多角色對話視頻。支持僅 10GB VRAM 的單 GPU運行&#xff0c;支持多種下游任務和應用。例如生成會說話的虛擬形象視頻&#xff0…

DeepSeek-R1-0528:開源推理模型的革新與突破

一、 發布日期與背景 2025年5月29日&#xff0c;備受業界關注的DeepSeek推理模型DeepSeek-R1迎來重要更新——DeepSeek-R1-0528模型正式發布。此次更新采取了“靜默發布”策略&#xff0c;未提前預告&#xff0c;而是通過官方渠道&#xff08;官網、App、小程序&#xff09;及…

LeetCode 1723: 完成所有工作的最短時間

給你一個整數數組 jobs &#xff0c;其中 jobs[i] 是完成第 i 項工作要花費的時間。 請你將這些工作分配給 k 位工人。所有工作都應該分配給工人&#xff0c;且每項工作只能分配給一位工人。工人的 工作時間 是完成分配給他們的所有工作花費時間的總和。請你設計一套最佳的工作…

JDK8新特性之Steam流

這里寫目錄標題 一、Stream流概述1.1、傳統寫法1.2、Stream寫法1.3、Stream流操作分類 二、Stream流獲取方式2.1、根據Collection獲取2.2、通過Stream的of方法 三、Stream常用方法介紹3.1、forEach3.2、count3.3、filter3.4、limit3.5、skip3.6、map3.7、sorted3.8、distinct3.…

split方法

在編程中&#xff0c;split 方法通常用于將字符串按照指定的分隔符拆分成多個部分&#xff0c;并返回一個包含拆分結果的列表&#xff08;或數組&#xff09;。不同編程語言中的 split 方法語法略有不同&#xff0c;但核心功能相似。以下是常見語言中的用法&#xff1a; ?1. P…

深入理解 x86 匯編中的符號擴展指令:從 CBW 到 CDQ 的全解析

引入 在匯編語言的世界里&#xff0c;數據寬度的轉換是一項基礎卻至關重要的操作。尤其是在處理有符號數時&#xff0c;符號擴展&#xff08;Sign Extension&#xff09;作為保持數值符號一致性的核心技術&#xff0c;直接影響著運算結果的正確性。本文將聚焦 x86 架構中最常用…

計算機基礎知識(第五篇)

計算機基礎知識&#xff08;第五篇&#xff09; 架構演化與維護 軟件架構的演化和定義 軟件架構的演化和維護就是對架構進行修改和完善的過程&#xff0c;目的就是為了使軟件能夠適應環境的變化而進行的糾錯性修改和完善性修改等&#xff0c;是一個不斷迭代的過程&#xff0…

前端開發三劍客:HTML5+CSS3+ES6

在前端開發領域&#xff0c;HTML、CSS和JavaScript構成了構建網頁與Web應用的核心基礎。隨著技術標準的不斷演進&#xff0c;HTML5、CSS3以及ES6&#xff08;ECMAScript 2015及后續版本&#xff09;帶來了諸多新特性與語法優化&#xff0c;極大地提升了開發效率和用戶體驗。本文…

c++ 頭文件

目錄 防止頭文件重復包含 頭文件的作用 如何讓程序的多個 .cpp 文件之間共享全局變量&#xff08;可能是 int、結構體、數組、指針、類對象&#xff09;? 防止頭文件重復包含 為什么要防止頭問件重復包含&#xff1f; 當然一般也不會把變量定義放到頭問件&#xff0c;那為…

深入解析 JavaScript 中 var、let、const 的核心區別與實踐應用

一、歷史背景與語法基礎 JavaScript 作為動態弱類型語言&#xff0c;變量聲明機制經歷了從 ES5 到 ES6 的重大變革。在 ES5 及更早版本中&#xff0c;var 是唯一的變量聲明方式&#xff0c;而 ES6&#xff08;2015 年&#xff09;引入了 let 和 const&#xff0c;旨在解決 var…

【Linux庖丁解牛】—自定義shell的編寫!

1. 打印命令行提示符 在我們使用系統提供的shell時&#xff0c;每次都會打印出一行字符串&#xff0c;這其實就是命令行提示符&#xff0c;那我們自定義的shell當然也需要這一行字符串。 這一行字符串包含用戶名&#xff0c;主機名&#xff0c;當前工作路徑&#xff0c;所以&a…

應用案例 | 設備分布廣, 現場維護難? 宏集Cogent DataHub助力分布式鍋爐遠程運維, 讓現場變“透明”

在日本&#xff0c;能源利用與環保問題再次成為社會關注的焦點。越來越多的工業用戶開始尋求更高效、可持續的方式來運營設備、管理能源。而作為一家專注于節能與自動化系統集成的企業&#xff0c;日本大阪的TESS工程公司給出了一個值得借鑒的答案。 01 鍋爐遠程監控難題如何破…

【OSG學習筆記】Day 16: 骨骼動畫與蒙皮(osgAnimation)

骨骼動畫基礎 骨骼動畫是 3D 計算機圖形中常用的技術&#xff0c;它通過以下兩個主要組件實現角色動畫。 骨骼系統 (Skeleton)&#xff1a;由層級結構的骨頭組成&#xff0c;類似于人體骨骼蒙皮 (Mesh Skinning)&#xff1a;將模型網格頂點綁定到骨骼上&#xff0c;使骨骼移動…

jdk同時安裝多個版本并自由切換

一、安裝不同版本的JDK 二、配置環境變量&#xff08;多版本JDK&#xff09; 1. 新建版本專用環境變量&#xff08;用于切換&#xff09; 操作位置&#xff1a;系統變量 > 新建 變量名&#xff1a;JAVA_HOME_1.8 變量值&#xff1a;JDK 8安裝路徑變量名&#xff1a;JAVA1…

java中裝飾模式

目錄 一 裝飾模式案例說明 1.1 說明 1.2 代碼 1.2.1 定義數據服務接口 1.2.2 定義基礎數據庫服務實現 1.2.3 日志裝飾器 1.2.4 緩存裝飾器 1.2.5 主程序調用 1.3 裝飾模式的特點 一 裝飾模式案例說明 1.1 說明 本案例是&#xff1a;數據查詢增加緩存&#xff0c;使用…

【論文閱讀】YOLOv8在單目下視多車目標檢測中的應用

Application of YOLOv8 in monocular downward multiple Car Target detection????? 原文真離譜&#xff0c;文章都不全還發上來 引言 自動駕駛技術是21世紀最重要的技術發展之一&#xff0c;有望徹底改變交通安全和效率。任何自動駕駛系統的核心都依賴于通過精確物體檢…

在uni-app中如何從Options API遷移到Composition API?

uni-app 從 Options API 遷移到 Composition API 的詳細指南 一、遷移前的準備 升級環境&#xff1a; 確保 HBuilderX 版本 ≥ 3.2.0項目 uni-app 版本 ≥ 3.0.0 了解 Composition API 基礎&#xff1a; 響應式系統&#xff1a;ref、reactive生命周期鉤子&#xff1a;onMount…

408第一季 - 數據結構 - 圖

圖的概念 完全圖 無向圖的完全圖可以這么想&#xff1a;如果有4個點&#xff0c;每個點都會連向3個點&#xff0c;每個點也都會有來回的邊&#xff0c;所以除以2 有向圖就不用除以2 連通分量 不多解釋 極大連通子圖的意思就是讓你把所有連起來的都圈出來 強連通圖和強連通…