一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32 RTC實(shí)時(shí)時(shí)鐘(一)

冬至子 ? 來(lái)源:紛紜雜談 ? 作者:CY_CHEN ? 2023-07-22 15:41 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

STM32處理器內(nèi)部集成了實(shí)時(shí)時(shí)鐘控制器(RTC),因此在實(shí)現(xiàn)實(shí)時(shí)時(shí)鐘功能時(shí),無(wú)須外擴(kuò)時(shí)鐘芯片即可構(gòu)建實(shí)時(shí)時(shí)鐘系統(tǒng)。

實(shí)時(shí)時(shí)鐘 (RTC) 是一個(gè)獨(dú)立的 BCD 定時(shí)器/計(jì)數(shù)器。RTC 提供一個(gè)日歷時(shí)鐘、兩個(gè)可編程鬧鐘中斷,以及一個(gè)具有中斷功能的周期性可編程喚醒標(biāo)志。RTC 還包含用于管理低功耗模式的自動(dòng)喚醒單元。

兩個(gè) 32 位寄存器包含二進(jìn)碼十進(jìn)數(shù)格式 (BCD) 的秒、分鐘、小時(shí)(12 或 24 小時(shí)制)、星期幾、日期、月份和年份。此外,還可提供二進(jìn)制格式的亞秒值。系統(tǒng)可以自動(dòng)將月份的天數(shù)補(bǔ)償為 28、29(閏年)、30 和 31天。并且還可以進(jìn)行夏令時(shí)補(bǔ)償。其它 32 位寄存器還包含可編程的鬧鐘亞秒、秒、分鐘、小時(shí)、星期幾和日期。

此外,還可以使用數(shù)字校準(zhǔn)功能對(duì)晶振精度的偏差進(jìn)行補(bǔ)償。

上電復(fù)位后,所有 RTC 寄存器都會(huì)受到保護(hù),以防止可能的非正常寫訪問(wèn)。無(wú)論器件狀態(tài)如何(運(yùn)行模式、低功耗模式或處于復(fù)位狀態(tài)),只要電源電壓保持在工作范圍內(nèi),RTC 便不會(huì)停止工作。

STM32F4XX的RTC模塊和時(shí)鐘配置可設(shè)置在備份區(qū)域,這樣系統(tǒng)復(fù)位或者從待機(jī)模式喚醒后RTC的設(shè)置和時(shí)間依然維持不變,只要備份域供電正常,RTC模塊就能持續(xù)地走時(shí)。為防止備份域被意外寫操作,備份區(qū)域也是被寫保護(hù)的。

備份區(qū)域包含20個(gè)備份寄存器,共80個(gè)字節(jié)??衫脗浞菁拇嫫?a href="http://www.www27dydycom.cn/analog/" target="_blank">模擬EEPROM,實(shí)現(xiàn)非易失功能,但是必須保證備份區(qū)域供電正常。通常,為保證系統(tǒng)掉電后RTC能夠正常走時(shí)且備份寄存器非易失,都會(huì)為RTC模塊配備一枚紐扣電池。

RTC框圖

圖片

時(shí)鐘和預(yù)分頻器

RTC 時(shí)鐘源 (RTCCLK) 通過(guò)時(shí)鐘控制器從 LSE 時(shí)鐘、LSI 振蕩器時(shí)鐘以及 HSE 時(shí)鐘三者中選擇。

可編程的預(yù)分頻器階段可生成 1 Hz 的時(shí)鐘,用于更新日歷。為最大程度地降低功耗,預(yù)分頻器分為 2 個(gè)可編程的預(yù)分頻器:

● 一個(gè)通過(guò) RTC_PRER 寄存器的 PREDIV_A 位配置的 7 位異步預(yù)分頻器。

● 一個(gè)通過(guò) RTC_PRER 寄存器的 PREDIV_S 位配置的 15 位同步預(yù)分頻器。

實(shí)時(shí)時(shí)鐘和日歷

RTC 日歷時(shí)間和日期寄存器可通過(guò)與 PCLK1(APB1 時(shí)鐘)同步的影子寄存器來(lái)訪問(wèn)。這些時(shí)間和日期寄存器也可以直接訪問(wèn),這樣可避免等待同步的持續(xù)時(shí)間。

● RTC_SSR 對(duì)應(yīng)于亞秒

● RTC_TR 對(duì)應(yīng)于時(shí)間

● RTC_DR 對(duì)應(yīng)于日期

每隔兩個(gè) RTCCLK 周期,便將當(dāng)前日歷值復(fù)制到影子寄存器,并將 RTC_ISR 寄存器的 RSF位置 1。在停機(jī)和待機(jī)模式下不會(huì)執(zhí)行復(fù)制操作。退出這兩種模式時(shí),影子寄存器會(huì)在最長(zhǎng) 2 個(gè) RTCCLK 周期后進(jìn)行更新。

