新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 簡(jiǎn)單初始化STM32的RTC

        簡(jiǎn)單初始化STM32的RTC

        作者: 時(shí)間:2016-12-03 來源:網(wǎng)絡(luò) 收藏
        RTC嘛 就跟DS1302 差不多吧...當(dāng)然了可分頻又有32位的計(jì)數(shù)器...報(bào)警、秒、溢出中斷.....等等。RTC在APB1總線上....

        本文引用地址:http://www.104case.com/article/201612/325222.htm

        要使用 RTC,一般來說也順帶地使用上后備寄存器—這是因?yàn)镽TC 是一個(gè)簡(jiǎn)單的秒中斷
        定時(shí)器,年月日時(shí)分秒的信息必須要找個(gè)地方能掉電保存才有意義.STM32 的備份寄存器(BKP)是42個(gè)16位的寄存器,可用來存儲(chǔ)84個(gè)字節(jié)的用戶應(yīng)用程序數(shù)據(jù)。他們處在備份域里,當(dāng)VDD電源被切斷,他們?nèi)匀挥蒝BAT維持供電。當(dāng)系統(tǒng)在待機(jī)模式下被喚醒,或系統(tǒng)復(fù)位或電源復(fù)位時(shí),他們也不會(huì)被復(fù)位。 此外,BKP控制寄存器用來管理侵入檢測(cè)和RTC校準(zhǔn)功能。 復(fù)位后,對(duì)備份寄存器和RTC的訪問被禁止,并且備份域被保護(hù)以防止可能存在的意外的寫操作它是用后備電池供電的,只要配置好后,即使系統(tǒng)關(guān)電,32768 的
        晶振和后備寄存器的數(shù)據(jù)也會(huì)得以維持.而且RTC的計(jì)數(shù)器是會(huì)繼續(xù)秒遞增的.那么要配
        置RTC,就必須開放以下東西:
        #include "stm32f10x_bkp.h" 這個(gè)是后備寄存器
        #include "stm32f10x_pwr.h" 電源管理
        #include "stm32f10x_rtc.h" RTC庫

        開始吧.....先是中斷

        void NVIC_Configuration(void)
        {
        NVIC_InitTypeDef NVIC_InitStructure;

        /* Configure one bit for preemption priority */
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

        /*RTC*/
        NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;//RTC全局中斷
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        }

        然后設(shè)置 RTC

        #include "STM32Lib\stm32f10x.h"
        #include "hal.h"


        static u8 RTC_Blank=0;
        /***********************************
        **函數(shù)名:RTC_Configuration
        **功能:RTC設(shè)置
        **注意事項(xiàng):要根據(jù)是否是第一次設(shè)置,才進(jìn)入下面的RTC設(shè)定
        判斷是否第一次設(shè)置,只需要判斷RTC后備寄存器1的值是否為事先寫入的0XA5A5,如果不是,則
        RTC是第一次上電,需要初始化RTC,并把實(shí)際時(shí)間轉(zhuǎn)化為RTC計(jì)數(shù)值,這里沒有設(shè)置實(shí)際時(shí)間,只是簡(jiǎn)單地初始化了RTC
        ************************************/
        void RTC_Configuration(void)
        {

        /*PWR時(shí)鐘(電源控制)與BKP時(shí)鐘(RTC后備寄存器)使能*/
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

        /*使能RTC和后備寄存器訪問*/
        PWR_BackupAccessCmd(ENABLE);

        /*從指定的后備寄存器(BKP_DR1)中讀出數(shù)據(jù)*/
        if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
        {
        /* 將外設(shè)BKP的全部寄存器重設(shè)為缺省值 */
        BKP_DeInit();

        /*啟用 LSE(外部低速晶振)*/
        RCC_LSEConfig(RCC_LSE_ON);
        /*等待外部晶振震蕩 需要等待比較長(zhǎng)的時(shí)間*/
        while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

        /*使用外部晶振32.768K作為RTC時(shí)鐘*/
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
        //允許RTC
        RCC_RTCCLKCmd(ENABLE);
        //等待RTC寄存器同步 原因下文說明
        RTC_WaitForSynchro();
        //等待最近一次對(duì)RTC寄存器的寫操作完成
        RTC_WaitForLastTask();

        //允許RTC的秒中斷(還有鬧鐘中斷和溢出中斷可設(shè)置)
        RTC_ITConfig(RTC_IT_SEC, ENABLE);
        //又是等待上一次對(duì)RTC寄存器的寫操作完成
        RTC_WaitForLastTask();
        //32768晶振預(yù)分頻值是32767,不過一般來說晶振都不那么準(zhǔn)
        RTC_SetPrescaler(32776);//如果需要校準(zhǔn)晶振,可修改此分頻值
        RTC_WaitForLastTask();

        //寫入RTC后備寄存器1 0xa5a5
        BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
        RTC_Blank=1;/*這個(gè)標(biāo)志代表RTC是沒有預(yù)設(shè)的(或者說是沒有上紐扣電池) 用串口呀啥的輸出來。*/

        }
        //如果RTC已經(jīng)設(shè)置
        else
        {
        //等待RTC與APB同步
        RTC_WaitForSynchro();
        RTC_WaitForLastTask();

        //使能秒中斷
        RTC_ITConfig(RTC_IT_SEC, ENABLE);//這句可以放到前面嗎?
        RTC_WaitForLastTask();//又等....
        }

        //清除標(biāo)志
        RCC_ClearFlag();
        }

        為啥要不停的等呢??

        RTC核完全獨(dú)立于RTC APB1接口。 軟件通過APB1接口訪問RTC的預(yù)分頻值、計(jì)數(shù)器值和鬧鐘值。但是,相關(guān)的可讀寄存器只在與RTC APB1時(shí)鐘進(jìn)行重新同步的RTC時(shí)鐘的上升沿被更新。RTC標(biāo)志也是如此的。 這意味著,如果APB1接口曾經(jīng)被關(guān)閉,而讀操作又是在剛剛重新開啟APB1之后,則在第一次的內(nèi)部寄存器更新之前,從APB1上讀出的RTC寄存器數(shù)值可能被破壞了(通常讀到0)。

        因此,若在讀取RTC寄存器時(shí),RTC的APB1接口曾經(jīng)處于禁止?fàn)顟B(tài),則軟件首先必須等待RTC_CRL寄存器中的RSF位(寄存器同步標(biāo)志)被硬件置’1’。

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

        /*******************************************************************************
        * Function Name : RTC_IRQHandler RTC中斷
        * Description :
        * Input : None
        * Output : None
        * Return : None
        *******************************************************************************/
        extern volatile bool Sec;//1S標(biāo)志
        void RTC_IRQHandler(void)
        {
        if(RTC_GetITStatus(RTC_IT_SEC) != RESET)//RTC發(fā)生了秒中斷(也有可能是溢出或者鬧鐘中斷)

        /*RTC_IT_OW溢出中斷/RTC_IT_ALR鬧鐘中斷/RTC_IT_SEC秒中斷*/
        {
        RTC_ClearITPendingBit(RTC_IT_SEC);
        Sec=TRUE;

        //以免RTC計(jì)數(shù)溢出,這里限制了RTC計(jì)數(shù)值的大小.0x0001517f實(shí)際就是一天的秒數(shù)
        if(RTC_GetCounter() >= 0x0001517f)
        {
        RTC_SetCounter(0x0);

        RTC_WaitForLastTask();
        }
        }
        }

        #include"STM32Lib\stm32f10x.h"
        #include"hal.h"

        volatilebool Sec=FALSE;

        int main(void)
        {
        ChipHalInit();//片內(nèi)硬件初始化
        ChipOutHalInit();//片外硬件初始化

        TestRtc();//測(cè)試RTC
        for(;;)
        {
        if(Sec==TRUE)
        {
        Sec=FALSE;
        GPIOA->ODR^=GPIO_Pin_8;//閃燈
        }
        }
        }

        最簡(jiǎn)單 最基層的CRT寫好了..........其實(shí)還有好多很酷的功能 比如是否掉電重啟 是否是SeSET 復(fù)位 等 應(yīng)該在CRT前 都檢測(cè)好........



        關(guān)鍵詞: 初始化STM32RT

        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 锡林郭勒盟| 滕州市| 台中市| 鄱阳县| 盘山县| 襄樊市| 靖远县| 丽江市| 广东省| 年辖:市辖区| 中方县| 汶川县| 永靖县| 新竹市| 绥芬河市| 桦南县| 利辛县| 松江区| 长治县| 临西县| 昌黎县| 河北省| 柏乡县| 措勤县| 永修县| 额尔古纳市| 满城县| 囊谦县| 邵武市| 平武县| 嘉定区| 钟祥市| 麦盖提县| 潢川县| 毕节市| 台东县| 永康市| 萨迦县| 丰台区| 诏安县| 泰宁县|