juvf 10 14 октября, 2015 Опубликовано 14 октября, 2015 (изменено) · Жалоба Проблемы с будильником на 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); } Изменено 14 октября, 2015 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 14 октября, 2015 Опубликовано 14 октября, 2015 · Жалоба Часы - это асинхронное оборудование для проца. Это описано в даташите. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 14 октября, 2015 Опубликовано 14 октября, 2015 · Жалоба Часы - это асинхронное оборудование для проца. Это описано в даташите. И? Почему RTC_GetAlarm() влияет на работу будильника? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 14 октября, 2015 Опубликовано 14 октября, 2015 · Жалоба Замените вашу RTC_GetAlarm() на любую другую процедуру или просто вызовите задержку. Думаю результат будет тот же. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 14 октября, 2015 Опубликовано 14 октября, 2015 · Жалоба Замените вашу RTC_GetAlarm() на любую другую процедуру или просто вызовите задержку. Думаю результат будет тот же. делал, не помогает Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 15 октября, 2015 Опубликовано 15 октября, 2015 · Жалоба решил проблему, может кому пригодиться. В примерах, и в моём коде соответственно, было нарушенно главное правило с++ - при объевлении переменных или структур всё должно быть явно определено. при инициализации часов не было задано rtc.RTC_AsynchPrediv = 0; в результате в RTC_AsynchPrediv был мусор, который то ноль.... то не ноль... при заводе будильника нужно либо ВСЕ поля структуры RTC_AlarmTypeDef явно задавать. либо инитить эту структуру функцией RTC_AlarmStructInit(). Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kostyan1 0 15 октября, 2015 Опубликовано 15 октября, 2015 · Жалоба было нарушенно главное правило с++ - при объевлении переменных или структур всё должно быть явно определено. Бедные "мужики" что пишут на сях - "они то не знали" этого правила. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 34 15 октября, 2015 Опубликовано 15 октября, 2015 · Жалоба Бедные "мужики" что пишут на сях - "они то не знали" этого правила. Ммм да, всегда удивляло - зачем писать на плюсах для МК?? Ну зачем :rolleyes: Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 15 октября, 2015 Опубликовано 15 октября, 2015 · Жалоба Ммм да, всегда удивляло - зачем писать на плюсах для МК?? Ну зачем :rolleyes: Да писать можно хоть на чем. Главное нужно инициализировать все поля структуры перед использованием. В с++ структура оформляется в класс и в конструкторе делается инит. В си явно руками нужно инитить, или, чтоб код не захламлять, написать функию инициализации типа AlarmStructInit(); Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kostyan1 0 15 октября, 2015 Опубликовано 15 октября, 2015 · Жалоба Ммм да, всегда удивляло - зачем писать на плюсах для МК?? Ну зачем :rolleyes: Да тут скорее не в плюсах дело, а в многострадальных стм библиотеках. ОП взял какой то пример видимо "с забора", а не хотя бы с форума сайта разработчика камня или из рабочих демопроектов, коих на том же сайте разработчика выше крыши. Не работает. Вместо того чтобы читать вдумчиво документацию по регистрам RTC, а их там всего с десяток, и тщательно дебажить (обнимая и нежно лаская каждый бит каждого регистра) полез на форум "найдите мне ошибку". Увы и ах, хорошие библиотеки не делают разработчиков хорошими по умолчанию. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 15 октября, 2015 Опубликовано 15 октября, 2015 · Жалоба Ммм да, всегда удивляло - зачем писать на плюсах для МК?? Ну зачем А потому что удобно... правда на С пишу, но пытаюсь С++ костылики вбивать. Типа глобальные переменные статиками объявляем и даем методы работы с ними, чтобы никто мне в модуле переменную извне просто так в обход моей логики не присвоил. В результате модули становятся более управляемые и легче пользуемыми другими пользователями. Да и свои программы лучше, если мы не винегрет из кучи глобальных переменных делаем, а следуем логике объектов. было нарушенно главное правило с++ - при объевлении переменных или структур всё должно быть явно определено. Вообще хорошим тоном является задавать переменным значение перед их использованием.... И это не главное правило С++, а главное правило здравого смысла. Если бы значение полей структуры были бы не важны, то нафига было бы ее передавать? А если они важны, то какого лешего было их не задать? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alag57 0 15 октября, 2015 Опубликовано 15 октября, 2015 · Жалоба в результате в RTC_AsynchPrediv был мусор, который то ноль.... то не ноль... ага, и причина в инициализации, или в с++ :) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться