91在线观看视频-91在线观看视频-91在线观看免费视频-91在线观看免费-欧美第二页-欧美第1页

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

第十三章 RTC 實時時鐘

W55MH32 ? 來源:W55MH32 ? 作者:W55MH32 ? 2025-05-28 11:32 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

單芯片解決方案,開啟全新體驗——W55MH32 高性能以太網單片機

W55MH32是WIZnet重磅推出的高性能以太網單片機,它為用戶帶來前所未有的集成化體驗。這顆芯片將強大的組件集于一身,具體來說,一顆W55MH32內置高性能Arm? Cortex-M3核心,其主頻最高可達216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲與數據處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協議棧、內置MAC以及PHY,擁有獨立的32KB以太網收發緩存,可供8個獨立硬件socket使用。如此配置,真正實現了All-in-One解決方案,為開發者提供極大便利。

在封裝規格上,W55MH32 提供了兩種選擇:QFN68和QFN100。

W55MH32Q采用QFN68封裝版本,尺寸為8x8mm,它擁有36個GPIO、3個ADC、12通道DMA、17個定時器、2個I2C、3個串口、2個SPI接口(其中1個帶I2S接口復用)、1個CAN以及1個USB2.0。在保持與同系列其他版本一致的核心性能基礎上,僅減少了部分GPIO以及SDIO接口,其他參數保持一致,性價比優勢顯著,尤其適合網關模組等對空間布局要求較高的場景。緊湊的尺寸和精簡化外設配置,使其能夠在有限空間內實現高效的網絡連接與數據交互,成為物聯網網關、邊緣計算節點等緊湊型設備的理想選擇。 同系列還有QFN100封裝的W55MH32L版本,該版本擁有更豐富的外設資源,適用于需要多接口擴展的復雜工控場景,軟件使用方法一致。更多信息和資料請進入http://www.w5500.com/網站或者私信獲取。

此外,本W55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應用,涵蓋TCP SSL、HTTP SSL以及MQTT SSL等,為網絡通信安全再添保障。

為助力開發者快速上手與深入開發,基于W55MH32Q這顆芯片,WIZnet精心打造了配套開發板。開發板集成WIZ-Link芯片,借助一根USB C口數據線,就能輕松實現調試、下載以及串口打印日志等功能。開發板將所有外設全部引出,拓展功能也大幅提升,便于開發者全面評估芯片性能。

若您想獲取芯片和開發板的更多詳細信息,包括產品特性、技術參數以及價格等,歡迎訪問官方網頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。

wKgZO2gbOfaAVPzkACJSygzv-rI600.png

第十三章 RTC 實時時鐘

本章分為如下幾個小節:

1 RTC簡介

2 功能描述

3 RTC寄存器描述

4 程序設計

5 下載驗證

1 RTC簡介

實時時鐘是一個獨立的定時器。RTC 模塊擁有一組連續計數的計數器,在相應軟件配置下,可提供時鐘日歷的功能。修改計數器的值可以重新設置系統當前的時間和日期。

RTC 模塊和時鐘配置系統(RCC_BDCR 寄存器)處于后備區域,即在系統復位或從待機模式喚醒后,RTC 的設置和時間維持不變。系統復位后,對后備寄存器和 RTC 的訪問被禁止,這是為了防止對后備區域(BKP)的意外寫操作。

執行以下操作將使能對后備寄存器和 RTC 的訪問:

?設置寄存器 RCC_APB1ENR 的 PWREN 和 BKPEN 位,使能電源和后備接口時鐘

?設置寄存器 PWR_CR 的 DBP 位,使能對后備寄存器和 RTC 的訪問。

1.1 主要特性

W55MH32的RTC的主要特性如下:

?可編程的預分頻系數:分頻系數最高為 220。

?32 位的可編程計數器,可用于較長時間段的測量。

?2 個分離的時鐘:用于 APB1 接口的 PCLK1 和 RTC 時鐘(RTC 時鐘的頻率必須小于 PCLK1 時鐘頻率的四分之一以上)。

?可以選擇以下三種 RTC 的時鐘源:

······ HSE 時鐘除以 128;

······LSE 振蕩器時鐘;

······LSI 振蕩器時鐘(詳見 6.2.8 節 RTC 時鐘)。

?2 個獨立的復位類型:

······APB1 接口由系統復位;

······RTC 核心(預分頻器、鬧鐘、計數器和分頻器)只能由后備域復位(詳見 6.1.3 節)。

?3 個專門的可屏蔽中斷:

·······鬧鐘中斷,用來產生一個軟件可編程的鬧鐘中斷。

······秒中斷,用來產生一個可編程的周期性中斷信號(最長可達 1 秒)。

······溢出中斷,指示內部可編程計數器溢出并回轉為 0 的狀態。

2 功能描述

2.1 概述

RTC 由兩個主要部分組成(參見下圖)。第一部分(APB1 接口)用來和 APB1 總線相連。此單元還包含一組 16 位寄存器,可通過 APB1 總線對其進行讀寫操作。APB1 接口由 APB1 總線時鐘驅動,用來與 APB1 總線接口。

另一部分(RTC 核心)由一組可編程計數器組成,分成兩個主要模塊。第一個模塊是 RTC 的預分頻模塊,它可編程產生最長為 1 秒的 RTC 時間基準 TR_CLK。RTC 的預分頻模塊包含了一個 20 位的可編程分頻器(RTC 預分頻器)。如果在 RTC_CR 寄存器中設置了相應的允許位,則在每個TR_CLK 周期中 RTC 產生一個中斷(秒中斷)。第二個模塊是一個 32 位的可編程計數器,可被初始化為當前的系統時間。系統時間按 TR_CLK 周期累加并與存儲在 RTC_ALR 寄存器中的可編程時間相比較,如果 RTC_CR 控制寄存器中設置了相應允許位,比較匹配時將產生一個鬧鐘中斷。

wKgZPGg2gtyAO92YAAL2EvNSggM130.png

簡化的 RTC 框圖

2.2 復位過程

除了 RTC_PRL、RTC_ALR、RTC_CNT 和 RTC_DIV 寄存器外,所有的系統寄存器都由系統復位或電源復位進行異步復位。

2.3 讀RTC寄存器

RTC 核完全獨立于 RTCAPB1 接口。

軟件通過 APB1 接口訪問 RTC 的預分頻值、計數器值和鬧鐘值。但是,相關的可讀寄存器只在與RTCAPB1 時鐘進行重新同步的 RTC 時鐘的上升沿被更新。RTC 標志也是如此的。這意味著,如果 APB1 接口曾經被關閉,而讀操作又是在剛剛重新開啟 APB1 之后,則在第一次的內部寄存器更新之前,從 APB1 上讀出的 RTC 寄存器數值可能被破壞了(通常讀到 0)。下述幾種情況下能夠發生這種情形:

發生系統復位或電源復位

系統剛從待機模式喚醒(參見第 18.3節:低功耗模式)。

系統剛從停機模式喚醒(參見第 18.3節:低功耗模式)。

所有以上情況中,APB1 接口被禁止時(復位、無時鐘或斷電)RTC 核仍保持運行狀態。

因此,若在讀取 RTC 寄存器時,RTC 的 APB1 接口曾經處于禁止狀態,則軟件首先必須等待RTC_CRL 寄存器中的 RSF 位(寄存器同步標志)被硬件置'1')。

注: RTC 的 APB1 接口不受 WFI 和 WFE 等低功耗模式的影響。

2.4 配置RTC寄存器

必須設置RTC_CRL寄存器中的CNF位,使RTC進入配置模式后,才能寫入 RTC_PRL、RTC_CNT、RTC_ALR 寄存器。

另外,對 RTC 任何寄存器的寫操作,都必須在前一次寫操作結束后進行??梢酝ㄟ^查詢 RTC_CR寄存器中的 RTOFF 狀態位,判斷 RTC 寄存器是否處于更新中。僅當 RTOFF 狀態位是'1'時,才可以寫入 RTC 寄存器。

配置過程:

1. 查詢 RTOFF 位,直到 RTOFF 的值變為'1'

2. 置 CNF 值為 1,進入配置模式

3. 對一個或多個 RTC 寄存器進行寫操作

4. 清除 CNF 標志位,退出配置模式

5. 查詢 RTOFF,直至 RTOFF 位變為'1'以確認寫操作已經完成。僅當 CNF 標志位被清除時,寫操作才能進行,這個過程至少需要 3 個 RTCCLK 周期。

2.5 RTC標志的設置

在每一個 RTC 核心的時鐘周期中,更改 RTC 計數器之前設置 RTC 秒標志(SECF)。在計數器到達0x0000 之前的最后一個 RTC 時鐘周期中,設置 RTC 溢出標志(OWF)。

在計數器的值到達鬧鐘寄存器的值加 1(RTC_ALR+1)之前的 RTC 時鐘周期中,設置 RTC_Alarm 和RTC 鬧鐘標志(ALRF)。對 RTC 鬧鐘的寫操作必須使用下述過程之一與 RTC 秒標志同步:

使用 RTC 鬧鐘中斷,并在中斷處理程序中修改 RTC 鬧鐘和/或 RTC 計數器。

等待 RTC 控制寄存器中的 SECF 位被設置,再更改 RTC 鬧鐘和/或 RTC 計數器。

wKgZO2g2gtuAWKpuAABQOZmGcbk772.png

RTC 秒和鬧鐘波形圖示例,PR=0003,ALARM=00004

wKgZPGg2gtuAETx0AABTF3gS0Ig259.png

RTC 溢出波形圖示例,PR=0003

3 RTC寄存器描述

3.1 RTC控制寄存器高位(RTC_CRH)

偏移地址:0x00

復位值:0x0000

wKgZO2g2gtuAVCpNAAE-dfGDb5w570.png

這些位用來屏蔽中斷請求。注意:系統復位后所有的中斷被屏蔽,因此可通過寫 RTC 寄存器來確保在初始化后沒有掛起的中斷請求。當外設正在完成前一次寫操作時(標志位 RTOFF=0),不能對RTC_CRH 寄存器進行寫操作。RTC 功能由這個控制寄存器控制。

3.2 RTC控制寄存器低位(RTC_CRL)

偏移地址:0x00

復位值:0x0000

wKgZO2g2gt2AMIwcAAbAsZRFPQA209.png

注:1.任何標志位都將保持掛起狀態,直到適當的 RTC_CR 請求位被軟件復位,表示所請求的中斷已經被接受。

2.在復位時禁止所有中斷,無掛起的中斷請求,可以對 RTC 寄存器進行寫操作。

3.當 APB1 時鐘不運行時,OWF、ALRF、SECF 和 RSF 位不被更新。

4.OWF、ALRF、SECF 和 RSF 位只能由硬件置位,由軟件來清零。

5.若 ALRF=1 且 ALRIE=1,則允許產生 RTC 全局中斷。如果在 EXTI 控制器中允許產生 EXTI 線 17 中斷,則允許產生 RTC 全局中斷和 RTC 鬧鐘中斷。

6.若 ALRF=1,如果在 EXTI 控制器中設置了 EXTI 線 17 的中斷模式,則允許產生 RTC 鬧鐘中斷;如果在 EXTI 控制器中設置了 EXTI 線 17 的事件模式,則這條線上會產生一個脈沖(不會產生 RTC鬧鐘中斷)。

3.3 RTC預分頻裝載寄存器(RTC_PRLH/RTC_PRLL)

預分頻裝載寄存器用來保存 RTC 預分頻器的周期計數值。它們受 RTC_CR 寄存器的 RTOFF 位保護,僅當 RTOFF 值為'1'時允許進行寫操作。

RTC 預分頻裝載寄存器高位(RTC_PRLH)

偏移地址:0x08

復位值:0x0000

wKgZPGg2gtyATt7XAAHOGa_KgWg536.png

RTC 預分頻裝載寄存器低位(RTC_PRLL)

偏移地址:0x0C

復位值:0x8000

wKgZPGg2gtuAJr6aAADTVrBNncE349.png

注: 如果輸入時鐘頻率(fRTCCLK)為 32.768 千赫,則在此寄存器中寫入 7FFFh 以獲得 1 秒的信號周期

3.4 RTC預分頻器余數寄存器(RTC_DIVH/RTC_DIVL)