當(dāng)應(yīng)用讀取日歷寄存器時(shí),它會(huì)訪問(wèn)影子寄存器的內(nèi)容。也可以通過(guò)將 RTC_CR 寄存器的

BYPSHAD 控制位置 1 來(lái)直接訪問(wèn)日歷寄存器。默認(rèn)情況下,該位被清零,用戶訪問(wèn)影子寄存器。

在 BYPSHAD=0 模式下讀取 RTC_SSR、RTC_TR 或 RTC_DR 寄存器時(shí),APB 時(shí)鐘頻率(f APB ) 必須至少為 RTC 時(shí)鐘頻率 (f RTCCLK ) 的 7 倍。

影子寄存器通過(guò)系統(tǒng)復(fù)位來(lái)復(fù)位。

RTC 寄存器寫保護(hù)

系統(tǒng)復(fù)位后,可通過(guò) PWR 電源控制寄存器 (PWR_CR) 的 DBP 位保護(hù) RTC 寄存器以防止非正常的寫訪問(wèn)。必須將 DBP 位置 1 才能使能 RTC 寄存器的寫訪問(wèn)。

上電復(fù)位后,所有 RTC 寄存器均受到寫保護(hù)。通過(guò)向?qū)懕Wo(hù)寄存器 (RTC_WPR) 寫入一個(gè)密鑰來(lái)使能對(duì) RTC 寄存器的寫操作。

要解鎖所有 RTC 寄存器(RTC_ISR[13:8]、RTC_TAFCR 和 RTC_BKPxR 除外)的寫保護(hù),需要執(zhí)行以下步驟:

  1. 將“0xCA”寫入 RTC_WPR 寄存器。
  2. 將“0x53”寫入 RTC_WPR 寄存器。

寫入一個(gè)錯(cuò)誤的關(guān)鍵字會(huì)再次激活寫保護(hù)。保護(hù)機(jī)制不受系統(tǒng)復(fù)位影響。

日歷初始化和配置

要編程包括時(shí)間格式和預(yù)分頻器配置在內(nèi)的初始時(shí)間和日期日歷值,需按照以下順序操作:

  1. 將 RTC_ISR 寄存器中的 INIT 位置 1 以進(jìn)入初始化模式。在此模式下,日歷計(jì)數(shù)器將停止工作并且其值可更新。
  2. 輪詢 RTC_ISR 寄存器中的 INITF 位。當(dāng) INITF 置 1 時(shí)進(jìn)入初始化階段模式。大約需要2 個(gè) RTCCLK 時(shí)鐘周期(由于時(shí)鐘同步)。
  3. 要為日歷計(jì)數(shù)器生成 1 Hz 時(shí)鐘,應(yīng)首先編程 RTC_PRER 寄存器中的同步預(yù)分頻系數(shù),然后編程異步預(yù)分頻系數(shù)。即使只需要更改這兩個(gè)字段中之一,也必須對(duì) RTC_PRER寄存器執(zhí)行兩次單獨(dú)的寫訪問(wèn)。
  4. 在影子寄存器(RTC_TR 和 RTC_DR)中加載初始時(shí)間和日期值,然后通過(guò) RTC_CR寄存器中的 FMT 位配置時(shí)間格式(12 或 24 小時(shí)制)。
  5. 通過(guò)清零 INIT 位退出初始化模式。隨后,自動(dòng)加載實(shí)際日歷計(jì)數(shù)器值,在 4 個(gè) RTCCLK時(shí)鐘周期后重新開始計(jì)數(shù)。

當(dāng)初始化序列完成之后,日歷開始計(jì)數(shù)。

注意:系統(tǒng)復(fù)位后,應(yīng)用可讀取 RTC_ISR 寄存器中的 INITS 標(biāo)志,以檢查日歷是否已初始化。如果該標(biāo)志為 0 ,表明日歷尚未初始化,因?yàn)槟攴葑侄卧O(shè)置為其上電復(fù)位時(shí)的默認(rèn)值 (0x00) 。

要在初始化之后讀取日歷,必須首先用軟件檢查 RTC_ISR 寄存器的 RSF 標(biāo)志是否置 1 。

接著查看寄存器描述:

RTC 時(shí)間寄存器 (RTC_TR)

RTC_TR 是日歷時(shí)間影子寄存器。只能在初始化模式下對(duì)該寄存器執(zhí)行寫操作。

圖片

位 22 PM:AM/PM 符號(hào) (AM/PM notation)

0:AM 或 24 小時(shí)制

1:PM

位 21:20 HT[1:0]: 小時(shí)的十位(BCD 格式)(Hour tens in BCD format)

