STM32 RTC时钟设置
来源:互联网 发布:v盾网络验证破解 编辑:程序博客网 时间:2024/06/06 18:20
RTC移植时注意两点
(1)RTC需要中断函数。每秒中断一次,更新需要显示的标志。
(2)RTC运行中校正时间,更新RTC_CNTx时不能直接调用Time_Adjust()函数,需要开启PWR 和 BKP 时钟,且允许访问BKP域。
void RTC_SetCurrentTime(struct rtc_time *tm){/* Enable PWR and BKP clocks */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/* Allow access to BKP Domain */PWR_BackupAccessCmd(ENABLE);Time_Adjust(tm);RCC_ClearFlag();}
RTC的配置代码如下:
/** ****************************************************************************** * 文件名程: bsp_rtc.c * 作 者: 硬石嵌入式开发团队 * 版 本: V1.0 * 编写日期: 2015-10-04 * 功 能: 实时时钟底层驱动程序 ****************************************************************************** * 说明: * 本例程配套硬石stm32开发板YS-F1Pro使用。 * * 淘宝: * 论坛:http://www.ing10bbs.com * 版权归硬石嵌入式开发团队所有,请勿商用。 ****************************************************************************** *//* 包含头文件 ----------------------------------------------------------------*/#include "bsp/usart/bsp_usartx.h"#include "bsp/rtc/bsp_rtc.h"/* 私有类型定义 --------------------------------------------------------------*//* 私有宏定义 ----------------------------------------------------------------*//* 私有变量 ------------------------------------------------------------------*//*星期,生肖用文字ASCII码*/uint8_t const *WEEK_STR[] = {"日", "一", "二", "三", "四", "五", "六"};uint8_t const *zodiac_sign[] = {"猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗"};/* 扩展变量 ------------------------------------------------------------------*//* 私有函数原形 --------------------------------------------------------------*/void Time_Adjust(struct rtc_time *tm);static uint8_t USART_Scanf(uint32_t value);void Time_Regulate(struct rtc_time *tm);/* 函数体 --------------------------------------------------------------------*//** * 函数功能: 配置RTC秒中断的主中断优先级为1,次优先级为0 * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */static void RTC_NVIC_Config(void){NVIC_InitTypeDef NVIC_InitStructure;/* Enable the RTC Interrupt */NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}/** * 函数功能: 简单的延时函数 * 输入参数: time:延时时间 * 返 回 值: 无 * 说 明:无 */static void Delay(uint16_t time){ uint16_t i; while(--time) { for(i=0;i<2000;i++); }}/** * 函数功能: 配置RTC * 输入参数: 无 * 返 回 值: 1:RTC配置成功或运行正常,0:RTC无法正常使用 * 说 明:无 */static uint8_t RTC_Configuration(void){ uint32_t count=0; /* Enable PWR and BKP clocks */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/* Allow access to BKP Domain */PWR_BackupAccessCmd(ENABLE);/* Reset Backup Domain */BKP_DeInit();/* Enable LSE */RCC_LSEConfig(RCC_LSE_ON);/* Wait till LSE is ready */while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){ Delay(100); count++; if(count>4000)return 0; }/* Select LSE as RTC Clock Source */RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);/* Enable RTC Clock */RCC_RTCCLKCmd(ENABLE);/* Wait for RTC registers synchronization * 因为RTC时钟是低速的,内环时钟是高速的,所以要同步 */RTC_WaitForSynchro();/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();/* Enable the RTC Second */RTC_ITConfig(RTC_IT_SEC, ENABLE);/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();/* Set RTC prescaler: set RTC period to 1sec */RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) = 1HZ *//* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask(); return 1;}void RTC_SetCurrentTime(struct rtc_time *tm){/* Enable PWR and BKP clocks */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/* Allow access to BKP Domain */PWR_BackupAccessCmd(ENABLE);Time_Adjust(tm);RCC_ClearFlag();}void RTC_SetAlarmTime(struct rtc_time *tm){Time_Regulate(tm);}/** * 函数功能: 检查并配置RTC * 输入参数: tm:用于读取RTC时间的结构体指针 * 返 回 值: 无 * 说 明:无 */uint8_t RTC_CheckAndConfig(struct rtc_time *tm){ /* 配置RTC秒中断的主中断优先级 */ RTC_NVIC_Config(); /*在启动时检查备份寄存器BKP_DR1,如果内容不是0xA5A5, 则需重新配置时间并询问用户调整时间*/if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5){printf("RTC not yet configured....\n");/* RTC Configuration */if(RTC_Configuration()!=1){ return 0;}printf("RTC configured....\n");/* Adjust time by users typed on the hyperterminal */Time_Adjust(tm);BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);}else{ /*启动无需设置新时钟*//*检查是否掉电重启*/if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET){ printf("Power On Reset occurred....\n");}/*检查是否Reset复位*/else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET){printf("External Reset occurred....\n");}printf("No need to configure RTC....\n");/*等待寄存器同步*/RTC_WaitForSynchro();/*允许RTC秒中断*/RTC_ITConfig(RTC_IT_SEC, ENABLE);/*等待上次RTC寄存器写操作完成*/RTC_WaitForLastTask();} /*定义了时钟输出宏,则配置校正时钟输出到PC13*/#ifdef RTCClockOutput_Enable /* Enable PWR and BKP clocks */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); /* Allow access to BKP Domain */ PWR_BackupAccessCmd(ENABLE); /* Disable the Tamper Pin */ BKP_TamperPinCmd(DISABLE); /* To output RTCCLK/64 on Tamper pin, the tamper functionality must be disabled */ /* Enable RTC Clock Output on Tamper Pin */ BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);#endif /* Clear reset flags */ RCC_ClearFlag(); return 1;}/** * 函数功能: 时间调节实现 * 输入参数: tm:用于读取RTC时间的结构体指针 * 返 回 值: 无 * 说 明:无 *//** * static * 函数功能: 时间调整,保存在RTC时钟结构体 * 输入参数: tm:用于读取RTC时间的结构体指针 * 返 回 值: 无 * 说 明:无 */ void Time_Regulate(struct rtc_time *tm){#if 0 tm->tm_year = 2015; tm->tm_mon = 10; tm->tm_mday = 4; tm->tm_hour = 10; tm->tm_min = 15; tm->tm_sec = 46;#else u32 Tmp_YY = 0xFF, Tmp_MM = 0xFF, Tmp_DD = 0xFF, Tmp_HH = 0xFF, Tmp_MI = 0xFF, Tmp_SS = 0xFF; printf("=========================Time Settings==================\n"); printf("请输入年份(Please Set Years): 20\n"); while (Tmp_YY == 0xFF) { Tmp_YY = USART_Scanf(99); } printf("年份被设置为: 20%0.2d\n", Tmp_YY); tm->tm_year = Tmp_YY+2000; Tmp_MM = 0xFF; printf("请输入月份(Please Set Months): \n"); while (Tmp_MM == 0xFF) { Tmp_MM = USART_Scanf(12); } printf("月份被设置为: %d\n", Tmp_MM); tm->tm_mon= Tmp_MM; Tmp_DD = 0xFF; printf("请输入日期(Please Set Dates): \n"); while (Tmp_DD == 0xFF) { Tmp_DD = USART_Scanf(31); } printf("日期被设置为: %d\n", Tmp_DD); tm->tm_mday= Tmp_DD; Tmp_HH = 0xFF; printf("请输入时钟(Please Set Hours): \n"); while (Tmp_HH == 0xFF) { Tmp_HH = USART_Scanf(23); } printf("时钟被设置为: %d\n", Tmp_HH ); tm->tm_hour= Tmp_HH; Tmp_MI = 0xFF; printf("请输入分钟(Please Set Minutes): \n"); while (Tmp_MI == 0xFF) { Tmp_MI = USART_Scanf(59); } printf("分钟被设置为: %d\n", Tmp_MI); tm->tm_min= Tmp_MI; Tmp_SS = 0xFF; printf("请输入秒钟(Please Set Seconds): \n"); while (Tmp_SS == 0xFF) { Tmp_SS = USART_Scanf(59); } printf("秒钟被设置为: %d\n", Tmp_SS); tm->tm_sec= Tmp_SS; #endif}void Time_Adjust(struct rtc_time *tm){ /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); /* Get time entred by the user on the hyperterminal */ Time_Regulate(tm); /* Get wday */ GregorianDay(tm); /* 修改当前RTC计数寄存器内容 */ RTC_SetCounter(mktimev(tm)); /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask();}/*** 函数功能: 从串口调试助手获取数字值(把ASCII码转换为数字)* 输入参数: value 用户在超级终端中输入的数值* 返 回 值: 输入字符的ASCII码对应的数值* 说 明:本函数专用于RTC获取时间,若进行其它输入应用,要修改一下*/static uint8_t USART_Scanf(uint32_t value){uint32_t index = 0;uint32_t tmp[2] = {0, 0};while (index < 2){/* Loop until RXNE = 1 */while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){} tmp[index++] = (USART_ReceiveData(USART1));if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39)) /*数字0到9的ASCII码为0x30至0x39*/{ printf("Please enter valid number between 0 and 9 -->: \n");index--; }}/* 计算输入字符的ASCII码转换为数字*/index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10);/* Checks */if (index > value){printf("Please enter valid number between 0 and %d\n", value);return 0xFF;}return index;}/** * 函数功能: 显示当前时间值 * 输入参数: TimeVar RTC计数值,单位为 s,tm:用于读取RTC时间的结构体指针 * 返 回 值: 无 * 说 明:无 */void Time_Display(uint32_t TimeVar,struct rtc_time *tm){ static uint8_t FirstDisplay = 1; uint32_t BJ_TimeVar; uint8_t str[15]; // 字符串暂存 /* 把标准时间转换为北京时间*/ BJ_TimeVar =TimeVar + 8*60*60; to_tm(BJ_TimeVar, tm);/*把定时器的值转换为北京时间*/ if((!tm->tm_hour && !tm->tm_min && !tm->tm_sec) || (FirstDisplay)) { GetChinaCalendar((u16)tm->tm_year, (u8)tm->tm_mon, (u8)tm->tm_mday, str); printf("今天新历:%0.2d%0.2d,%0.2d,%0.2d\n", str[0], str[1], str[2], str[3]); GetChinaCalendarStr((u16)tm->tm_year,(u8)tm->tm_mon,(u8)tm->tm_mday,str); printf("今天农历:%s\n", str); if(GetJieQiStr((u16)tm->tm_year, (u8)tm->tm_mon, (u8)tm->tm_mday, str)) printf("今天农历:%s\n", str); FirstDisplay = 0; } /* 输出时间戳,公历时间 */ printf(" UNIX时间戳 = %d 当前时间为: %d年(%s年) %d月 %d日 (星期%s) %0.2d:%0.2d:%0.2d\n",TimeVar, tm->tm_year, zodiac_sign[(tm->tm_year-3)%12], tm->tm_mon, tm->tm_mday, WEEK_STR[tm->tm_wday], tm->tm_hour, tm->tm_min, tm->tm_sec);}/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
RTC程序文件:http://pan.baidu.com/s/1jIzfaxo
阅读全文
0 0
- STM32 RTC时钟设置
- STM32 RTC时钟
- STM32 RTC实时时钟
- stm32 RTC时钟配置
- STM32 RTC 时钟简介
- STM32 RTC 时钟
- stm32 rtc 实时时钟
- STM32 RTC时钟配置
- stm32 RTC时钟配置
- STM32的RTC实时时钟
- STM32学习-RTC实时时钟
- STM32之RTC实时时钟
- STM32 RTC时钟源LSE
- STM32 RTC设置 (转)
- 纠结的STM32 RTC时钟源LSE
- stm32——RTC实时时钟
- stm32——RTC实时时钟
- STM32 时钟设置
- 双向A*算法浅析
- BaseActivity之后的修改步骤
- Java学习
- leetcode 205 Isomorphic Strings
- Atcoder Shik and Game
- STM32 RTC时钟设置
- hdu6166(xjb迪杰斯特拉)
- 最小生成树 prim算法 C++实现
- [简单逻辑学]学习逻辑学的思想准备——避免闪避式语言
- linux 安装expect
- xlistview
- HTML5
- 广播监听网络状态
- Codeforces-840C On the Bench(dp)