在 TR_CLK 的每個周期里,RTC 預分頻器中計數器的值都會被重新設置為 RTC_PRL 寄存器的值。用戶可通過讀取 RTC_DIV 寄存器,以獲得預分頻計數器的當前值,而不停止分頻計數器的工作,從而獲得精確的時間測量。此寄存器是只讀寄存器,其值在 RTC_PRL 或 RTC_CNT 寄存器中的值發生改變后,由硬件重新裝載。

RTC 預分頻器余數寄存器高位(RTC_DIVH)

偏移地址:0x10

復位值:0x0000

wKgZO2g2gtuAcr6BAACUkDXJI2c091.png

RTC 預分頻器余數寄存器低位(RTC_DIVL)

偏移地址:0x14

復位值:0x8000

wKgZPGg2gtuAJr6aAADTVrBNncE349.png

3.5 RTC計數器寄存器(RTC_CNTH/RTC_CNTL)

RTC 核有一個 32 位可編程的計數器,可通過兩個 16 位的寄存器訪問。計數器以預分頻器產生的TR_CLK時間基準為參考進行計數。RTC_CNT寄存器用來存放計數器的計數值。他們受 RTC_CR的位RTOFF寫保護,僅當RTOFF值為'1'時,允許寫操作。在高或低寄存器(RTC_CNTH或RTC_CNTL)上的寫操作,能夠直接裝載到相應的可編程計數器,并且重新裝載 RTC 預分頻器。當進行讀操作時,直接返回計數器內的計數值(系統時間)。

RTC 計數器寄存器高位(RTC_CNTH)

偏移地址:0x18

復位值:0x0000

wKgZO2g2gtuAZBeOAADEt3w5CV4574.png

RTC 計數器寄存器低位(RTC_CNTL)

偏移地址:0x1C

復位值:0x0000

wKgZPGg2gtuAatcOAADGAT390g4207.png

3.6 RTC鬧鐘寄存器(RTC_ALRH/RTC_ALRL)

當可編程計數器的值與 RTC_ALR 中的 32 位值相等時,即觸發一個鬧鐘事件,并且產生 RTC 鬧鐘中斷。此寄存器受 RTC_CR 寄存器里的 RTOFF 位寫保護,僅當 RTOFF 值為'1'時,允許寫操作。

RTC 鬧鐘寄存器高位(RTC_ALRH)

偏移地址:0x20

復位值:0xFFFF

wKgZPGg2gtuAGaZZAAC6xOcL1pI689.png

RTC 鬧鐘寄存器低位(RTC_ALRL)

偏移地址:0x24

復位值:0xFFFF

wKgZO2g2gtuAB8HLAAC6HFoBHCs550.png

3.7 RTC寄存器映像

RTC-寄存器映像和復位值

wKgZO2g2gtyAeJvKAAHN1MrlvTg654.png

4 程序設計

4.1 RTC_Calendar例程

1.初始化部分:延時初始化:調用delay_init()函數,雖未展示其具體實現,但為程序提供時間相關基礎功能。

?時鐘配置:RCC_ClkConfiguration()函數對系統時鐘進行配置。先復位 RCC,開啟 HSE 并等待其就緒,配置 PLL 為 HSE 經 1 分頻后輸入,9 倍頻輸出,使能 PLL 并等待其就緒,選擇 PLLCLK 作為系統時鐘源,同時設置 HCLK、PCLK1 和 PCLK2 的分頻因子,還開啟 LSI 和 HSI。

?串口初始化:UART_Configuration()函數配置 USART1 串口。使能 USART1 和 GPIOA 時鐘,將 PA9 配置為復用推挽輸出(TX),PA10 配置為浮空輸入(RX),設置波特率為 115200,數據位 8 位,停止位 1 位,無校驗,無硬件流控制,工作模式為收發模式,最后使能串口。

?NVIC 配置:NVIC_Configuration()函數設置 NVIC 優先級分組為 1,使能 RTC 中斷,設置其搶占優先級為 1,子優先級為 0。

?RTC 配置:RTC_Configuration()函數配置 RTC。使能 PWR 和 BKP 時鐘,允許訪問備份區域,對 BKP 進行初始化,開啟 LSI 并等待其就緒,選擇 LSI 作為 RTC 時鐘源,使能 RTC 時鐘并等待同步,設置 RTC 秒中斷,設置預分頻器為 32767,使 RTC 周期為 1 秒。