位 16:16 HU[3:0]: 小時(shí)的個(gè)位(BCD 格式)(Hour units in BCD format)

位 14:12 MNT[2:0]: 分鐘的十位(BCD 格式)(Minute tens in BCD format)

位 11:8 MNU[3:0]: 分鐘的個(gè)位(BCD 格式)(Minute units in BCD format)

位 6:4 ST[2:0]: 秒的十位(BCD 格式)(Second tens in BCD format)

位 3:0 SU[3:0]: 秒的個(gè)位(BCD 格式)(Second units in BCD format)

RTC 日期寄存器 (RTC_DR)

RTC_DR 是日歷日期影子寄存器。只能在初始化模式下對(duì)該寄存器執(zhí)行寫操作。

圖片

位 23:20 YT[3:0]: 年份的十位(BCD 格式)(Year tens in BCD format)

位 19:16 YU[3:0]: 年份的個(gè)位(BCD 格式)(Year units in BCD format)

位 15:13 WDU[2:0]: 星期幾的個(gè)位 (Week day units)

000:禁止

001:星期一

...

111:星期日

位 12 MT: 月份的十位(BCD 格式)(Month tens in BCD format)

位 11:8 MU: 月份的個(gè)位(BCD 格式)(Month units in BCD format)

位 5:4 DT[1:0]: 日期的十位(BCD 格式)(Date tens in BCD format)

位 3:0 DU[3:0]: 日期的個(gè)位(BCD 格式)(Date units in BCD format)

RTC 控制寄存器 (RTC_CR)

圖片

位 23 COE:校準(zhǔn)輸出使能 (Calibration output enable)

該位使能 RTC_CALIB 輸出

0:禁止校準(zhǔn)輸出

1:使能校準(zhǔn)輸出

位 22:21 OSEL[1:0]:輸出選擇 (Output selection)

這些位用于選擇要連接到 RTC_ALARM 輸出的標(biāo)志

00:禁止輸出

01:使能鬧鐘 A 輸出

10:使能鬧鐘 B 輸出

11:使能喚醒輸出

位 20 POL:輸出極性 (Output polarity)

該位用于配置 RTC_ALARM 輸出的極性

0:當(dāng) ALRAF/ALRBF/WUTF 置 1 時(shí)(取決于 OSEL[1:0]),該引腳為高電平

1:當(dāng) ALRAF/ALRBF/WUTF 置 1 時(shí)(取決于 OSEL[1:0]),該引腳為低電平

位 19 COSEL:校準(zhǔn)輸出選擇 (Calibration output selection)

當(dāng) COE=1 時(shí),該位可選擇 RTC_CALIB 上輸出的信號(hào)。

0:校準(zhǔn)輸出為 512 Hz

1:校準(zhǔn)輸出為 1 Hz

在 RTCCLK 為 32.768 kHz 且預(yù)分頻器為其默認(rèn)值(PREDIV_A=127 且 PREDIV_S=255)的條件下,這些頻率有效。

位 18 BKP:備份 (Backup)

用戶可對(duì)此位執(zhí)行寫操作以記錄是否已對(duì)夏令時(shí)進(jìn)行更改。

位 17 SUB1H:減少 1 小時(shí)(冬季時(shí)間更改)(Subtract 1 hour (winter time change))

當(dāng)該位在初始化模式以外的模式下置 1 時(shí),如果當(dāng)前小時(shí)不是 0,則日歷時(shí)間將減少 1 小時(shí)。此位始終讀為 0。當(dāng)前小時(shí)為 0 時(shí),將此位置 1 沒(méi)有任何作用。

0:無(wú)作用。

1:將當(dāng)前時(shí)間減少 1 小時(shí)。這可用于冬季時(shí)間更改。

位 16 ADD1H:增加 1 小時(shí)(夏季時(shí)間更改)(Add 1 hour (summer time change))

當(dāng)該位在初始化模式以外的模式下置 1 時(shí),日歷時(shí)間將增加 1 小時(shí)。此位始終讀為 0。

0:無(wú)作用。

1:將當(dāng)前時(shí)間增加 1 小時(shí)。這可用于夏季時(shí)間更改

位 15 TSIE:時(shí)間戳中斷使能 (Timestamp interrupt enable)

0:禁止時(shí)間戳中斷

1:使能時(shí)間戳中斷

位 14 WUTIE:使能喚醒定時(shí)器使能 (Wakeup timer interrupt enable)

0:禁止喚醒定時(shí)器中斷

1:使能喚醒定時(shí)器中斷

位 13 ALRBIE: ** 鬧鐘 B 中斷使能 (Alarm B interrupt enable)**

0:鬧鐘 B 中斷禁止

1:鬧鐘 B 中斷使能

