STM32之RTC配置与初始化-rtc.h rtc.c

<rtc.h>
#include "stm32f10x.h"
#ifndef _RTC_H
#define _RTC_H
typedef struct
{
    vu8 hour;
    vu8 mintue;
    vu8 second;
    vu16 year;
    vu8 month;
    vu8 day;
    vu8 week;
}_calendar_obj;
// extern _calendar_obj Calendar;
u8 RTC_Init(void);
u8 Is_Leap_Year(u16 _year);
_calendar_obj RTC_GetCalendar(void);
u8 RTC_GetWeek(u16 _year,u8 _month,u8 _day);
u8 RTC_SetCalendar(u16 _year,u8 _month,u8 _day,u8 _hour,u8 _min,u8 _second);
#endif

<rtc.c>
#include "rtc.h"

const u8 month_table[]={31,28,31,30,31,30,31,31,30,31,30,31};
const u8 week_table[]={0,3,3,6,1,4,6,2,5,0,3,5};

_calendar_obj Calendar;

void delay_ms(u16 time)
{
    u16 i=0;
    while(time--)
    {
        i=12000;
        while(i--);
    }
}

u8 Is_Leap_Year(u16 _year)
{
    if((_year%4 && _year%100!=0) | (_year%400==0)) return 0;
    else return 1;
}

u8 RTC_Init(void)
{
    u16 temp=0;
    //enable RTC_CLK outside
    if(BKP_ReadBackupRegister(BKP_DR1)!=0x5050)
    {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);
        PWR_BackupAccessCmd(ENABLE);
        BKP_DeInit();
        RCC_LSEConfig(RCC_LSE_ON);
        while(RCC_GetFlagStatus(RCC_FLAG_HSERDY)==RESET)
        {
            temp++;
            delay_ms(10);
        }
        if(temp>250) return 0;
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
        RCC_RTCCLKCmd(ENABLE);
        RTC_WaitForLastTask();
        RTC_ITConfig(RTC_IT_SEC,ENABLE);
        RTC_WaitForLastTask();
        RTC_SetPrescaler(32767);
        RTC_WaitForLastTask();
        RTC_SetCalendar(2015,10,10,10,10,10);
        RTC_ExitConfigMode();
        BKP_WriteBackupRegister(BKP_DR1,0x5050);
    }
    else
    {
        RTC_WaitForSynchro();
        RTC_ITConfig(RTC_IT_SEC,ENABLE);
        RTC_WaitForLastTask();
    }
    return 1;
}

_calendar_obj RTC_GetCalendar(void)
{
    static u16 daycount=0;
    u32 timecount=RTC_GetCounter();
    u32 daynum=timecount/86400;  //day
    u16 temp=0;

    //Calendar year
    if(daycount!=daynum)  //>1
    {
        daycount=daynum;
        temp=1970;
        while(daynum>365)
        {
            if(Is_Leap_Year(temp))
            {
                if(daynum>=366)
                    daynum=daynum-366;
                else
                    break;
            }
            else
                daynum=daynum-365;
            temp++;
        }
        Calendar.year=temp;  // set year
        temp=0;  //reset temp

        // Calendar month
        while(daynum>=28)
        {
            if(Is_Leap_Year(Calendar.year) && temp==1)
            {
                if(daynum>=29) daynum=daynum-29;
                else break;
            }
            else
            {
                if(daynum>=month_table[temp])
                    daynum=daynum-month_table[temp];
                else
                    break;
            }
            temp++;
        }
        Calendar.month=temp+1;  //set month
        Calendar.day=daynum+1;  //set day
    }

    daynum=timecount%86400;
    Calendar.hour=daynum/3600;  //set hour
    Calendar.mintue=(daynum%3600)/60;  //set mintue
    Calendar.second=(daynum%3600)%60;  //set second

    return Calendar;
}

u8 RTC_SetCalendar(u16 _year,u8 _month,u8 _day,u8 _hour,u8 _min,u8 _second)
{
    u16 i;
    u32 seccount=0;  //second total
    if(_year<1970 || _year>2099) return 1;  //valid year

    //calculate year
    for(i=1970;i<_year;i++)
    {
        if(Is_Leap_Year(i))
            seccount=seccount+3600*24*366; //3600*24*366=31622400
        else
            seccount=seccount+3600*24*365; //3600*24*365=31536000
    }
    //calculate month
    _month=_month-1;
    for(i=0;i<_month;i++)
    {
        seccount=seccount+(u32)month_table[i]*3600*24;
        if(Is_Leap_Year(_year) && i==1)  //February,add 1 day
        {
            seccount=seccount+3600*24;
        }
    }

    //calculate day
    seccount=seccount+(u32)(_day-1)*3600*24;
    seccount+=(u32)_hour*3600;
    seccount+=(u32)_min*60;
    seccount+=_second;

    //set Calendar
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);
    PWR_BackupAccessCmd(ENABLE);
    RTC_SetCounter(seccount);
    RTC_WaitForLastTask();

    return 0;
}