2.主循環部分:在main()函數中,先進行延時、時鐘配置,接著配置串口,輸出 “RTC Calendar Test.” 及系統時鐘頻率信息。檢查 BKP 寄存器值判斷 RTC 是否已配置,若未配置則進行 RTC 配置并設置時間,若已配置則判斷復位類型并根據情況處理。最后調用Time_Show()函數進入一個循環,當TimeDisplay為 1 時顯示當前時間。

3.時間調整與顯示部分:時間調整:Time_Adjust()函數調用Time_Regulate()函數獲取用戶通過串口輸入的時分秒,然后設置 RTC 計數器。

// 時間調整函數(通過串口輸入設置時間)
void Time_Adjust(void)
{
    RTC_WaitForLastTask();
    RTC_SetCounter(Time_Regulate()); // 調用輸入函數獲取時間并設置RTC計數器
    RTC_WaitForLastTask();
}
// 時間輸入函數(串口交互獲取時分秒)
uint32_t Time_Regulate(void)
{
    uint32_t Tmp_HH, Tmp_MM, Tmp_SS;
    
    // 輸入小時(0-23)
    printf("rn  Please Set Hours");
    while ((Tmp_HH = USART_Scanf(23)) == 0xFF);
    
    // 輸入分鐘(0-59)
    printf("rn  Please Set Minutes");
    while ((Tmp_MM = USART_Scanf(59)) == 0xFF);
    
    // 輸入秒(0-59)
    printf("rn  Please Set Seconds");
    while ((Tmp_SS = USART_Scanf(59)) == 0xFF);
    
    return (Tmp_HH * 3600 + Tmp_MM * 60 + Tmp_SS); // 返回總秒數
}
// 時間顯示函數(實時打印時間)
void Time_Show(void)
{
    printf("nr");
    while (1)
    {
        if (TimeDisplay == 1) // TimeDisplay由RTC中斷觸發置1
        {
            Time_Display(RTC_GetCounter()); // 轉換并顯示時間
            TimeDisplay = 0;
        }
    }
}
// 時間格式化顯示
void Time_Display(uint32_t TimeVar)
{
    uint32_t THH = TimeVar / 3600;
    uint32_t TMM = (TimeVar % 3600) / 60;
    uint32_t TSS = TimeVar % 60;
    
    // 計數器溢出處理(約24小時歸零)
    if (RTC_GetCounter() == 0x0001517F) 
    {
        RTC_SetCounter(0);
        RTC_WaitForLastTask();
    }
    
    printf("Time: %02d:%02d:%02dn", THH, TMM, TSS);
}

時間顯示:Time_Show()函數進入一個循環,當TimeDisplay為 1 時,調用Time_Display()函數獲取 RTC 計數器的值并轉換為時、分、秒格式進行顯示。同時,Time_Display()函數還會在 RTC 計數器達到特定值(0x0001517F)時將其重置為 0。

4.串口輸入處理部分:USART_Scanf()函數用于從串口接收用戶輸入的數字,檢查輸入是否為有效數字,若無效則提示用戶重新輸入,直到輸入有效數字。

4.2 RTC_LSICalib例程

1.初始化部分:延時初始化:調用delay_init()函數,雖未給出其具體實現,但為程序提供時間相關的基礎功能。

// 1. 延時初始化(依賴delay.h實現)
delay_init();

// 1.a 串口初始化
void UART_Configuration(uint32_t bound)
{
    // 使能時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
    
    // 配置TX/RX引腳
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;  // PA9-TX
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10;  // PA10-RX
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // 配置串口參數
    USART_InitStructure.USART_BaudRate = bound;  // 115200bps
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    
    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);
}

// 1.b RTC配置
void RTC_Configuration(void)
{
    // 使能電源和備份域時鐘
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    PWR_BackupAccessCmd(ENABLE);
    
    BKP_DeInit();  // 復位備份域
    
    // 配置RTC時鐘源(LSI)
    RCC_LSICmd(ENABLE);
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
    RCC_RTCCLKCmd(ENABLE);
    
    RTC_WaitForSynchro();  // 等待RTC寄存器同步
    RTC_ITConfig(RTC_IT_SEC, ENABLE);  // 使能秒中斷
    RTC_SetPrescaler(40000);  // 預設預分頻值(假設LSI=40kHz)
    
    // 配置RTC輸出
    BKP_TamperPinCmd(DISABLE);
    BKP_RTCOutputConfig(BKP_RTCOutputSource_Second);
}