位 12 ALRAIE:鬧鐘 A 中斷使能 (Alarm A interrupt enable)

0:禁止鬧鐘 A 中斷

1:使能鬧鐘 A 中斷

位 11 TSE:時(shí)間戳使能 (Time stamp enable)

0:禁止時(shí)間戳

1:使能時(shí)間戳

位 10 WUTE:喚醒定時(shí)器使能 (Wakeup timer enable)

0:禁止喚醒定時(shí)器

1:使能喚醒定時(shí)器

位 9 ALRBE: ** 鬧鐘 B 使能 (Alarm B enable)**

0:禁止鬧鐘 B

1:使能鬧鐘 B

位 8 ALRAE :鬧鐘 A 使能 (Alarm A enable)

0:禁止鬧鐘 A

1:使能鬧鐘 A

位 7 DCE :粗略數(shù)字校準(zhǔn)使能 (Coarse digital calibration enable)

0:禁止數(shù)字校準(zhǔn)

1:使能數(shù)字校準(zhǔn)

PREDIV_A 必須大于或等于 6

位 6 FMT:小時(shí)格式 (Hour format)

0:24 小時(shí)/天格式

1:AM/PM 小時(shí)格式

位 5 BYPSHAD:旁路影子寄存器 (Bypass the shadow registers)

0:日歷值(從 RTC_SSR、RTC_TR 和 RTC_DR 讀取時(shí))取自影子寄存器,該影子寄存器每?jī)蓚€(gè) RTCCLK 周期更新一次。

1:日歷值(從 RTC_SSR、RTC_TR 和 RTC_DR 讀取時(shí))直接取自日歷計(jì)數(shù)器。

注意:如果 APB1 時(shí)鐘的頻率低于 7 倍的 RTCCLK 頻率,則必須將 BYPSHAD 置“ 1 ”。

位 4 REFCKON: **參考時(shí)鐘檢測(cè)使能(50 Hz 或 60 Hz)(Reference clock detection enable (50 or **60 Hz))

0:禁止參考時(shí)鐘檢測(cè)

1:使能參考時(shí)鐘檢測(cè)

注意:PREDIV_S 必須為 0x00FF 。

位 3 TSEDGE:時(shí)間戳事件有效邊沿 (Timestamp event active edge)

0:TIMESTAMP 上升沿生成時(shí)間戳事件

1:TIMESTAMP 下降沿生成時(shí)間戳事件

TSEDGE 發(fā)生更改時(shí),必須復(fù)位 TSE 以避免將 TSF 意外置 1

位 2:0 WUCKSEL[2:0]:喚醒時(shí)鐘選擇 (Wakeup clock selection)

000:選擇 RTC/16 時(shí)鐘

001:選擇 RTC/8 時(shí)鐘

010:選擇 RTC/4 時(shí)鐘

011:選擇 RTC/2 時(shí)鐘

10x:選擇 ck_spre 時(shí)鐘(通常為 1 Hz)

11x:選擇 ck_spre 時(shí)鐘(通常為 1 Hz)并將 WUT 計(jì)數(shù)器值增加 216

RTC 初始化和狀態(tài)寄存器 (RTC_ISR)

圖片

位 16 RECALPF:重新校準(zhǔn)掛起標(biāo)志 (Recalibration pending Flag)

當(dāng)軟件對(duì) RTC_CALR 寄存器執(zhí)行寫操作時(shí),RECALPF 狀態(tài)標(biāo)志將自動(dòng)置“1”,指示RTC_CALR 寄存器已屏蔽。當(dāng)采用新的校準(zhǔn)設(shè)置時(shí),該位恢復(fù)為“0”。

位 14 TAMP2F:TAMPER2 檢測(cè)標(biāo)志 (TAMPER2 detection flag)

在入侵輸入 2 上檢測(cè)到入侵檢測(cè)事件時(shí),由硬件將此標(biāo)志置 1。

該標(biāo)志由軟件寫零清除。

位 13 TAMP1F:入侵檢測(cè)標(biāo)志 (Tamper detection flag)

當(dāng)檢測(cè)到入侵檢測(cè)事件時(shí),由硬件將此標(biāo)志置 1。

該標(biāo)志由軟件寫零清除。

位 12 TSOVF:時(shí)間戳溢出標(biāo)志 (Timestamp overflow flag)

當(dāng)在 TSF 已置 1 的情況下發(fā)生時(shí)間戳事件時(shí),由硬件將此標(biāo)志置 1。

該標(biāo)志由軟件寫零清除。建議僅在 TSF 位清零之后再檢查并清TSOVF 位。否則,如果時(shí)間戳事件恰好在清零 TSF 位之前剛剛發(fā)生,則溢出事件可能會(huì)被漏掉。

