Embedded

ARM Cortex M4 core - (5) RTC 알람시계

MiddleJo 2024. 9. 4. 20:08

RTC.zip
10.76MB

목차

1. 배경

2. 보드 구성 및 소스코드

3. 실습결과

 

 

1. 배경

 

다양한 작업을 하다 보면 타이머가 필요한 경우가 있습니다.

RTC는 다양한 시간 단위로 컨트롤할 수 있고, 알람 인터럽트를 제공합니다.

 

간단하게 10초마다 알람을 울리는 알람시계를 만들어보도록 하겠습니다.

 

2. 보드 구성 및 소스코드

기본적으로, Board Select 선택 시 불필요한 기능이 포함되어

코드가 길어지고 보기 불편합니다.

 

이번에는, Oscillator 설정 등의 설정이 복잡하여

Board select로 선택하고 진행하도록 하겠습니다.

 

 

 

- 보드 세팅

 

 

- RCC 세팅

 

이번에도 LSE를 사용하도록 하겠습니다.

 

 

 

- NVIC 세팅

 

RTC Interrupt를 사용하기 위해 세팅해 줍니다.

 

 

- RTC 설정

 

이후에 코드에서도 바꿀 수 있지만, 여기서 보기 좋게 바꿀 수 있습니다.

Seconds 메뉴에 10 입력하여 10초마다 울리게 만들도록 하겠습니다.

 

 

 

 

- PV

/* USER CODE BEGIN PV */
//char ampm[2][3] = {"AM","PM"};
char *ampm[] = {"AM","PM"}; // 1d array
char temp[100];
char s1[100];

//#define RTC_HOURFORMAT12_AM = ((uint8_t)0x00)
//#define RTC_HOURFORMAT12_PM = ((uint8_t)0x40)

void get_time(void)
{
	RTC_DateTypeDef sDate;
	RTC_TimeTypeDef sTime;

	HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);

	sprintf(temp, "\r\n20%02d-%02d-%02d %s %02d:%02d:%02d", sDate.Year, sDate.Month,
	sDate.Date, ampm[sTime.TimeFormat >> 6], sTime.Hours, sTime.Minutes, sTime.Seconds);
	sprintf(s1,"%d",sTime.TimeFormat);
	sprintf(s1,"%d",sTime.Hours);
	sprintf(s1,"%d",5);
}
/* USER CODE END PV */

 

PV함수와 함께, get time 함수를 정의합니다.

시간에 대해 문자열을 만들어줍니다.

중간에 define 함수는 stm32f4xx_hal_rtc.h에서 바꿔줘도 됩니다.

 

 

 

 

- Main

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ETH_Init();
  MX_USART3_UART_Init();
  MX_USB_OTG_FS_PCD_Init();
  MX_RTC_Init();

  /* Initialize interrupts */
  MX_NVIC_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  get_time();
	  HAL_UART_Transmit(&huart3, (uint8_t *)&temp, strlen(temp), 1000);
	  HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

 

앞서 정의한 get_time 함수로 시간 정보를 받고,

UART를 통해 PC에 보여줍니다.

 

 

- HAL_RTC_Alarm Callback

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
	printf("\r\nAlarm Callback Occurred!! \r\n");

	HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);

//	// load time
//	RTC_TimeTypeDef sTime;
//	HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BIN);
//
//	// reset alarm
//	RTC_AlarmTypeDef sAlarm = {0};
//	sAlarm.AlarmTime.Hours = sTime.Hours;
//	sAlarm.AlarmTime.Minutes = sTime.Minutes;
//	sAlarm.AlarmTime.Seconds = (sTime.Seconds + 10) % 60;
//	if ((sTime.Seconds + 10) >= 60) {
//		sAlarm.AlarmTime.Minutes = (sTime.Minutes + 1) % 60;
//		if ((sTime.Minutes + 1) >= 60) {
//			sAlarm.AlarmTime.Hours = (sTime.Hours + 1) % 24;
//		}
//	}
//	sAlarm.AlarmTime.SubSeconds = 0;
//	sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
//	sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
//	sAlarm.AlarmMask = RTC_ALARMMASK_HOURS | RTC_ALARMMASK_MINUTES | RTC_ALARMMASK_DATEWEEKDAY;
//	sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
//	sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
//	sAlarm.AlarmDateWeekDay = 1;
//	sAlarm.Alarm = RTC_ALARM_A;
//
//	if (HAL_RTC_SetAlarm_IT(hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
//	{
//		Error_Handler();
//	}
}

 

주석은 다른 실험을 위해 작성하였습니다. 작동에는 지장이 없습니다.

 

 

3. 실습결과

 

 

 

10초가 되었을 때 알람이 잘 울리는 것을 알 수 있습니다.

실습 당시 날짜를 않고 실행하였는데, 보드 설정에서 설정하실 수 있습니다.