// 1.c 定時器配置(TIM5用于測量LSI頻率)
void TIM_Configuration(void)
{
    // 使能時鐘和引腳重映射
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
    GPIO_PinRemapConfig(GPIO_Remap_TIM5CH4_LSI, ENABLE);
    
    // 配置TIM5時基
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
    
    // 配置TIM5通道4為輸入捕獲模式
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0;
    TIM_ICInit(TIM5, &TIM_ICInitStructure);
    
    // 使能TIM5和捕獲中斷
    TIM_Cmd(TIM5, ENABLE);
    TIM5->SR = 0;  // 清除中斷標志
    TIM_ITConfig(TIM5, TIM_IT_CC4, ENABLE);
}

// 1.d NVIC中斷配置
void NVIC_Configuration(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  // 優先級分組1
    
    // 配置RTC中斷(最高優先級)
    NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    // 配置TIM5中斷(次高優先級)
    NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

串口初始化:UART_Configuration()函數配置 USART1 串口。使能 USART1 和 GPIOA 時鐘,將 PA9 配置為復用推挽輸出(用于 TX 發送),PA10 配置為浮空輸入(用于 RX 接收)。設置串口波特率為 115200,數據位 8 位,停止位 1 位,無校驗位,無硬件流控制,工作模式為同時接收和發送,并最終使能串口。

RTC 配置:RTC_Configuration()函數對 RTC 進行配置。使能 PWR 和 BKP 時鐘,允許訪問備份區域,對 BKP 進行初始化。開啟 LSI,選擇 LSI 作為 RTC 時鐘源,使能 RTC 時鐘并等待同步,設置 RTC 秒中斷,設置預分頻器為 40000,禁用 BKP 篡改引腳,配置 RTC 輸出為秒信號。

定時器配置:TIM_Configuration()函數對 TIM5 進行配置。使能 AFIO 和 TIM5 時鐘,重映射 TIM5 通道 4 到 LSI。設置 TIM5 的預分頻器為 0,計數模式為向上計數,周期為 0xFFFF,時鐘分頻為 1。配置 TIM5 通道 4 為輸入捕獲模式,上升沿觸發,直接映射到 TI,不分頻,無濾波。使能 TIM5,清除狀態寄存器,使能 TIM5 通道 4 捕獲中斷。

NVIC 配置:NVIC_Configuration()函數設置 NVIC 優先級分組為 1。使能 RTC 中斷,設置其搶占優先級為 0,子優先級為 0;使能 TIM5 中斷,設置子優先級為 2。

2.主循環部分:在main()函數中,先進行延時初始化,接著配置串口,輸出 “RTC LSI Calib Test.” 及系統時鐘頻率信息。然后進行 RTC、TIM5 配置和 NVIC 配置。等待OperationComplete變為 2,這意味著 TIM5 測量操作完成。當OperationComplete為 2 時,計算 LSI 的實際頻率,并根據該頻率設置 RTC 的預分頻器,最后進入無限循環while(1)。

int main(void)
{
    // 系統初始化
    delay_init();
    UART_Configuration(115200);
    printf("RTC LSI Calib Test.n");
    RCC_GetClocksFreq(&clocks);
    printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhzn",
           (float)clocks.SYSCLK_Frequency / 1000000, 
           (float)clocks.HCLK_Frequency / 1000000,
           (float)clocks.PCLK1_Frequency / 1000000, 
           (float)clocks.PCLK2_Frequency / 1000000, 
           (float)clocks.ADCCLK_Frequency / 1000000);
    
    // 外設初始化
    RTC_Configuration();
    TIM_Configuration();
    NVIC_Configuration();
    
    // 2. 等待TIM5測量完成(OperationComplete=2)
    while (OperationComplete != 2);
    
    // 計算LSI實際頻率并校準RTC
    if (PeriodValue != 0)
    {
        // LSI頻率 = (2*PCLK1)/PeriodValue
        LsiFreq = (uint32_t)((uint32_t)(clocks.PCLK1_Frequency * 2) / (uint32_t)PeriodValue);
    }
    printf("LsiFreq: %d Hzn", LsiFreq);
    
    // 根據測量結果校準RTC預分頻器
    RTC_SetPrescaler(LsiFreq - 1);
    RTC_WaitForLastTask();
    
    // 無限循環
    while (1);
}