位 11 TSF:時(shí)間戳標(biāo)志 (Timestamp flag)

發(fā)生時(shí)間戳事件時(shí),由硬件將此標(biāo)志置 1。

該標(biāo)志由軟件寫零清除。

位 10 WUTF:喚醒定時(shí)器標(biāo)志 (Wakeup timer flag)

當(dāng)喚醒自動(dòng)重載計(jì)數(shù)器計(jì)數(shù)到 0 時(shí),由硬件將此標(biāo)志置 1。

該標(biāo)志由軟件寫零清除。

軟件必須在 WUTF 再次置 1 的 1.5 個(gè) RTCCLK 周期之前將該標(biāo)志清零。

位 9 ALRBF:鬧鐘 B 標(biāo)志 (Alarm B flag)

當(dāng)時(shí)間/日期寄存器(RTC_TR 和 RTC_DR)與鬧鐘 B 寄存器 (RTC_ALRMBR) 匹配時(shí),由硬件將該標(biāo)志置 1。該標(biāo)志由軟件寫零清除。

位 8 ALRAF:鬧鐘 A 標(biāo)志 (Alarm A flag)

當(dāng)時(shí)間/日期寄存器(RTC_TR 和 RTC_DR)與鬧鐘 A 寄存器 (RTC_ALRMAR) 匹配時(shí),由

硬件將該標(biāo)志置 1。

該標(biāo)志由軟件寫零清除。

位 7 INIT:初始化模式 (Initialization mode)

0:自由運(yùn)行模式。

1:初始化模式,用于編程時(shí)間和日期寄存器(RTC_TR 和 RTC_DR)以及預(yù)分頻器寄存器(RTC_PRER)。計(jì)數(shù)器停止計(jì)數(shù),當(dāng) INIT 被復(fù)位后,計(jì)數(shù)器從新值開始計(jì)數(shù)。

位 6 INITF:初始化標(biāo)志 (Initialization flag)

當(dāng)此位置 1 時(shí),RTC 處于初始化狀態(tài),此時(shí)可更新事件、日期和預(yù)分頻器寄存器。

0:不允許更新日歷寄存器。

1:允許更新日歷寄存器。

位 5 RSF:寄存器同步標(biāo)志 (Registers synchronization flag)

每次將日歷寄存器的值復(fù)制到影子寄存器(RTC_SSRx、RTC_TRx 和 RTC_DRx)時(shí),都會(huì)由硬件將此位置 1。在初始化模式下、平移操作掛起時(shí) (SHPF=1) 或在旁路影子寄存器模式 (BYPSHAD=1) 下,該位由硬件清零。該位還可由軟件清零。

0:日歷影子寄存器尚未同步

1:日歷影子寄存器已同步

位 4 INITS:初始化狀態(tài)標(biāo)志 (Initialization status flag)

當(dāng)日歷年份字段不為 0 時(shí)(上電復(fù)位狀態(tài)),由硬件將該位置 1。

0:日歷尚未初始化

1:日歷已經(jīng)初始化

位 3 SHPF:平移操作掛起 (Shift operation pending)

0:沒(méi)有平移操作掛起

1:某個(gè)平移操作掛起

只要通過(guò)對(duì) RTC_SHIFTR 寄存器執(zhí)行寫操作來(lái)啟動(dòng)平移操作,此標(biāo)志便由硬件置 1。執(zhí)行完相應(yīng)的平移操作后,此標(biāo)志由硬件清零。對(duì) SHPF 執(zhí)行寫入操作不起作用。

位 2 WUTWF:喚醒定時(shí)器寫標(biāo)志 (Wakeup timer write flag)

在 RTC_CR 寄存器中的 WUTE 位置 0 后,當(dāng)喚醒定時(shí)器值可更改時(shí),由硬件將該位置 1。

0:不允許更新喚醒定時(shí)器配置

1:允許更新喚醒定時(shí)器配置

位 1 ALRBWF:鬧鐘 B 寫標(biāo)志 (Alarm B write flag)

在 RTC_CR 寄存器中的 ALRBIE 位置 0 之后,當(dāng)鬧鐘 B 的值可更改時(shí),由硬件將該位置 1。該位在初始化模式下由硬件清零。

0:不允許更新鬧鐘 B

1:允許更新鬧鐘 B

位 0 ALRAWF:鬧鐘 A 寫標(biāo)志 (Alarm A write flag)

在 RTC_CR 寄存器中的 ALRAE 位置 0 后,當(dāng)鬧鐘 A 的值可更改時(shí),由硬件將該位置 1。

該位在初始化模式下由硬件清零。

0:不允許更新鬧鐘 A

1:允許更新鬧鐘 A

RTC 預(yù)分頻器寄存器 (RTC_PRER)

