久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1164|回復(fù): 0
收起左側(cè)

STM32 RTc模塊

[復(fù)制鏈接]
ID:384719 發(fā)表于 2018-8-9 17:45 | 顯示全部樓層 |閱讀模式
芯片內(nèi)集成了計(jì)數(shù)器+存儲(chǔ)器  外面接電源+晶振即可代碼表現(xiàn)為一個(gè)init+一個(gè)算法


#include "rtc.h"

void STEP1_RCC(void)
{
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
}

void STEP2_NVIC(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

        NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}



void Set_alarm(uint32_t AlarmValue)
{
        if(RTC_GetITStatus(RTC_IT_ALR) != RESET)                                 //alarm interrupt
        {
                RTC_ClearITPendingBit(RTC_IT_ALR);
        }

        RTC_ITConfig(RTC_IT_ALR, ENABLE);
        RTC_WaitForLastTask();
        RTC_SetAlarm(AlarmValue);
}

void Disable_alarm(void)
{
  RTC_ITConfig(RTC_IT_ALR , DISABLE);
  RTC_WaitForLastTask();
}

void RTC_Configuration(void)
{
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);

        //允許訪問BKP區(qū)域
        PWR_BackupAccessCmd(ENABLE);
        //復(fù)位BKP
        BKP_DeInit();
        //使能外部低速晶振 32.768K
        RCC_LSEConfig(RCC_LSE_ON);
        //等待外部低速晶振就緒
        while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);
        //選擇RTC外部時(shí)鐘為低速晶振 32.768K
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
        //使能RTC時(shí)鐘
        RCC_RTCCLKCmd(ENABLE);
        //等待RTC寄存器同步
        RTC_WaitForSynchro();
        //等待寫RTC寄存器完成
        RTC_WaitForLastTask();
        //使能RTC秒中斷
        RTC_ITConfig(RTC_IT_SEC,ENABLE);         
       
        Set_alarm(2);
        //設(shè)置預(yù)分頻
        RTC_SetPrescaler(32767);
        //等待寫RTC寄存器完成
        RTC_WaitForLastTask();
}

void Clock_Init(void)
{
        if(BKP_ReadBackupRegister(BKP_DR1)!=0xA5A5)
        {
                 //第一次運(yùn)行  初始化設(shè)置
                //RTC初始化
                RTC_Configuration();
                //等待寫RTC寄存器完成
            RTC_WaitForLastTask();
                //設(shè)置時(shí)間初值
                RTC_SetCounter(0xA442);
                //等待寫RTC寄存器完成
            RTC_WaitForLastTask();
                //寫配置標(biāo)志
                BKP_WriteBackupRegister(BKP_DR1,0xA5A5);
        }
        else
        {
                //等待RTC寄存器同步
                RTC_WaitForSynchro();
                //等待寫RTC寄存器完成
                RTC_WaitForLastTask();
                //使能RTC秒中斷
          RTC_ITConfig(RTC_IT_SEC,ENABLE);
    //等待寫RTC寄存器完成
                RTC_WaitForLastTask();
          Set_alarm(2);
        }

        RCC_ClearFlag();//清除復(fù)位標(biāo)志;
}

void RTC_Init(void)
{
        STEP1_RCC();
        STEP2_NVIC();
        Clock_Init();
}






