Запуск RTC и настройка будильника: различия между версиями
Андрей (обсуждение | вклад) (Новая страница: «В примере будут записаны данные в основной массив OTP, тестовый столбец и тестовую строку,...») |
Дмитрий (обсуждение | вклад) (закомментировал код. добавил подключение UARTa. пронумеровал рисунки (начиная с 3) в HAL_RTC) |
||
(не показано 14 промежуточных версий 1 участника) | |||
Строка 1: | Строка 1: | ||
В примере будут | В примере будут запущен таймер RTC и настроен будильник. | ||
== Работа с конфигуратором (В разработке) == | == Работа с конфигуратором (В разработке) == | ||
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как | Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как RTC тактируется от шины APB_M_CLK, то зададим делители AHB_DIV и APB_M_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так: | ||
(Картинка тактирования из конфигуратора. В работе) | (Картинка тактирования из конфигуратора. В работе) | ||
Затем перейдем к настройке самого | Затем перейдем к настройке самого RTC. Для этого откроем вкладку RTC и нажмем включить. | ||
[[Файл:Рисунок 1 - Настройки RTC в конфигураторе.png|мини|Рисунок 1 - Настройки RTC в конфигураторе]] | |||
Выберем тактирование от "внешнего осциллятора OSC32K". Во вкладке дата и время RTC нажмем кнопку взять дату с компьютера. Все поля автоматически заполнятся. При заполнении полей вручную следует вводить корректную дату. | |||
Следующая вкладка "регистры RTC". Здесь задаются значения регистров общего назначения REG0-REG15. Они могут использоваться в произвольных целях. Регистры располагаются в батарейном домене и сохраняют свое значение при отключении системного питания и при внешнем сбросе. В данном примере в них ничего записываться не будет. | |||
[[Файл:Рисунок - Настройки будильника RTC в конфигураторе.png|мини|Рисунок - Настройки будильника RTC в конфигураторе]] | |||
В самом начале настроек нажмем галочку "включить будильник". После этого появится еще одна вкладка с настройками даты и времени будильника. Запишем все поля будильника как во времени и дате RTC, но секунды напишем на 5 больше. | |||
В итоге настройки | В итоге настройки RTC в конфигураторе должны выглядеть как на рисунках. | ||
(Объяснение работы с конфигуратором. В разработке) | (Объяснение работы с конфигуратором. В разработке) | ||
Нажимаем кнопку генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code. | Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code. | ||
== Использование библиотеки HAL_RTC == | == Использование библиотеки HAL_RTC == | ||
В сгенерированном проекте в файле main.c должна быть функция | В сгенерированном проекте в файле main.c должна быть функция RTC_Init, в которой будут заданы настройки для RTC. Выглядит она так: | ||
{{#spoiler:show=Развернуть код|hide=Свернуть код| | |||
<syntaxhighlight lang="c" line="1"> | |||
static void RTC_Init(void) | |||
{ | |||
RTC_TimeTypeDef sTime = {0}; | |||
RTC_DateTypeDef sDate = {0}; | |||
RTC_AlarmTypeDef sAlarm = {0}; | |||
hrtc.Instance = RTC; | |||
/* Установка даты и времени RTC */ | |||
sTime.Dow = RTC_WEEKDAY_WEDNESDAY; | |||
sTime.Hours = 14; | |||
sTime.Minutes = 54; | |||
sTime.Seconds = 15; | |||
/* Выключение RTC для записи даты и времени */ | |||
HAL_RTC_Disable(&hrtc); | |||
HAL_RTC_SetTime(&hrtc, &sTime); | |||
sDate.Century = 21; | |||
sDate.Day = 15; | |||
sDate.Month = RTC_MONTH_FEBRUARY; | |||
sDate.Year = 23; | |||
HAL_RTC_SetDate(&hrtc, &sDate); | |||
/* Включение будильника. Настройка даты и времени будильника */ | |||
sAlarm.AlarmTime.Dow = RTC_WEEKDAY_WEDNESDAY; | |||
sAlarm.AlarmTime.Hours = 14; | |||
sAlarm.AlarmTime.Minutes = 54; | |||
sAlarm.AlarmTime.Seconds = 20; | |||
sAlarm.AlarmDate.Century = 21; | |||
sAlarm.AlarmDate.Day = 15; | |||
sAlarm.AlarmDate.Month = RTC_MONTH_FEBRUARY; | |||
sAlarm.AlarmDate.Year = 23; | |||
/* Маски сравнения будильника по дате и времени */ | |||
sAlarm.MaskAlarmTime = RTC_TALRM_CDOW_M | RTC_TALRM_CH_M | RTC_TALRM_CM_M | RTC_TALRM_CS_M; | |||
sAlarm.MaskAlarmDate = RTC_DALRM_CC_M | RTC_DALRM_CD_M | RTC_DALRM_CM_M | RTC_DALRM_CY_M; | |||
HAL_RTC_SetAlarm(&hrtc, &sAlarm); | |||
HAL_RTC_Enable(&hrtc); | |||
} | |||
</syntaxhighlight> | |||
}} | |||
Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_M присутствует PM_CLOCK_RTC_M. Сама функция должна выглядеть примерно так: | |||
{{#spoiler:show=Развернуть код|hide=Свернуть код| | |||
<syntaxhighlight lang="c" line="1"> | |||
void SystemClock_Config(void) | |||
{ | |||
RCC_OscInitTypeDef RCC_OscInit = {0}; | |||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; | |||
RCC_OscInit.OscillatorEnable = RCC_OSCILLATORTYPE_OSC32K | RCC_OSCILLATORTYPE_OSC32M; | |||
RCC_OscInit.OscillatorSystem = RCC_OSCILLATORTYPE_OSC32M; | |||
RCC_OscInit.AHBDivider = 0; | |||
RCC_OscInit.APBMDivider = 0; | |||
RCC_OscInit.APBPDivider = 0; | |||
RCC_OscInit.HSI32MCalibrationValue = 0; | |||
RCC_OscInit.LSI32KCalibrationValue = 0; | |||
HAL_RCC_OscConfig(&RCC_OscInit); | |||
PeriphClkInit.PMClockAHB = PMCLOCKAHB_DEFAULT; | |||
PeriphClkInit.PMClockAPB_M = PMCLOCKAPB_M_DEFAULT | PM_CLOCK_WU_M | PM_CLOCK_RTC_M; | |||
PeriphClkInit.PMClockAPB_P = PMCLOCKAPB_P_DEFAULT | PM_CLOCK_UART_0_M; | |||
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_OSC32K; | |||
PeriphClkInit.RTCClockCPUSelection = RCC_RTCCLKCPUSOURCE_NO_CLK; | |||
HAL_RCC_ClockConfig(&PeriphClkInit); | |||
} | |||
</syntaxhighlight> | |||
}} | |||
Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. Для этого нужно подключить библиотеки uart_lib и xprintf. | |||
{{#spoiler:show=Развернуть код|hide=Свернуть код| | |||
<syntaxhighlight lang="c" line="1"> | |||
#include "mik32_hal_rtc.h" | |||
#include "mik32_hal_rcc.h" | |||
#include "uart_lib.h" | |||
#include "xprintf.h" | |||
</syntaxhighlight> | |||
}} | |||
Для инициализации UART в функции main, после функции тактирования SystemClock_Config, следует написать: | |||
<syntaxhighlight lang="c" line="1" start="1"> | |||
UART_Init(UART_0, 3333, UART_CONTROL1_TE_M | UART_CONTROL1_M_8BIT_M, 0, 0); | |||
</syntaxhighlight> | |||
Скорость UART задается делителем во втором аргументе функции. При такой записи скорость будет 9600 бод. | |||
В начале main.c можно видеть объявление структуры с набором настроек для RTC, которую использует функция инициализации RTC_Init. | |||
{{#spoiler:show=Развернуть код|hide=Свернуть код| | |||
<syntaxhighlight lang="c" line="1"> | |||
RTC_HandleTypeDef hrtc; | |||
RTC_TimeTypeDef CurrentTime = {0}; | |||
RTC_DateTypeDef CurrentDate = {0}; | |||
void SystemClock_Config(void); | |||
static void RTC_Init(void); | |||
</syntaxhighlight> | |||
}} | |||
Для запуска RTC нужно после его инициализации воспользоваться функцией HAL_RTC_Enable. | |||
С помощью функции HAL_RTC_Check можно вывести в UART дату и время RTC. | |||
Функция HAL_RTC_GetFlagALRM возвращает значение 1 при срабатывании будильника. | |||
HAL_RTC_AlarmDisable - сбрасывает маску сравнения будильника. Дата и время будильника не сравнивается с датой и временем RTC. | |||
HAL_RTC_AlrmClear - очищает флаг будильника ALRM. | |||
Функция main может выглядеть примерно так: | |||
{{#spoiler:show=Развернуть код|hide=Свернуть код| | |||
<syntaxhighlight lang="c" line="1"> | |||
int main() | |||
{ | |||
SystemClock_Config(); | |||
UART_Init(UART_0, 3333, UART_CONTROL1_TE_M | UART_CONTROL1_M_8BIT_M, 0, 0); | |||
RTC_Init(); | |||
HAL_RTC_Enable(&hrtc); | |||
int counter = 1000000; | |||
while (1) | |||
{ | |||
if (--counter < 0) | |||
{ | |||
CurrentDate = HAL_RTC_CheckDate(&hrtc); | |||
xprintf("\n%d век\n", CurrentDate.Century); | |||
xprintf("%d.%d.%d\n", CurrentDate.Day, CurrentDate.Month, CurrentDate.Year); | |||
CurrentTime = HAL_RTC_CheckTime(&hrtc); | |||
switch (CurrentTime.Dow) | |||
{ | |||
case 1: | |||
xprintf("Понедельник\n"); | |||
break; | |||
case 2: | |||
xprintf("Вторник\n"); | |||
break; | |||
case 3: | |||
xprintf("Среда\n"); | |||
break; | |||
case 4: | |||
xprintf("Четверг\n"); | |||
break; | |||
case 5: | |||
xprintf("Пятница\n"); | |||
break; | |||
case 6: | |||
xprintf("Суббота\n"); | |||
break; | |||
case 7: | |||
xprintf("Воскресенье\n"); | |||
break; | |||
} | |||
xprintf("%d:%d:%d.%d\n", CurrentTime.Hours, CurrentTime.Minutes, CurrentTime.Seconds, hrtc.Instance->TOS); | |||
counter = 1000000; | |||
} | |||
if (HAL_RTC_GetAlrmFlag(&hrtc)) | |||
{ | |||
xprintf("\nAlarm!\n"); | |||
HAL_RTC_AlarmDisable(&hrtc); | |||
HAL_RTC_ClearAlrmFlag(&hrtc); | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
}} | |||
[[Файл:Вывод в UART.png|мини|Рисунок 3 - Вывод в UART]] | |||
В данном примере запускается RTC и выводит дату и время в UART. Через 5 секунд должен сработать будильник. При срабатывании будильника в UART отправляется сообщение "Alarm!". После этого будильник должен отключиться, а вывод времени и даты RTC продолжиться. Пример вывода UART изображен на рисунке 3. |
Текущая версия от 09:51, 24 марта 2023
В примере будут запущен таймер RTC и настроен будильник.
Работа с конфигуратором (В разработке)
Для начала настроем в конфигураторе тактирование mik32, например, от внешнего кварца 32МГц. Затем настроем делители шины. Так как RTC тактируется от шины APB_M_CLK, то зададим делители AHB_DIV и APB_M_DIV. В данном примере оставим делители по умолчанию. В итоге вкладка с тактированием должна выглядеть так:
(Картинка тактирования из конфигуратора. В работе)
Затем перейдем к настройке самого RTC. Для этого откроем вкладку RTC и нажмем включить.
Выберем тактирование от "внешнего осциллятора OSC32K". Во вкладке дата и время RTC нажмем кнопку взять дату с компьютера. Все поля автоматически заполнятся. При заполнении полей вручную следует вводить корректную дату.
Следующая вкладка "регистры RTC". Здесь задаются значения регистров общего назначения REG0-REG15. Они могут использоваться в произвольных целях. Регистры располагаются в батарейном домене и сохраняют свое значение при отключении системного питания и при внешнем сбросе. В данном примере в них ничего записываться не будет.
В самом начале настроек нажмем галочку "включить будильник". После этого появится еще одна вкладка с настройками даты и времени будильника. Запишем все поля будильника как во времени и дате RTC, но секунды напишем на 5 больше.
В итоге настройки RTC в конфигураторе должны выглядеть как на рисунках.
(Объяснение работы с конфигуратором. В разработке)
Нажимаем кнопку сохранения и генерации. В итоге у нас появится проект для PlatformIo. Далее работа идет в visual studio code.
Использование библиотеки HAL_RTC
В сгенерированном проекте в файле main.c должна быть функция RTC_Init, в которой будут заданы настройки для RTC. Выглядит она так:
Кроме этого в функции SystemClock_Config приведены настройки для тактирования. Убедитесь что в PeriphClkInit.PMClockAPB_M присутствует PM_CLOCK_RTC_M. Сама функция должна выглядеть примерно так:
Для демонстрации вывода текста в PeriphClkInit.PMClockAPB_P присутствует PM_CLOCK_UART_0_M. У вас его может не быть так как UART нужно включить отдельно. Для этого нужно подключить библиотеки uart_lib и xprintf.
Для инициализации UART в функции main, после функции тактирования SystemClock_Config, следует написать:
UART_Init(UART_0, 3333, UART_CONTROL1_TE_M | UART_CONTROL1_M_8BIT_M, 0, 0);
Скорость UART задается делителем во втором аргументе функции. При такой записи скорость будет 9600 бод.
В начале main.c можно видеть объявление структуры с набором настроек для RTC, которую использует функция инициализации RTC_Init.
Для запуска RTC нужно после его инициализации воспользоваться функцией HAL_RTC_Enable.
С помощью функции HAL_RTC_Check можно вывести в UART дату и время RTC.
Функция HAL_RTC_GetFlagALRM возвращает значение 1 при срабатывании будильника.
HAL_RTC_AlarmDisable - сбрасывает маску сравнения будильника. Дата и время будильника не сравнивается с датой и временем RTC.
HAL_RTC_AlrmClear - очищает флаг будильника ALRM.
Функция main может выглядеть примерно так:
В данном примере запускается RTC и выводит дату и время в UART. Через 5 секунд должен сработать будильник. При срабатывании будильника в UART отправляется сообщение "Alarm!". После этого будильник должен отключиться, а вывод времени и даты RTC продолжиться. Пример вывода UART изображен на рисунке 3.