3.輔助函數部分:IncrementVar_OperationComplete()函數使OperationComplete變量自增,并返回自增前的值。

// 3.a 遞增OperationComplete并返回舊值
uint32_t IncrementVar_OperationComplete(void)
{
    OperationComplete++;
    return (uint32_t)(OperationComplete - 1);
}

// 3.b 獲取OperationComplete值
uint32_t GetVar_OperationComplete(void)
{
    return (uint32_t)OperationComplete;
}

// 3.c 設置PeriodValue值
void SetVar_PeriodValue(uint32_t Value)
{
    PeriodValue = (uint32_t)(Value);
}

GetVar_OperationComplete()函數返回OperationComplete變量的值。

SetVar_PeriodValue()函數設置PeriodValue變量的值。

5 下載驗證

5.1 RTC_Calendar例程

wKgZPGg2gtyAdsnsAAHXEQVL4mw508.png

5.2 RTC_LSICalib例程

wKgZO2g2gtyAVIQ_AAJgDSTOzRQ146.png

WIZnet 是一家無晶圓廠半導體公司,成立于 1998 年。產品包括互聯網處理器 iMCU?,它采用 TOE(TCP/IP 卸載引擎)技術,基于獨特的專利全硬連線 TCP/IP。iMCU? 面向各種應用中的嵌入式互聯網設備。

WIZnet 在全球擁有 70 多家分銷商,在香港、韓國、美國設有辦事處,提供技術支持和產品營銷。