u8 RTC_GetWeek(u16 _year,u8 _month,u8 _day)
{
    u16 temp;
    u8 yearH,yearL;
    yearH=_year/100;  //   2016/100=20
    yearL=_year%100;  //   2016%100=16

    if(yearH>19) yearL+=100;
    temp=yearL+yearL/4;
    temp=temp+_day+week_table[_month-1];
    if(yearL%4==0 && _month<3)
        temp=temp-1;

    return temp%7;
}
时间: 2024-10-05 05:41:40

STM32之RTC配置与初始化-rtc.h rtc.c的相关文章

STM32串口通信配置(USART1+USART2+USART3+UART4)

一.串口一的配置(初始化+中断配置+中断接收函数) 1 /*=============================================================================== 2 Copyright: 3 Version: 4 Author: 5 Date: 2017/11/3 6 Description: 7 配置独立看门狗初始化函数,在主函数中运行IWDG_ReloadCounter进行喂狗主函数必须在4s内进行一次喂狗不然系统会复位: 8 函数功

【转】第二课.配置和初始化

原文网址:http://fsjoy.blog.51cto.com/318484/244803 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://fsjoy.blog.51cto.com/318484/244803 第二课.配置和初始化 配置git 在使用git之前你需要配置一下git.git在你创建提交的时候会记录你的名字和email地址,所以你应该告诉git这些内容.可以使用'git config'命令来设置,如果传递参数'-

STM32的ADC配置

本文出至:http://bibber.blog.sohu.com/162815791.html ADC是多少位的? 12位 ADC有多少个? 1个.2个或多至3个,视不同的器件而不同:每个又有多个通道. 关于通道的名堂: 10.3.3  通道选择 有16个多路通道.可以把转换分成两组:规则的和注入的.在任意多个通道上以任意顺序进行的一系列转换构成成组转换.例如,可以如下顺序完成转换:通道3.通道8.通道2.通道2.通道0.通道2.通道2.通道15. ●  规则组由多达16个转换组成.规则通道和它

STM32的IO配置点灯

1.led.c的具体的代码: /*----------------------------------------------------------*/ #include "led.h" /* ------------------------------------------------------------------------- 文件名:led.c 描述 :根据硬件连接配置LED端口,打开对应的寄存器 ------------------------------------

STM32 输入捕获配置

在STM32 的定时器,除了 TIM6 和 TIM7,就是通过检测 TIMx_CHx 上的 边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候, 将当时定时器 的值(TIMx_CNT) 存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面, 完成一次捕获.同时还可以配置捕获时是否触发中断/DMA 等. 1)开启 TIM5 时钟和 GPIOA 时钟, 配置 PA0 为下拉输入. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

基于意法半导体MCU STM32的底层配置

意法半导体MCU是全球领先的半导体供应商,自成立以来已满足了市场上多元化的需求,提供了各行业领域范围半导体产品及解决方案.为了保持其技术优势,意法半导体坚定地致力于创新,约有7400人从事研发和产品设计工作,并在2018年将其收入的15%用于研发.STM32MCU被广泛应用在各种丰富的不同行业当中.为此本篇文章将介绍有关STM32底层配置的相关技术. 本文通过,介绍STM32主要的底层配置,通过关键步骤的程序源代码的介绍,阐述实现数据传输的细节以及注意事项.该方法对其他项目或芯片有一定的实现价值

springmvc中配置servlet初始化类

<bean  id="InitStart" lazy-init="false" init-method="InitSystem" class="my.spring.uitl.InitStart"></bean> 配置在springmvc的配置文件中 只要项目启动,就会默认执行这个类的这个方法 相比静态类代码块的好处, 有点在tomcat启动时就会调用如果有错立即报错,静态代码块,调用时才会报错 作用 可

Mysql源码安装、配置、初始化及启动

[在此处输入文章标题] 主机环境redhat6.5 实验环境服务端 ip 172.25.29.1  mysql 安装包  mysql-boost-5.7.11.tar.gz   cmake-2.8.12.2-4.el6.x86_64.rpm 1.mysql的源码安装 1.解压压缩包 [[email protected] mnt]# tar zxfmysql-boost-5.7.11.tar.gz  #解压gz包 [[email protected] mnt]# yum installcmake-

DRBD简介 安装、编译报错解决 DRBD的配置、初始化及同步

主机环境 redhat6.5 64位 实验环境 服务端1 ip 172.25.25.111 主机名:server1.example.com   drbd     服务端2 ip172.25.25.112   主机名:server2.example.com    drbd 安装包 drbd-8.4.3.tar.gz 防火墙状态:关闭   1.Debd的简介 1.基本信息:Distributed Replicated Block Device(DRBD)是一个用软件实现的.无共享的.服务器之间镜像块