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

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

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

STM32 RTC實時時鐘(二)

冬至子 ? 來源:紛紜雜談 ? 作者:CY_CHEN ? 2023-07-22 15:43 ? 次閱讀

上次實驗完成了對實時時鐘的基本功能——計時的實驗,這次在計時的基礎上對RTC的可編程鬧鐘的功能進行測試。

RTC 單元提供兩個可編程鬧鐘,即鬧鐘 A 和鬧鐘 B。

可通過將 RTC_CR 寄存器中的 ALRAE 和 ALRBE 位置 1 來使能可編程鬧鐘功能。如果日歷亞秒、秒、分鐘、小時、日期或日分別與鬧鐘寄存器RTC_ALRMASSR/RTC_ALRMAR 和RTC_ALRMBSSR/RTC_ALRMBR 中編程的值相匹配,則 ALRAF 和 ALRBF 標志會被置為1??赏ㄟ^ RTC_ALRMAR 和 RTC_ALRMBR 寄存器的 MSKx 位以及 RTC_ALRMASSR 和RTC_ALRMBSSR 寄存器的 MASKSSx 位單獨選擇各日歷字段??赏ㄟ^ RTC_CR 寄存器中的 ALRAIE 和 ALRBIE 位使能鬧鐘中斷。

鬧鐘 A 和鬧鐘 B(如果已通過 RTC_CR 寄存器中的位 OSEL[0:1] 使能)可連接到 RTC_ALARM輸出??赏ㄟ^ RTC_CR 寄存器的 POL 位配置 RTC_ALARM 極性。

要對可編程的鬧鐘(鬧鐘 A 或鬧鐘 B)進行編程或更新,必須執(zhí)行類似的步驟:

  1. 將 RTC_CR 寄存器中的 ALRAE 或 ALRBE 位清零以禁止鬧鐘 A 或鬧鐘 B。
  2. 輪詢 RTC_ISR 寄存器中的 ALRAWF 或 ALRBWF 位,直到其中一個置 1,以確保鬧鐘寄存器可以訪問。大約需要 2 個 RTCCLK 時鐘周期(由于時鐘同步)。
  3. 編程鬧鐘 A 或鬧鐘 B 寄存器(RTC_ALRMASSR/RTC_ALRMAR 或 RTC_ALRMBSSR/RTC_ALRMBR)。
  4. 將 RTC_CR 寄存器中的 ALRAE 或 ALRBE 位置 1 以再次使能鬧鐘 A 或鬧鐘 B。

注意:約 2 個 RTCCLK 時鐘周期(由于時鐘同步)后,將執(zhí)行對 RTC_CR 寄存器的更改。

寫程序前先簡單了解下鬧鐘相關的寄存器:

RTC鬧鐘A寄存器 (RTC_ALRMAR)

圖片

位 31 MSK4:鬧鐘 A 日期掩碼 (Alarm A date mask)

0:如果日期/日匹配,則鬧鐘 A 置 1

1:在鬧鐘 A 比較中,日期/日無關

位 30 WDSEL:星期幾選擇 (Week day selection)

0:DU[3:0] 代表日期的個位

1:DU[3:0] 代表星期幾。DT[1:0] 為無關位。

位 29:28 DT[1:0]:日期的十位(BCD 格式)

位 27:24 DU[3:0]:日期的個位或日(BCD 格式)

位 23 MSK3:鬧鐘 A 小時掩碼 (Alarm A hours mask)

0:如果小時匹配,則鬧鐘 A 置 1?

1:在鬧鐘 A 比較中,小時無關

位 22 PM :AM/PM 符號 (AM/PM notation)

0:AM 或 24 小時制

1:PM

位 21:20 HT[1:0]:小時的十位(BCD 格式)

位 19:16 HU[3:0]:小時的個位(BCD 格式)

位 15 MSK2:鬧鐘 A 分鐘掩碼 (Alarm A minutes mask)

0:如果分鐘匹配,則鬧鐘 A 置 1

1:在鬧鐘 A 比較中,分鐘無關

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

位 11:8 MNU[3:0]:分鐘的個位(BCD 格式)

位 7 MSK1:鬧鐘 A 秒掩碼 (Alarm A seconds mask)

0:如果秒匹配,則鬧鐘 A 置 1

1:在鬧鐘 A 比較中,秒無關

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

位 3:0 SU[3:0]:秒的個位(BCD 格式)

鬧鐘B寄存器RTC_ALRMBR與鬧鐘A寄存器RTC_ALRMAR的寄存器功能一樣,這里不再進行介紹。

RTC鬧鐘配置函數(shù)和中斷處理函數(shù)