預(yù)分頻器寄存器復(fù)位值剛好使時(shí)鐘頻率為1Hz,滿足RTC的需求,所以這里不對(duì)其進(jìn)行配置。

RTC初始化程序如下:

#include "RTC.h"
#include "stm32f4xx.h"
void RTC_Init(u8 hour,u8 fen,u8 miao,u8 nian,u8 yue,u8 ri,u8 xingqi)
{
  u32 temp = 0;
  RCC- >APB1ENR  |=  1< 28;  //開電源管理模塊時(shí)鐘
  PWR- >CR  |=  1< 8;          //解除保護(hù)
  RCC- >BDCR  &=~  (1< 2);      //調(diào)試模式下不旁路LSE
  RCC- >BDCR  |=  1< 0;        //開啟LSE振蕩器
  while(!(RCC- >BDCR & 1< 1));
  RCC- >BDCR  &=~  (0x3< 8);
  RCC- >BDCR  |=  1< 8;        //選擇LSE為RTC時(shí)鐘源
  RCC- >BDCR  |=  1< 15;      //使能RTC模塊
  RTC- >WPR  =  0xCA;          //解除寫保護(hù)
  RTC- >WPR  =  0x53;          //解除寫保護(hù)
  RTC- >ISR  |=  1< 7;        //INIT位置1
  while((RTC- >ISR  &  (1< 6))==0);      //等待進(jìn)入初始化模式
  temp |= (hour/10)< 20  |  (hour%10)< 16  |  (fen/10)< 12  |  (fen%10)< 8  |  (miao/10)< 4  |  (miao%10);
  RTC- >TR  =  temp;
  temp  =  0;
  temp |= (nian/10)< 20  |  (nian%10)< 16  |  (xingqi)< 13  |  (yue/10)< 12  |  (yue%10)< 8  |  (ri/10)< 4  |  (ri%10);
  RTC- >DR  =  temp;
  RTC- >CR  =  0;
  RTC- >ISR  &=~(1< 7);      //退出初始化模式
  RTC- >WPR = 0;              //寫任意值,再次保護(hù)
}

編寫主函數(shù)測(cè)試:

#include "stm32f4xx.h"
#include "usart.h"
#include "delay.h"
#include "stdio.h"
#include "RTC.h"


typedef struct
{
  u8 shi;
  u8 fen;
  u8 miao;
  u8 nian;
  u8 yue;
  u8 ri;
  u8 xingqi;
}TIME_Typedef;
TIME_Typedef time = {1};


int main()
{
  Usart1_Init(115200);
  RTC_Init(23,59,50,19,7,9,2);

  while(1)
  {
    time.shi    =    ((RTC- >TR  &  0x300000) >>20)*10  +  ((RTC- >TR  &  0xf0000) >>16);
    time.fen    =    ((RTC- >TR  &  0x7000) >>12)*10  +  ((RTC- >TR  &  0xf00) >>8);
    time.miao    =    ((RTC- >TR  &  0x70) >>4)*10  +  (RTC- >TR  &  0xf);


    printf("%d:%d:%drn",time.shi,time.fen,time.miao);

    Delay_ms(1000);
  }
}

運(yùn)行后可以看到串口輸出了設(shè)置的時(shí)分秒計(jì)數(shù),時(shí)間不會(huì)出錯(cuò),RTC實(shí)時(shí)時(shí)鐘測(cè)試成功。

圖片

但是在系統(tǒng)復(fù)位后,發(fā)現(xiàn)又重新從剛開始設(shè)的時(shí)間計(jì)時(shí),這顯然不是我們想要的,所以在這里再添加備份域的讀寫函數(shù)。

RTC 備份寄存器 (RTC_BKPxR)

圖片

RTC的備份域是在RTC基地址上偏移了0x50開始到偏移0x9c的范圍。

//備份域
//注意:備份域寄存器也受DBP位保護(hù),在未初始化RTC模塊的條件下,如果要使用備份域,
//需單獨(dú)開啟DBP位
//num:0~19
void RTC_WriteBKPxR(u8 num,u32 dat)
{
  u32 add = 0;

  num %= 20;
  add = RTC_BASE + 0x50 + 4*num;
  *((volatile u32 *)add) = dat;
}


u32 RTC_ReadBKPxR(u8 num)
{
  u32 add = 0;

  num %= 20;
  add = RTC_BASE + 0x50 + 4*num;
  add = *((volatile u32 *)add);

  return add;
}

然后再在初始化函數(shù)中調(diào)用讀取備份域函數(shù),判斷是否已經(jīng)設(shè)置過(guò)時(shí)間,如果第一次設(shè)時(shí)間就寫備份域的標(biāo)記,再設(shè)置時(shí)間;不是第一次就直接開啟計(jì)時(shí)。初始化函數(shù)更改如下:

void RTC_Init(u8 hour,u8 fen,u8 miao,u8 nian,u8 yue,u8 ri,u8 xingqi)
{
  u32 temp = 0;
  RCC- >APB1ENR  |=  1< 28;  //開電源管理模塊時(shí)鐘
  PWR- >CR  |=  1< 8;          //解除保護(hù)
  RCC- >BDCR  &=~  (1< 2);      //調(diào)試模式下不旁路LSE
  RCC- >BDCR  |=  1< 0;        //開啟LSE振蕩器
  while(!(RCC- >BDCR & 1< 1));
  RCC- >BDCR  &=~  (0x3< 8);
  RCC- >BDCR  |=  1< 8;        //選擇LSE為RTC時(shí)鐘源
  RCC- >BDCR  |=  1< 15;      //使能RTC模塊
  RTC- >WPR  =  0xCA;          //解除寫保護(hù)
  RTC- >WPR  =  0x53;          //解除寫保護(hù)
  RTC- >ISR  |=  1< 7;        //INIT位置1
  while((RTC- >ISR  &  (1< 6))==0);      //等待進(jìn)入初始化模式
  temp = RTC_ReadBKPxR(0);
  if(temp != 0xaa)
  {
    RTC_WriteBKPxR(0,0xaa);
    temp  =  0;
    temp |= (hour/10)< 20  |  (hour%10)< 16  |  (fen/10)< 12  |  (fen%10)< 8  |  (miao/10)< 4  |  (miao%10);
    RTC- >TR  =  temp;
    temp  =  0;
    temp |= (nian/10)< 20  |  (nian%10)< 16  |  (xingqi)< 13  |  (yue/10)< 12  |  (yue%10)< 8  |  (ri/10)< 4  |  (ri%10);
    RTC- >DR  =  temp;
  }
  RTC- >CR  =  0;
  RTC- >ISR  &=~(1< 7);      //退出初始化模式
  RTC- >WPR = 0;              //寫任意值,再次保護(hù)
}

主函數(shù)依舊不變,運(yùn)行程序發(fā)現(xiàn)系統(tǒng)復(fù)位后,時(shí)間是繼續(xù)復(fù)位之前的計(jì)時(shí),不會(huì)再被重新設(shè)置,所以在用RTC時(shí)加上備份域就可以防止系統(tǒng)復(fù)位造成計(jì)時(shí)不理想。

