Перейти к содержанию
    

stm32 RTC Alarm

Проблемы с будильником на STM32F401VCT6. Нужно переодически делать полезную работу. Решил сделать по будильнику. часы и будильник поднял легко, как вот тут

Один раз запускаю будильник, например на 5 секунд - через 5 секунд попадаю в прерывание RTC_Alarm_IRQHandler(). Внутри прерывания добавил перезапуск будильника на тотже интервал. Далее будильник срабатывает через секунду. Почему?

 

перепробывал всё, перепроверил всё... пересчеты времени... делал массив в который кидал текущее время и время аларма.... вроде будильник правильно завожу, но он ПЕРВЫЙ раз срабатывает через 5 сек, как положенно, а все последующие разы через 1 сек.

 

потом, для дебага в прерывании, перед новым инитом алармы вставил строчку

RTC_GetAlarm(RTC_Format_BIN, RTC_Alarm_A, &alarm1);

ЗАРАБОТАЛО!!! Будильник как положенно раз в 5 сек срабатывает. Если эту строчку закоментить, то раз в 1 сек. Не могу понять, как RTC_GetAlarm() влияет на работу будильника?

 

int main()
{
RTC_InitTypeDef rtc;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //Включаем тактирование (PWR — Power Control):

PWR_BackupAccessCmd(ENABLE);

RCC_BackupResetCmd(ENABLE);
RCC_BackupResetCmd(DISABLE);

RCC_LSICmd(ENABLE);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
RCC_RTCCLKCmd(ENABLE);

rtc.RTC_HourFormat = RTC_HourFormat_24;
rtc.RTC_SynchPrediv = 0x7FFF;
RTC_Init(&rtc);

EXTI_InitTypeDef exti;
EXTI_ClearITPendingBit(EXTI_Line17);
exti.EXTI_Line = EXTI_Line17;
exti.EXTI_Mode = EXTI_Mode_Interrupt;
exti.EXTI_Trigger = EXTI_Trigger_Rising;
exti.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti);

NVIC_EnableIRQ(RTC_Alarm_IRQn);
NVIC_SetPriority(RTC_Alarm_IRQn, 13);

   setNewAlarmRTC(5);


	while(1);
}

extern "C" void RTC_Alarm_IRQHandler()
{
if( RTC_GetITStatus(RTC_IT_ALRA) != RESET )
{
	RTC_ClearITPendingBit(RTC_IT_ALRA);
	EXTI_ClearITPendingBit(EXTI_Line17);
	setNewAlarmRTC(5); 		//перезапустим таймер
}
}

//заводит будильник Alarm_A на время через seconds секунд
void setNewAlarmRTC(uint32_t seconds)
{

RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
RTC_ITConfig(RTC_IT_ALRA, DISABLE);
RTC_ClearITPendingBit(RTC_IT_ALRA);

  	RTC_TimeTypeDef time;
RTC_GetTime(RTC_Format_BIN, &time);


RTC_AlarmTypeDef alarm1;
//RTC_GetAlarm(RTC_Format_BIN, RTC_Alarm_A, &alarm1);//если эту строку раскоментировать, то будильник будет работать нормально

RTC_TimeTypeDef alarmTime = time;
addSecToTime(&alarmTime, seconds);//добавим секунды к текущему времени

RTC_AlarmTypeDef alarm;
alarm.RTC_AlarmTime = alarmTime;
alarm.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay;
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &alarm);

//RTC_OutputConfig(RTC_Output_AlarmA, RTC_OutputPolarity_High);
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
RTC_AlarmCmd(RTC_Alarm_A, ENABLE);
RTC_ClearFlag(RTC_FLAG_ALRAF);
}

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Часы - это асинхронное оборудование для проца. Это описано в даташите.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Часы - это асинхронное оборудование для проца. Это описано в даташите.

И? Почему RTC_GetAlarm() влияет на работу будильника?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Замените вашу RTC_GetAlarm() на любую другую процедуру или просто вызовите задержку. Думаю результат будет тот же.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Замените вашу RTC_GetAlarm() на любую другую процедуру или просто вызовите задержку. Думаю результат будет тот же.

делал, не помогает

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

решил проблему, может кому пригодиться. В примерах, и в моём коде соответственно, было нарушенно главное правило с++ - при объевлении переменных или структур всё должно быть явно определено.

 

при инициализации часов не было задано rtc.RTC_AsynchPrediv = 0; в результате в RTC_AsynchPrediv был мусор, который то ноль.... то не ноль...

 

при заводе будильника нужно либо ВСЕ поля структуры RTC_AlarmTypeDef явно задавать. либо инитить эту структуру функцией RTC_AlarmStructInit().

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

было нарушенно главное правило с++ - при объевлении переменных или структур всё должно быть явно определено.

Бедные "мужики" что пишут на сях - "они то не знали" этого правила.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Бедные "мужики" что пишут на сях - "они то не знали" этого правила.

 

Ммм да, всегда удивляло - зачем писать на плюсах для МК?? Ну зачем :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ммм да, всегда удивляло - зачем писать на плюсах для МК?? Ну зачем :rolleyes:

Да писать можно хоть на чем. Главное нужно инициализировать все поля структуры перед использованием. В с++ структура оформляется в класс и в конструкторе делается инит. В си явно руками нужно инитить, или, чтоб код не захламлять, написать функию инициализации типа AlarmStructInit();

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ммм да, всегда удивляло - зачем писать на плюсах для МК?? Ну зачем :rolleyes:

Да тут скорее не в плюсах дело, а в многострадальных стм библиотеках. ОП взял какой то пример видимо "с забора", а не хотя бы с форума сайта разработчика камня или из рабочих демопроектов, коих на том же сайте разработчика выше крыши. Не работает. Вместо того чтобы читать вдумчиво документацию по регистрам RTC, а их там всего с десяток, и тщательно дебажить (обнимая и нежно лаская каждый бит каждого регистра) полез на форум "найдите мне ошибку". Увы и ах, хорошие библиотеки не делают разработчиков хорошими по умолчанию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ммм да, всегда удивляло - зачем писать на плюсах для МК?? Ну зачем

А потому что удобно... правда на С пишу, но пытаюсь С++ костылики вбивать. Типа глобальные переменные статиками объявляем и даем методы работы с ними, чтобы никто мне в модуле переменную извне просто так в обход моей логики не присвоил. В результате модули становятся более управляемые и легче пользуемыми другими пользователями.

 

Да и свои программы лучше, если мы не винегрет из кучи глобальных переменных делаем, а следуем логике объектов.

 

 

было нарушенно главное правило с++ - при объевлении переменных или структур всё должно быть явно определено.

Вообще хорошим тоном является задавать переменным значение перед их использованием.... И это не главное правило С++, а главное правило здравого смысла. Если бы значение полей структуры были бы не важны, то нафига было бы ее передавать? А если они важны, то какого лешего было их не задать?

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в результате в RTC_AsynchPrediv был мусор, который то ноль.... то не ноль...

ага, и причина в инициализации,

или в с++ :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...