stm32 rtc 详解

目录

[L151 RTC 唤醒代码 方式一 通过 RTC Alarm Interrupt:(基本和F1系列一样):](#L151 RTC 唤醒代码 方式一 通过 RTC Alarm Interrupt:(基本和F1系列一样):)

[L151 RTC 唤醒代码 方式二 通过 RTC WakeUp Interrupt](#L151 RTC 唤醒代码 方式二 通过 RTC WakeUp Interrupt)

[F103VE RTC 闹钟唤醒代码 (103RC 没有闹钟中断):](#F103VE RTC 闹钟唤醒代码 (103RC 没有闹钟中断):)


RTC(real time clock 实时时钟)

STM32不同系列RTC 不一样

L151 RTC 唤醒代码 方式一 通过 RTC Alarm Interrupt:(基本和F1系列一样):

cubemx 自动生成如下代码:

cpp 复制代码
/*rtc.c*/
void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};
  RTC_AlarmTypeDef sAlarm = {0};

  /** Initialize RTC Only
  */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN Check_RTC_BKUP */
    
  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date
  */
  sTime.Hours = 0x0;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 0x1;
  sDate.Year = 0x0;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /** Enable the Alarm A
  */
  sAlarm.AlarmTime.Hours = 0x0;
  sAlarm.AlarmTime.Minutes = 0x0;
  sAlarm.AlarmTime.Seconds = 0x0;
  sAlarm.AlarmTime.SubSeconds = 0x0;
  sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
  sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
  sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  sAlarm.AlarmDateWeekDay = 0x1;
  sAlarm.Alarm = RTC_ALARM_A;
  if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }

}




/*stm32l1xx_it.c*/
void RTC_Alarm_IRQHandler(void)
{
  /* USER CODE BEGIN RTC_Alarm_IRQn 0 */

  /* USER CODE END RTC_Alarm_IRQn 0 */
  HAL_RTC_AlarmIRQHandler(&hrtc);
  /* USER CODE BEGIN RTC_Alarm_IRQn 1 */

  /* USER CODE END RTC_Alarm_IRQn 1 */
}
cpp 复制代码
void AlarmTimeSet(uint8_t min,uint8_t sec)
{
	RTC_TimeTypeDef nTime;
	RTC_DateTypeDef yTime;
	RTC_AlarmTypeDef aTime;
	
	HAL_RTC_GetTime(&hrtc,&nTime,RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc,&yTime, RTC_FORMAT_BIN);

	printf("%02d/%02d/%02d\r\n", 2000 + yTime.Year,yTime.Month, yTime.Date); 
	/* Display time Format : hh:mm:ss */
	printf("%02d:%02d:%02d\r\n",nTime.Hours, nTime.Minutes, nTime.Seconds);
	uint32_t curSecVal = nTime.Hours*60*60 + nTime.Minutes*60 + nTime.Seconds;
	
	
	uint32_t alarmSecVal = curSecVal + (min*60) + sec;
	
	aTime.Alarm = 1;
	aTime.AlarmTime.Hours = alarmSecVal/3600;
	aTime.AlarmTime.Minutes = (alarmSecVal%3600)/60;
	aTime.AlarmTime.Seconds = alarmSecVal %60;
	
	printf("%02d:%02d:%02d\r\n",aTime.AlarmTime.Hours, aTime.AlarmTime.Minutes, aTime.AlarmTime.Seconds);

	
	HAL_RTC_WaitForSynchro(&hrtc);
	
	HAL_RTC_SetAlarm_IT(&hrtc,&aTime,RTC_FORMAT_BIN);
	
	HAL_RTC_WaitForSynchro(&hrtc);
}



void RTC_AlarmConfig(void)
{

	RTC_AlarmTypeDef salarmstructure;

	/*##-1- Configure the RTC Alarm peripheral #################################*/
	/* Set Alarm to 01:17:30
		 RTC Alarm Generation: Alarm on Hours, Minutes and Seconds */
	salarmstructure.Alarm = RTC_ALARM_A;
	salarmstructure.AlarmTime.Hours = 0;
	salarmstructure.AlarmTime.Minutes = 0;
	salarmstructure.AlarmTime.Seconds = 10;

	if(HAL_RTC_SetAlarm_IT(&hrtc,&salarmstructure,RTC_FORMAT_BIN) != HAL_OK)
	{
			/* Initialization Error */
			Error_Handler();
	}
}


void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) 
{
	
}

L151 RTC 唤醒代码 方式二 通过 RTC WakeUp Interrupt

Cubemx:

wake up clock = 1HZ

wake up counter = 1

则1S唤醒一次

cubemx 自动生成如下代码:

cpp 复制代码
void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};

  /** Initialize RTC Only 
  */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN Check_RTC_BKUP */
    
  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date 
  */
  sTime.Hours = 0x0;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 0x1;
  sDate.Year = 0x0;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /** Enable the WakeUp 
  */
  if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 1, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
  {
    Error_Handler();
  }

}
cpp 复制代码
void RTC_WKUP_IRQHandler(void)
{
  /* USER CODE BEGIN RTC_WKUP_IRQn 0 */
	
 
  /* USER CODE END RTC_WKUP_IRQn 0 */
  HAL_RTCEx_WakeUpTimerIRQHandler(&hrtc);
  /* USER CODE BEGIN RTC_WKUP_IRQn 1 */

  /* USER CODE END RTC_WKUP_IRQn 1 */
}