void RTC_AlarmConfig(u8 Alarm_sel,u8 Alarm_set,u8 Alarm_day,u8 Alarm_hour,u8 Alarm_minute)
{
  u32 prigroup = 0;
  u32 priority = 0;
  u32 temp = 0;

  //1.解除保護
  //寫密鑰:先寫0xca,再寫0x53
  RTC- >WPR  =  0XCA;
  RTC- >WPR  = 0X53;

  switch(Alarm_set)
  {
    case SPECIAL_DAY:
      temp |= Alarm_day< 24;  //設置具體星期
      break;

    case WORK_DAY:
    case ALL_DAY:
      temp |= (u32)(1< 31);
      break;

    case DISABLE_DAY:
      break;
  }

  temp |= 1< 30;                //用星期來匹配
  temp |= ((Alarm_hour/10)< 4  |  (Alarm_hour%10))< 16 | 1< 23;
  temp |= ((Alarm_minute/10)< 4  |  (Alarm_minute%10))< 8 | 1< 15;
  temp |= 1< 7;

  //關閉鬧鐘,等待鬧鐘可寫入
  if(Alarm_sel == ALARM_A)
  {
    RTC- >CR  &= ~(1< 8);
    while((RTC- >ISR & (1< 0)) == 0){}
    RTC- >ALRMAR = temp;
    RTC- >CR |= 1< 8;      //開啟鬧鐘A
    //開鬧鐘A的中斷
    RTC- >CR |= 1< 12;
    //清中斷標記
    RTC- >ISR &= ~(1< 8);  
  }
  else if(Alarm_sel == ALARM_B)
  {
    RTC- >CR  &= ~(1< 9);
    while((RTC- >ISR & (1< 1)) == 0){}
    RTC- >ALRMBR = temp;
    RTC- >CR |= 1< 9;    //開啟鬧鐘B
    //開鬧鐘B的中斷
    RTC- >CR |= 1< 13;      
    //清中斷標記
    RTC- >ISR &= ~(1< 9);
  }

  //鬧鐘中斷對應于外部中斷線,因此要設置外部中斷線(17)
  EXTI- >IMR  |= 1< 17;
  EXTI- >RTSR  |= 1< 17;      //鬧鐘中斷需設置為上升沿
  //清中斷標記
  EXTI- >PR  |= 1< 17;

  prigroup = NVIC_GetPriorityGrouping();
  priority = NVIC_EncodePriority(prigroup,1,2);
  NVIC_SetPriority(RTC_Alarm_IRQn,priority);
  NVIC_EnableIRQ(RTC_Alarm_IRQn);

  switch(Alarm_set)
  {
    case SPECIAL_DAY:
      break;

    case WORK_DAY:
      temp = (RTC- >DR  &  0x0000e000) >>13;
      if(temp  >5)
      {
        if(Alarm_sel == ALARM_A)
          RTC- >CR  &= ~(1< 8);
        else if(Alarm_sel == ALARM_B)
          RTC- >CR  &= ~(1< 9);
      }
      else
      {
        if(Alarm_sel == ALARM_A)
          RTC- >CR  |= 1< 8;
        else if(Alarm_sel == ALARM_B)
          RTC- >CR  |= 1< 9;
      }
      break;

    case ALL_DAY:
      break;

    case DISABLE_DAY:
      if(Alarm_sel == ALARM_A)
          RTC- >CR  &= ~(1< 8);
      else if(Alarm_sel == ALARM_B)
          RTC- >CR  &= ~(1< 9);
      break;
  }

  //2. 再次保護
  RTC- >WPR  = 0XFF;          //寫任意值,再次保護
}


//中斷處理
void RTC_Alarm_IRQHandler()
{
  EXTI- >PR  |= 1< 17;
  //中斷處理
  if(RTC- >ISR & (1< 8))
  {
    RTC- >ISR  &= ~(1< 8);
    //鬧鐘A中斷處理
    LED_Toggle(DS1);
  }
  else if(RTC- >ISR & (1< 9))
  {
    RTC- >ISR  &= ~(1< 9);
    //鬧鐘B中斷處理
  }
}

由于鬧鐘的編寫比較簡單,這里就不多加描述了,接下來編寫主函數(shù)進行測試。

#include "stm32f4xx.h"
#include "usart.h"
#include "delay.h"
#include "stdio.h"
#include "RTC.h"
#include "led.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()
{
  LED_Init();
  Usart1_Init(115200);
  RTC_Init(23,59,50,19,7,9,2);
  RTC_AlarmConfig(ALARM_A,SPECIAL_DAY,3,0,0);

  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);
  }
}

初始時間設為23:59:50,鬧鐘時間設為0:0:0。運行程序,經(jīng)過10秒鐘后,鬧鐘進入中斷,LED燈實現(xiàn)翻轉(zhuǎn),RTC鬧鐘實驗測試成功。

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

    關注

    31

    文章

    5358

    瀏覽量

    120775
  • 計時器
    +關注

    關注

    1

    文章

    426

    瀏覽量

    32771
  • 中斷處理
    +關注

    關注

    0

    文章

    94

    瀏覽量

    10988
  • BCD編碼
    +關注

    關注

    0

    文章

    9

    瀏覽量

    6037
  • RTC
    RTC
    +關注

    關注

    2

    文章

    542

    瀏覽量

    66772
收藏 人收藏

    評論

    相關推薦

    STM32 RTC實時時鐘(一)

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

    RTC實時時鐘簡介

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

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

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

    如何去使用STM32實時時鐘RTC

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

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

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

    STM32F2技術培訓_實時時鐘_RTC

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

    ALIENTEK_MINISTM32_實驗11_RTC實時時鐘實驗

    ALIENTEK MINISTM32 實驗11 RTC實時時鐘實驗,很好的資料,快來下載吧
    發(fā)表于 02-19 11:35 ?17次下載

    STM32F0xx_ RTC實時時鐘配置詳細過程

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

    STM32 RTC實時時鐘資料下載

    電子發(fā)燒友網(wǎng)為你提供STM32 RTC實時時鐘資料下載的電子資料下載,更有其他相關的電路圖、源代碼、課件教程、中文資料、英文資料、參考設計、用戶指南、解決方案等資料,希望可以幫助到廣大的電子工程師們。
    發(fā)表于 04-16 08:48 ?33次下載
    <b class='flag-5'>STM32</b> <b class='flag-5'>RTC</b><b class='flag-5'>實時時鐘</b>資料下載

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

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

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

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

    stm32f4 RTC實時時鐘解析

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

    STM32CubeMX系列|RTC實時時鐘

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

    基于STM32單片機RTC實時時鐘使用庫文件設計

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

    CW32實時時鐘RTC)介紹

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