/***********************判斷是否為閏年********/
const uint8_t monthTable[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
/*
    函數(shù)功能:判斷是否閏年
    函數(shù)參數(shù):需要判斷的年份
    返回值:    返回1成功 其他失敗
*/
static uint8_t isLeapYear(uint16_t mYear)   
{
    if (((mYear%4 == 0)&&((mYear%100) != 0))||(mYear%400) == 0)
    {
        return 1;
    }else
    {
        return 0;
    }
}
/********************************************************************************/
/*
    函數(shù)功能:日期轉(zhuǎn)換為秒并配置RTC
    函數(shù)參數(shù):年、月、日、時(shí)、分、秒
    返回值:    返回0成功 其他失敗
*/
uint8_t RTC_SetSec(_TM* DATA)
{
    uint32_t secCount = 0;
    uint16_t i;
          uint16_t year=DATA->year;
          uint8_t month=DATA->mon;
          uint8_t day=DATA->day;
          uint8_t hour=DATA->hour;
          uint8_t minute=DATA->min;
          uint8_t sec=DATA->sec;

    if (year <1970 || year >2099)
    {
        return 1;
    }
    for (i=1970; i<year; i++)
    {
        if (isLeapYear(i))
        {
            secCount += 31622400UL;
        }
        else
        {
            secCount += 31536000UL;
        }
    }

    for (i=0; i<month-1; i++)
    {
        secCount += ((uint32_t)monthTable[i]*86400UL);
        if (isLeapYear(year) && i==1)   //潤年 多加一天
        {
            secCount += 86400UL;
        }
    }
    secCount += (uint32_t)(day-1) * 86400UL;   
    secCount += (uint32_t)(hour)*3600;
    secCount += (uint32_t)(minute)*60;
    secCount += (uint32_t)(sec);


    /*執(zhí)行以下操作可以使能對(duì)備份寄存器和 RTC 的訪問:
    1)通過設(shè)置寄存器 RCC_APB1ENR 的 PWREN 和 BKPEN 位來打開電源和后備接口的時(shí)鐘
    2)電源控制寄存器(PWR_CR)的 DBP 位來使能對(duì)后備寄存器和 RTC 的訪問
    */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP, ENABLE);
    PWR_BackupAccessCmd(ENABLE);
    RTC_SetCounter(secCount);
    RTC_WaitForLastTask();
    return 0;
}
/********************************************************************************/
/*
    函數(shù)功能:從RTC獲取秒轉(zhuǎn)換為年、月、日、星期、時(shí)、分、秒
                        存入 struct thisDate 中
    函數(shù)參數(shù):struct thisDate
    返回值:    返回0成功 其他失敗
*/
uint8_t RTC_GetDate(_TM* thisDate)
{
    uint32_t timeCount = 0;
    uint32_t Count ;
    uint16_t tmp = 0;
    timeCount = RTC_GetCounter();
    Count = timeCount/86400UL;  //計(jì)算出天數(shù)
    thisDate->week = (4+Count)%7;
    if (Count !=0)                  //大于一天
    {
        tmp = 1970;                     //從1970年開始
        while(Count>=365)
        {
            if (isLeapYear(tmp))//是閏年
            {
                if (Count>= 366)    //天數(shù)大于366
                {
                    Count -= 366;
                }else
                {
                    tmp++;                  //天數(shù)小于366 最后一年
                    break;
                }
            }else
            {
                Count -= 365;       //平年
            }
                tmp++;
        }
        thisDate->year = tmp;   //獲取到了年
        tmp = 0;
        while(Count>= 28)
        {
            if (isLeapYear(thisDate->year) && tmp == 1)
            {
                if (Count >= 29)
                {
                    Count -= 29;
                }
                else   
                {
                    break;  //當(dāng)年是閏年 二月 某時(shí)
                }
            }else
            {
                if (Count >= monthTable[tmp])
                {
                    Count -= monthTable[tmp];
                }else
                {
                    break;
                }
            }
                tmp ++;
        }
        thisDate->mon = tmp+1;    //獲取到月
        thisDate->day = Count+1;    //獲取到日
    }
    Count = timeCount%86400UL;
    thisDate->hour = Count/3600;
    thisDate->min= (Count%3600)/60;
    thisDate->sec = (Count%3600)%60;
    return 0;
}


_RTC Rtc = {RTC_Init,RTC_GetDate,RTC_SetSec};
_TM  Today={12,27,13,1,8,8,2018};





#ifndef __RTC_H
#define __RTC_H

#include "time.h"//等待研究
#include "stm32f10x_bkp.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_rtc.h"
#include "stm32f10x_pwr.h"
#include "misc.h"

typedef struct
{
  u8 sec;
        u8 min;
        u8 hour;
        u8 week;
        u8 day;
        u8 mon;
        u16 year;
}_TM;


typedef struct
{
        void (*init)(void);
        u8 (*GetTime)(_TM *);
        u8 (*SetTime)(_TM *);
}_RTC;

extern _RTC Rtc;
extern _TM  Today;
#endif


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 91在线最新| 国产一区二区三区在线视频 | 亚洲网站在线观看 | 国产成人网 | 亚洲福利一区二区 | 精品一区二区三区av | 久久久激情视频 | 国产成人在线视频播放 | 国产一区不卡 | 日日干夜夜操天天操 | 国产日韩欧美一区二区 | 久久精品成人热国产成 | 国产第一亚洲 | 成人av一区 | 色啪网 | 成人不卡一区二区 | 国产成人午夜高潮毛片 | 亚洲性人人天天夜夜摸 | 四虎影视1304t| 免费在线观看成人 | 一本一道久久a久久精品综合蜜臀 | 日本视频免费 | 欧美jizzhd精品欧美巨大免费 | 欧美成人自拍视频 | 欧美99 | 全免费a级毛片免费看视频免 | 精品免费国产一区二区三区四区 | 无人区国产成人久久三区 | av小说在线 | 欧美黑人一级爽快片淫片高清 | 粉嫩粉嫩芽的虎白女18在线视频 | 特黄小视频 | 午夜精品影院 | 久草在线青青草 | 一区二区免费视频 | 日韩视频在线一区二区 | 黄免费在线 | 一区二区免费 | 欧美中文字幕在线观看 | 久久久久久久久毛片 | 久久毛片 |