圖片

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 控制器
    +關(guān)注

    關(guān)注

    114

    文章

    17066

    瀏覽量

    183719
  • EEPROM
    +關(guān)注

    關(guān)注

    9

    文章

    1085

    瀏覽量

    83584
  • RTC
    RTC
    +關(guān)注

    關(guān)注

    2

    文章

    619

    瀏覽量

    68630
  • STM32F4
    +關(guān)注

    關(guān)注

    3

    文章

    201

    瀏覽量

    28958
  • STM32處理器
    +關(guān)注

    關(guān)注

    0

    文章

    5

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    RTC實(shí)時(shí)時(shí)鐘簡(jiǎn)介

    RTC實(shí)時(shí)時(shí)鐘1. RTC實(shí)時(shí)時(shí)鐘簡(jiǎn)介2. 硬件設(shè)計(jì)3. 軟件設(shè)計(jì)3.1 STM32CubeMX設(shè)置3.2 MDK-ARM編程4. 下載驗(yàn)證
    發(fā)表于 08-18 06:55

    如何去實(shí)現(xiàn)STM32實(shí)時(shí)時(shí)鐘RTC的時(shí)間計(jì)算部分

    STM32實(shí)時(shí)時(shí)鐘RTC是什么?STM32實(shí)時(shí)時(shí)鐘RTC是由哪些部分組成的?如何去實(shí)現(xiàn)
    發(fā)表于 11-22 06:33

    如何去使用STM32實(shí)時(shí)時(shí)鐘RTC

    實(shí)時(shí)時(shí)鐘RTC是什么?如何去使用STM32實(shí)時(shí)時(shí)鐘RTC呢?有哪些注意事項(xiàng)?
    發(fā)表于 11-22 08:05

    RTC是什么?RTC實(shí)時(shí)時(shí)鐘實(shí)驗(yàn)

    是什么?STM32F4 的實(shí)時(shí)時(shí)鐘RTC)相對(duì)于 STM32F1 來(lái)說(shuō),改進(jìn)了不少,帶了日歷功能了,STM32F4 的
    發(fā)表于 01-13 07:19

    STM32F2技術(shù)培訓(xùn)_實(shí)時(shí)時(shí)鐘_RTC

    STM32F2 技術(shù)培訓(xùn)_實(shí)時(shí)時(shí)鐘_RTC
    發(fā)表于 12-03 17:35 ?0次下載

    STM32F0xx_ RTC實(shí)時(shí)時(shí)鐘配置詳細(xì)過(guò)程

    STM32F0xx_RTC實(shí)時(shí)時(shí)鐘配置詳細(xì)過(guò)程
    的頭像 發(fā)表于 04-07 11:50 ?8766次閱讀
    <b class='flag-5'>STM32</b>F0xx_ <b class='flag-5'>RTC</b><b class='flag-5'>實(shí)時(shí)時(shí)鐘</b>配置詳細(xì)過(guò)程

    淺談RTC實(shí)時(shí)時(shí)鐘特征與原理

    、RTC實(shí)時(shí)時(shí)鐘特征與原理 查看STM32中文手冊(cè) 16 實(shí)時(shí)時(shí)鐘RTC)(308頁(yè))
    的頭像 發(fā)表于 06-30 15:54 ?1.1w次閱讀

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

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

    stm32f4 RTC實(shí)時(shí)時(shí)鐘解析

    應(yīng)用最為廣泛的消費(fèi)類電子產(chǎn)品之。它為人們提供精確的實(shí)時(shí)時(shí)間,或者為電子系統(tǒng)提供精確的時(shí)間基準(zhǔn),目前實(shí)時(shí)時(shí)鐘芯片大多采用精度較高的晶體振蕩器作為時(shí)鐘源。對(duì)于
    發(fā)表于 12-04 18:06 ?19次下載
    <b class='flag-5'>stm32</b>f4 <b class='flag-5'>RTC</b><b class='flag-5'>實(shí)時(shí)時(shí)鐘</b>解析

    STM32CubeMX系列|RTC實(shí)時(shí)時(shí)鐘

    RTC實(shí)時(shí)時(shí)鐘1. RTC實(shí)時(shí)時(shí)鐘簡(jiǎn)介2. 硬件設(shè)計(jì)3. 軟件設(shè)計(jì)3.1 STM32CubeMX設(shè)置3.2 MDK-ARM編程4. 下載驗(yàn)證
    發(fā)表于 12-24 19:15 ?16次下載
    <b class='flag-5'>STM32</b>CubeMX系列|<b class='flag-5'>RTC</b><b class='flag-5'>實(shí)時(shí)時(shí)鐘</b>

    STM32CubeMX-實(shí)時(shí)時(shí)鐘(RTC)

    實(shí)時(shí)時(shí)鐘 (RTC) 是個(gè)獨(dú)立的 BCD 定時(shí)器/計(jì)數(shù)器。RTC 提供具有可編程鬧鐘中斷功能的日歷時(shí)鐘 /日歷。
    的頭像 發(fā)表于 01-14 17:24 ?2848次閱讀

    基于STM32單片機(jī)RTC實(shí)時(shí)時(shí)鐘使用庫(kù)文件設(shè)計(jì)

    基于STM32單片機(jī)RTC實(shí)時(shí)時(shí)鐘使用庫(kù)文件設(shè)計(jì)源代碼
    發(fā)表于 04-26 14:28 ?5次下載

    STM32學(xué)習(xí)筆記之RTC實(shí)時(shí)時(shí)鐘2

    STM32實(shí)時(shí)時(shí)鐘RTC)是個(gè)獨(dú)立的定時(shí)器。 STM32RTC 模塊擁有
    的頭像 發(fā)表于 05-26 14:26 ?1474次閱讀
    <b class='flag-5'>STM32</b>學(xué)習(xí)筆記之<b class='flag-5'>RTC</b><b class='flag-5'>實(shí)時(shí)時(shí)鐘</b>2

    STM32 RTC實(shí)時(shí)時(shí)鐘(二)

    上次實(shí)驗(yàn)完成了對(duì)實(shí)時(shí)時(shí)鐘的基本功能——計(jì)時(shí)的實(shí)驗(yàn),這次在計(jì)時(shí)的基礎(chǔ)上對(duì)RTC的可編程鬧鐘的功能進(jìn)行測(cè)試。
    的頭像 發(fā)表于 07-22 15:43 ?2344次閱讀
    <b class='flag-5'>STM32</b> <b class='flag-5'>RTC</b><b class='flag-5'>實(shí)時(shí)時(shí)鐘</b>(二)

    CW32實(shí)時(shí)時(shí)鐘RTC)介紹

    CW32實(shí)時(shí)時(shí)鐘RTC)介紹
    的頭像 發(fā)表于 10-24 15:36 ?1618次閱讀
    CW32<b class='flag-5'>實(shí)時(shí)時(shí)鐘</b>(<b class='flag-5'>RTC</b>)介紹