1024手机基地看电影,午夜福利视频导航,国产精品福利在线一区,亚洲欧美日韩另类成人,在线观看午夜日本理论片,成年超爽免费网站,国产精品成人免费,精品动作一级毛片,成人免费观看网站,97精品伊人久久大香蕉

標題: STM32 RTc模塊 [打印本頁]

作者: GKoSon    時間: 2018-8-9 17:45
標題: STM32 RTc模塊
芯片內集成了計數器+存儲器  外面接電源+晶振即可代碼表現為一個init+一個算法


#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區域
        PWR_BackupAccessCmd(ENABLE);
        //復位BKP
        BKP_DeInit();
        //使能外部低速晶振 32.768K
        RCC_LSEConfig(RCC_LSE_ON);
        //等待外部低速晶振就緒
        while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);
        //選擇RTC外部時鐘為低速晶振 32.768K
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
        //使能RTC時鐘
        RCC_RTCCLKCmd(ENABLE);
        //等待RTC寄存器同步
        RTC_WaitForSynchro();
        //等待寫RTC寄存器完成
        RTC_WaitForLastTask();
        //使能RTC秒中斷
        RTC_ITConfig(RTC_IT_SEC,ENABLE);         
       
        Set_alarm(2);
        //設置預分頻
        RTC_SetPrescaler(32767);
        //等待寫RTC寄存器完成
        RTC_WaitForLastTask();
}

void Clock_Init(void)
{
        if(BKP_ReadBackupRegister(BKP_DR1)!=0xA5A5)
        {
                 //第一次運行  初始化設置
                //RTC初始化
                RTC_Configuration();
                //等待寫RTC寄存器完成
            RTC_WaitForLastTask();
                //設置時間初值
                RTC_SetCounter(0xA442);
                //等待寫RTC寄存器完成
            RTC_WaitForLastTask();
                //寫配置標志
                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();//清除復位標志;
}

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};
/*
    函數功能:判斷是否閏年
    函數參數:需要判斷的年份
    返回值:    返回1成功 其他失敗
*/
static uint8_t isLeapYear(uint16_t mYear)   
{
    if (((mYear%4 == 0)&&((mYear%100) != 0))||(mYear%400) == 0)
    {
        return 1;
    }else
    {
        return 0;
    }
}
/********************************************************************************/
/*
    函數功能:日期轉換為秒并配置RTC
    函數參數:年、月、日、時、分、秒
    返回值:    返回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);


    /*執行以下操作可以使能對備份寄存器和 RTC 的訪問:
    1)通過設置寄存器 RCC_APB1ENR 的 PWREN 和 BKPEN 位來打開電源和后備接口的時鐘
    2)電源控制寄存器(PWR_CR)的 DBP 位來使能對后備寄存器和 RTC 的訪問
    */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP, ENABLE);
    PWR_BackupAccessCmd(ENABLE);
    RTC_SetCounter(secCount);
    RTC_WaitForLastTask();
    return 0;
}
/********************************************************************************/
/*
    函數功能:從RTC獲取秒轉換為年、月、日、星期、時、分、秒
                        存入 struct thisDate 中
    函數參數: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;  //計算出天數
    thisDate->week = (4+Count)%7;
    if (Count !=0)                  //大于一天
    {
        tmp = 1970;                     //從1970年開始
        while(Count>=365)
        {
            if (isLeapYear(tmp))//是閏年
            {
                if (Count>= 366)    //天數大于366
                {
                    Count -= 366;
                }else
                {
                    tmp++;                  //天數小于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;  //當年是閏年 二月 某時
                }
            }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







歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1