[STM32] RTC

pikamon·2021년 1월 1일
0

STM32

목록 보기
5/12
post-thumbnail

본 글은 STM32F769I MCU를 기준으로 작성되었습니다.
세부적인 내용은 제품군마다 조금씩 다를 수 있습니다.


1. RTC란?

RTC란 Real Time Clock의 줄임말로, 클럭을 입력으로 받아서 인간의 입장에서 유의미한, 즉 현실 세계의 시간을 표현해내기 위해 사용되는 모듈을 말한다.

2. 예제

RTC 모듈에 임의의 시간을 설정하고 주기마다 UART로 출력하는 예제를 만들어보자.

아래 그림을 보면 RTC가 APB1 버스에 물려있는 것을 볼 수 있다.

1. Configuration

RTC 항목에서 Activate Clock Source 를 체크하여 활성화한다.

2. 코드 작성

RTC는 별도의 GPIO 초기화가 필요하지 않다.
UART를 통해 출력 결과를 볼 것이기 때문에 UART도 활성화시켜준다.
시간은 현재 시간을 하드코딩하였다.

#include "main.h"

RTC_HandleTypeDef hrtc;
UART_HandleTypeDef huart1;

void SystemClock_Config(void)
{
	RCC_OscInitTypeDef RCC_OscInitStruct = { 0, };
	RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0, };

	__HAL_RCC_PWR_CLK_ENABLE();
	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI;
	RCC_OscInitStruct.HSIState = RCC_HSI_ON;
	RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
	RCC_OscInitStruct.LSIState = RCC_LSI_ON;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
	RCC_OscInitStruct.PLL.PLLM = 8;
	RCC_OscInitStruct.PLL.PLLN = 192;
	RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
	RCC_OscInitStruct.PLL.PLLQ = 4;
	RCC_OscInitStruct.PLL.PLLR = 2;
	HAL_RCC_OscConfig(&RCC_OscInitStruct);

	RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
	HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
}

static void MX_RTC_Init(void)
{
	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;
	HAL_RTC_Init(&hrtc);
}

static void MX_USART1_UART_Init(void)
{
	huart1.Instance = USART1;
	huart1.Init.BaudRate = 115200;
	huart1.Init.WordLength = UART_WORDLENGTH_8B;
	huart1.Init.StopBits = UART_STOPBITS_1;
	huart1.Init.Parity = UART_PARITY_NONE;
	huart1.Init.Mode = UART_MODE_TX_RX;
	huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart1.Init.OverSampling = UART_OVERSAMPLING_16;
	huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
	huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
	HAL_UART_Init(&huart1);
}

static void MX_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = { 0, };

	__HAL_RCC_GPIOA_CLK_ENABLE();

	// Initialize USART1
	GPIO_InitStruct.Pin =  GPIO_PIN_10 | GPIO_PIN_9;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

unsigned char B2D(unsigned char byte)
{
	unsigned char low, high;
	low = byte & 0x0F;
	high = ((byte >> 4) & 0x0F) * 10;
	return high + low;
}

int main(void)
{
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	MX_USART1_UART_Init();
	MX_RTC_Init();

	RTC_DateTypeDef date;
	date.Year = 0x22;
	date.Month = RTC_MONTH_MAY;
	date.Date = 0x29;
	date.WeekDay = RTC_WEEKDAY_SUNDAY;
	HAL_RTC_SetDate(&hrtc, &date, RTC_FORMAT_BCD);

	RTC_TimeTypeDef time;
	time.Hours = 0x18;
	time.Minutes = 0x26;
	time.Seconds = 0x13;
	HAL_RTC_SetTime(&hrtc, &time, RTC_FORMAT_BCD);

	char msg[21]; // YYYY-MM-DD HH:mm:SS

	while (1)
	{
		HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BCD);
		HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BCD);

		sprintf(msg, "%04d-%02d-%02d %02d:%02d:%02d\r\n",
				B2D(date.Year) + 2000, B2D(date.Month), B2D(date.Date),
				B2D(time.Hours), B2D(time.Minutes), B2D(time.Seconds));

		HAL_UART_Transmit(&huart1, (uint8_t*)msg, sizeof(msg), 100);
		HAL_Delay(1000);
	}
}

void Error_Handler(void)
{

}

3. 빌드 및 실행 결과

Ctrl + B 를 통해 빌드하면 정상 빌드되는 것을 볼 수 있다.

실제 타겟 보드에 올려서 실행해보자.

F11 을 누르면 창이 디버그 창으로 변경되며, Resume 버튼을 누르면 멈춤 없이 실행된다.

보드와 PC를 USB 5핀 케이블로 연결한 후, 터미널 프로그램을 열어서 COM포트를 연다.

위와 같이 1초 주기로 입력한 시간이 증가하며 출력되는 것을 볼 수 있다.

profile
개발자입니당 *^^* 깃허브 https://github.com/pikamonvvs

0개의 댓글