可通过如下函数设置 中断时间

cpp 复制代码
void SetRtcWakeUpTime(uint16_t time)
{
    /*1HZ = RTC_WAKEUPCLOCK_CK_SPRE_16BITS*/
	HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, time, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
    
}

F103VE RTC 闹钟唤醒代码 (103RC 没有闹钟中断):

cubemx 自动生成如下代码:

cpp 复制代码
void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef DateToUpdate = {0};

  /** Initialize RTC Only 
  */
  hrtc.Instance = RTC;
  hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
  hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN Check_RTC_BKUP */
	if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1)==0X5050)
	{
		return;
	}
	HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1,0X5050);
  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date 
  */
  sTime.Hours = 0;
  sTime.Minutes = 0;
  sTime.Seconds = 10;

  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
  {
    Error_Handler();
  }
  DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY;
  DateToUpdate.Month = RTC_MONTH_JANUARY;
  DateToUpdate.Date = 1;
  DateToUpdate.Year = 0;

  if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN) != HAL_OK)
  {
    Error_Handler();
  }

}

void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{

  if(rtcHandle->Instance==RTC)
  {
  /* USER CODE BEGIN RTC_MspInit 0 */

  /* USER CODE END RTC_MspInit 0 */
    HAL_PWR_EnableBkUpAccess();
    /* Enable BKP CLK enable for backup registers */
    __HAL_RCC_BKP_CLK_ENABLE();
    /* RTC clock enable */
    __HAL_RCC_RTC_ENABLE();

    /* RTC interrupt Init */
    HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
  /* USER CODE BEGIN RTC_MspInit 1 */

  /* USER CODE END RTC_MspInit 1 */
  }
}

闹钟 配置代码如下:

cpp 复制代码
void AlarmTimeSet(uint8_t min,uint8_t sec)
{
	RTC_TimeTypeDef nTime;
	RTC_DateTypeDef yTime;
	RTC_AlarmTypeDef aTime;
	
	HAL_RTC_GetTime(&hrtc,&nTime,RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc,&yTime, RTC_FORMAT_BIN);

	printf("%02d/%02d/%02d\r\n", 2000 + yTime.Year,yTime.Month, yTime.Date); 
	/* Display time Format : hh:mm:ss */
	printf("%02d:%02d:%02d\r\n",nTime.Hours, nTime.Minutes, nTime.Seconds);
	uint32_t curSecVal = nTime.Hours*60*60 + nTime.Minutes*60 + nTime.Seconds;
	
	
	uint32_t alarmSecVal = curSecVal + (min*60) + sec;
	
	aTime.Alarm = 1;
	aTime.AlarmTime.Hours = alarmSecVal/3600;
	aTime.AlarmTime.Minutes = (alarmSecVal%3600)/60;
	aTime.AlarmTime.Seconds = alarmSecVal %60;
	
	printf("%02d:%02d:%02d\r\n",aTime.AlarmTime.Hours, aTime.AlarmTime.Minutes, aTime.AlarmTime.Seconds);

	
	HAL_RTC_WaitForSynchro(&hrtc);
	
	HAL_RTC_SetAlarm_IT(&hrtc,&aTime,RTC_FORMAT_BIN);
	
	HAL_RTC_WaitForSynchro(&hrtc);
}



void RTC_AlarmConfig(void)
{

	RTC_AlarmTypeDef salarmstructure;

	/*##-1- Configure the RTC Alarm peripheral #################################*/
	/* Set Alarm to 01:17:30
		 RTC Alarm Generation: Alarm on Hours, Minutes and Seconds */
	salarmstructure.Alarm = RTC_ALARM_A;
	salarmstructure.AlarmTime.Hours = 0;
	salarmstructure.AlarmTime.Minutes = 0;
	salarmstructure.AlarmTime.Seconds = 10;

	if(HAL_RTC_SetAlarm_IT(&hrtc,&salarmstructure,RTC_FORMAT_BIN) != HAL_OK)
	{
			/* Initialization Error */
			Error_Handler();
	}
}


void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) 
{
	
}
相关推荐
嵌入式大圣10 分钟前
单片机与MQTT协议
stm32·单片机·嵌入式硬件·物联网·51单片机
&AtTiTuDe;12 分钟前
STM32F103RCT6输出互补PWM波(HAL库)
经验分享·笔记·stm32
南城花随雪。24 分钟前
单片机:实现多任务处理(附带源码)
单片机·嵌入式硬件
jmlinux3 小时前
STM32 HAL库 + LM2904运算放大器 + ADC + 4-20ma液位传感器:电路设计及代码实现
stm32·单片机·嵌入式硬件
嵌入式小强工作室3 小时前
STM32内部flash分区
stm32·单片机·嵌入式硬件
析木不会编程3 小时前
【小白51单片机专用教程】protues仿真流水灯
单片机·嵌入式硬件·51单片机
嵌入式大圣4 小时前
单片机TCP无线数据透传
单片机·嵌入式硬件·tcp/ip
qq_459730035 小时前
1-15 GD32ARM存储器
c语言·arm开发·单片机
奇文怪式5 小时前
VSCode编辑+GCC for ARM交叉编译工具链+CMake构建+OpenOCD调试(基于STM32的标准库/HAL库)
arm开发·vscode·stm32