香港辦事處管理的區域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 實時時鐘
    +關注

    關注

    4

    文章

    314

    瀏覽量

    67070
  • RTC
    RTC
    +關注

    關注

    2

    文章

    622

    瀏覽量

    68887
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    STM32 RTC實時時鐘(一)

    STM32處理器內部集成了實時時鐘控制器(RTC),因此在實現實時時鐘功能時,無須外擴時鐘芯片即可構建實時時鐘系統。
    的頭像 發表于 07-22 15:41 ?5578次閱讀
    STM32 <b class='flag-5'>RTC</b><b class='flag-5'>實時時鐘</b>(一)

    《我和 LabVIEW》示例程序(2010.04.02)光盤第八至第十三章

    《我和 LabVIEW》示例程序(2010.04.02)光盤第八至第十三章
    發表于 06-27 17:12

    明德揚點撥FPGA課程---第十三章 ?計數器的使用

    第十三章計數器的使用1. 計數器使用原則2. 計數器練習13. 計數器練習1答案4. 計數器練習25. 計數器練習2答案6. 計數器練習37. 計數器練習3答案8. 計數器練習49. 計數器練習4
    發表于 10-30 10:15

    布爾值轉換(逐點)vi怎么用啊?還有8.2第十三章中火車輪的檢測中怎樣畫出的柱狀圖 ?

    布爾值轉換(逐點)vi怎么用???還有8.2第十三章中火車輪的檢測中怎樣畫出的柱狀圖 ?求大神解答第十三章火車輪實時監測的實例VI?。。。。。。。。。。?!
    發表于 11-14 14:22

    什么是實時時鐘RTC)?如何更改RTC的時間?

    什么是實時時鐘RTC)?實時時鐘RTC)的基本功能是什么?實時時鐘RTC)晶體誤差的主要來
    發表于 07-19 08:44

    RTC實時時鐘簡介

    RTC實時時鐘1. RTC實時時鐘簡介2. 硬件設計3. 軟件設計3.1 STM32CubeMX設置3.2 MDK-ARM編程4. 下載驗證
    發表于 08-18 06:55

    RTC是什么?RTC實時時鐘實驗

    文章目錄前言一、RTC是什么?二、RTC實時時鐘實驗1.引入庫2.讀入數據總結前言前面我們說了OLED實驗,是一個比較好的顯示測試代碼的方法?,F在我們學習關于RTC
    發表于 01-13 07:19

    RTC實時時鐘怎么使用?

    RTC實時時鐘怎么使用?cubemx中如何配置RTC?如何在keil中編寫程序?
    發表于 01-18 07:33

    淺談RTC實時時鐘特征與原理

    一、RTC實時時鐘特征與原理 查看STM32中文手冊 16 實時時鐘RTC)(308頁) RTC (Real Time Clock):
    的頭像 發表于 06-30 15:54 ?1.1w次閱讀

    STM32CubeMX | 40 - 實時時鐘RTC的使用(日歷和鬧鐘)

    STM32CubeMX | 40 - 實時時鐘RTC的使用(日歷和鬧鐘)
    發表于 11-23 18:06 ?19次下載
    STM32CubeMX | 40 - <b class='flag-5'>實時時鐘</b><b class='flag-5'>RTC</b>的使用(日歷和鬧鐘)

    STM32CubeMX系列|RTC實時時鐘

    RTC實時時鐘1. RTC實時時鐘簡介2. 硬件設計3. 軟件設計3.1 STM32CubeMX設置3.2 MDK-ARM編程4. 下載驗證
    發表于 12-24 19:15 ?16次下載
    STM32CubeMX系列|<b class='flag-5'>RTC</b><b class='flag-5'>實時時鐘</b>

    DA1468x SoC 的實時時鐘(RTC) 概念

    DA1468x SoC 的實時時鐘 (RTC) 概念
    發表于 03-15 20:16 ?0次下載
    DA1468x SoC 的<b class='flag-5'>實時時鐘</b>(<b class='flag-5'>RTC</b>) 概念

    實時時鐘RTC:32.768kHz晶振

    實時時鐘(RTC: Real-Time Clock)是集成電路,通常稱為時鐘芯片。目前實時時鐘芯片大多采用精度較高的晶體振蕩器作為時鐘源。
    的頭像 發表于 05-08 10:45 ?3305次閱讀
    <b class='flag-5'>實時時鐘</b><b class='flag-5'>RTC</b>:32.768kHz晶振

    DA1468x SoC 的實時時鐘(RTC) 概念

    DA1468x SoC 的實時時鐘 (RTC) 概念
    發表于 07-06 19:27 ?0次下載
    DA1468x SoC 的<b class='flag-5'>實時時鐘</b>(<b class='flag-5'>RTC</b>) 概念

    CW32實時時鐘RTC)介紹

    CW32實時時鐘RTC)介紹
    的頭像 發表于 10-24 15:36 ?1658次閱讀
    CW32<b class='flag-5'>實時時鐘</b>(<b class='flag-5'>RTC</b>)介紹
    主站蜘蛛池模板: 日本wwwxx| 天堂自拍 | 丁香婷婷在线 | 国产黄色网 | 狠狠色噜噜狠狠狠狠色综合久 | 国产无套视频在线观看香蕉 | 日韩中文字幕第一页 | 六月色 | 国产精品久久国产三级国不卡顿 | 明日花在线观看 | 国产吧在线 | 免费能直接在线观看黄的视频 | 色婷婷影院在线视频免费播放 | 在线免费观看一区二区三区 | 婷婷综合激六月情网 | 欧美一二区视频 | 国产午夜三区视频在线 | 久久激情网 | 能在线观看的一区二区三区 | 日本免费一级 | 欧美一级做一级做片性十三 | 免费观看的黄色网址 | 6080伦理久久亚洲精品 | 四虎永久在线日韩精品观看 | 2020年亚洲天天爽天天噜 | 狠狠的日视频 | 大色综合色综合资源站 | 久操视频在线免费观看 | 午夜剧场刺激性爽免费视频 | 亚洲人成网站在线 | 中文天堂资源在线www | 欧美一区二区三区精品 | 四虎永久在线精品2022 | 天天操天天谢 | 日本免费黄色片 | 黑人又大又粗又长又深受不了 | 日韩欧美一卡二区 | 久久久久久久综合色一本 | 免费人成黄页在线观看1024 | 久久99久久精品97久久综合 | 成人精品福利 |