/* @NOT_ACT_USED */ /****************************************************************************** 版权所有 (C), 2001-2011, 上海全波通信技术有限公司 ****************************************************************************** 文 件 名 : rtc.c 版 本 号 : 初稿 作 者 : 郭金涛 生成日期 : 2013年7月30日 最近修改 : 功能描述 : RTC应用层相关API及初始化函数 函数列表 : rtc_back_mem_para_init rtc_init 修改历史 : 1.日 期 : 2013年7月30日 作 者 : 郭金涛 修改内容 : 创建文件 ******************************************************************************/ #include #include "type.h" #include "rtc.h" #include "os_task.h" #include "stm32f4xx.h" #include "delay.h" #include "eeprom.h" #include "stm32f4xx_hal.h" #if 1//_USE_RVL_ #include "i2c_drv.h" #endif #include "sys_config.h" #define RTC_SET_MAGIC_FLAG 0XF236 static S_BACKUP_MEM *pbackup_mem = NULL; RTC_HandleTypeDef hrtc; static void rtc_config(void) { // //uint32 time_out = 0; /* Enable the PWR clock */ //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); __HAL_RCC_PWR_CLK_ENABLE(); /* Allow access to RTC */ //PWR_BackupAccessCmd(ENABLE); HAL_PWR_EnableBkUpAccess(); /* Enable the LSE OSC */ //RCC_LSEConfig(RCC_LSE_ON); __HAL_RCC_LSE_CONFIG(RCC_LSE_ON); //time_out = 0x10000; //delay_ms(500); /* Wait till LSE is ready */ while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) { //if (time_out-- == 0) //{ // RCC_LSEConfig(RCC_LSE_OFF); // return; //} } /* Select the RTC Clock Source */ //RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); /* Enable the RTC Clock */ //RCC_RTCCLKCmd(ENABLE); __HAL_RCC_RTC_ENABLE(); //RTC_WaitForSynchro(); HAL_RTC_WaitForSynchro(&hrtc); //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE); __HAL_RCC_BKPSRAM_CLK_ENABLE(); //PWR_BackupRegulatorCmd(ENABLE); HAL_PWREx_EnableBkUpReg(); while(__HAL_PWR_GET_FLAG(PWR_FLAG_BRR) == RESET) { } } /***************************************************************************** 函 数 名 : rtc_init 功能描述 : 初始化RTC,当前系统使用的是32.768的LSE外部时钟 输入参数 : void 输出参数 : 无 返 回 值 : 调用函数 : 被调函数 : 修改历史 : 1.日 期 : 2013年7月24日 作 者 : 郭金涛 修改内容 : 新生成函数 *****************************************************************************/ uint32 rtc_init(void) { uint8 rtc_err = 0; printf("%s..\n",__FUNCTION__); //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); __HAL_RCC_PWR_CLK_ENABLE(); //使能备份区内存功能 //PWR_BackupAccessCmd(ENABLE); HAL_PWR_EnableBkUpAccess(); hrtc.Instance =RTC; //if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR0) != RTC_SET_MAGIC_FLAG) if(RTC_ReadBackupRegister(RTC_BKP_DR0) != RTC_SET_MAGIC_FLAG) {//DR0,存放的为RTC初始化标识 RTC_DateTypeDef d; RTC_TimeTypeDef t; printf("rtc is do not set.\n",__FUNCTION__); rtc_config(); RTC_WriteBackupRegister(RTC_BKP_DR0,RTC_SET_MAGIC_FLAG); //HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,RTC_SET_MAGIC_FLAG); d.RTC_Year = 14; d.RTC_Month = 1; d.RTC_Date = 1; t.RTC_Hours = 0; t.RTC_Minutes = 0; t.RTC_Seconds = 0; rtc_set_date_time(&d,&t); } else { /* Wait for RTC APB registers synchronisation */ if ( HAL_RTC_WaitForSynchro(&hrtc) == ERROR) { rtc_err = 2; return rtc_err; } //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE); __HAL_RCC_BKPSRAM_CLK_ENABLE(); } printf("%s success.\n",__FUNCTION__); return 0; } //初始化备份区的内存变量信息,此处内存可有电池供电,掉电不丢失 //预计有日志等部分变量放在备份内存区,也可以把临终遗言dump进去 uint32 rtc_back_mem_para_init(void) { uint32 *ptest; uint32 reset_flag = 0; uint16 i=0; printf("%s ..\n",__FUNCTION__); ptest = (uint32*)BACK_MEM_START_ADDRESS; if(*ptest!=0x33ffda1d) { printf("back_mem need init.\n"); *ptest = 0x33ffda1d; if(*ptest!=0x33ffda1d) { printf("%s failed 1.\n",__FUNCTION__); pbackup_mem = NULL; return 1; } reset_flag = 1; } if(sizeof(S_BACKUP_MEM)>BACK_MEM_SIZE-sizeof(uint32)) { printf("%s failed 2.\n",__FUNCTION__); pbackup_mem = NULL; return 2; } //实际可用的为BACK_MEM_START_ADDRESS+4 pbackup_mem = (S_BACKUP_MEM*)(BACK_MEM_START_ADDRESS+sizeof(uint32)); printf("%s success.\n",__FUNCTION__); if(reset_flag) { #if 1//_USE_RVL_ i = (c256_byteread(EERPOM_RESET_TIME_ADDR)<<8)|c256_byteread(EERPOM_RESET_TIME_ADDR+1); if(i==0xffff) { i = 0; c256_bytewrite(EERPOM_RESET_TIME_ADDR,0); c256_bytewrite(EERPOM_RESET_TIME_ADDR+1,0); } #endif pbackup_mem->reset_total_time = i; memset(&pbackup_mem->close_time,0,sizeof(pbackup_mem->close_time)); return 0; } pbackup_mem->reset_total_time++; #if 1//_USE_RVL_ c256_bytewrite(EERPOM_RESET_TIME_ADDR,pbackup_mem->reset_total_time>>8); c256_bytewrite(EERPOM_RESET_TIME_ADDR+1,pbackup_mem->reset_total_time); #endif printf("total reset time:%d.\n",pbackup_mem->reset_total_time); printf("last close sys time:%04d-%02d-%02d %02d:%02d:%02d.\n", pbackup_mem->close_time.year,pbackup_mem->close_time.month,pbackup_mem->close_time.date, pbackup_mem->close_time.hour,pbackup_mem->close_time.min,pbackup_mem->close_time.sec); (void)pbackup_mem; return 0; } uint32 sys_get_rst_time(void) { if(!pbackup_mem) return 0; return pbackup_mem->reset_total_time; } void sys_reset_rst_time(void) { if(pbackup_mem) { pbackup_mem->reset_total_time = 0; } #if 1//_USE_RVL_ c256_bytewrite(EERPOM_RESET_TIME_ADDR,0); c256_bytewrite(EERPOM_RESET_TIME_ADDR+1,0); #endif } void rtc_get_date_time(RTC_DateTypeDef *pd,RTC_TimeTypeDef *pt) { if((!pd)||(!pt)) { return; } //RTC_GetTime(RTC_Format_BIN, pt); //RTC_GetDate(RTC_Format_BIN, pd); HAL_RTC_GetTime(&hrtc, pt, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, pd, RTC_FORMAT_BIN); } //必须先读取时间,后读日期,否则若刚设置过日期,则日期会读取异常 void rtc_get_date(RTC_DateTypeDef *pd) { if(pd) { //RTC_GetDate(RTC_Format_BIN, pd); HAL_RTC_GetDate(&hrtc, pd, RTC_FORMAT_BIN); } } void rtc_get_time(RTC_TimeTypeDef *pt) { if(pt) { //RTC_GetTime(RTC_Format_BIN, pt); HAL_RTC_GetTime(&hrtc, pt, RTC_FORMAT_BIN); } } void rtc_set_date_time(RTC_DateTypeDef *pd,RTC_TimeTypeDef *pt) { uint32 ret = 0; if((!pd)||(!pt)) { return; } pd->RTC_WeekDay = 1; //ret = RTC_SetDate(RTC_Format_BIN, pd); ret = HAL_RTC_SetDate(&hrtc, pd, RTC_FORMAT_BIN); if(ERROR==ret) { printf("set date err!\n"); } //ret = RTC_SetTime(RTC_Format_BIN, pt); ret = HAL_RTC_SetTime(&hrtc, pt, RTC_FORMAT_BIN); if(ERROR==ret) { printf("set time err!\n"); } } void rtc_set_date(RTC_DateTypeDef *pd) { uint32 ret = 0; if(pd) { pd->RTC_WeekDay = 1; //RTC_SetDate(RTC_Format_BIN, pd); ret = HAL_RTC_SetDate(&hrtc, pd, RTC_FORMAT_BIN); } } void rtc_set_time(RTC_TimeTypeDef *pt) { uint32 ret = 0; if(pt) { //RTC_SetTime(RTC_Format_BIN, pt); ret = HAL_RTC_SetTime(&hrtc, pt, RTC_FORMAT_BIN); } } //更新系统关闭时间 void rtc_update_close_time(void) { if(pbackup_mem) { get_sys_time(&pbackup_mem->close_time); } } void rtc_get_last_close_time(S_SYS_TIME *ptime) { if(pbackup_mem) { *ptime = pbackup_mem->close_time; } } void* rtc_get_log_mem_address(void) { if(pbackup_mem) { return (void*)&pbackup_mem->os_log[0]; } else { return (void*)0; } }