×

Внимание

Форум находится в режиме только для чтения.

stm32f100 RTC регистры ALARM

11 года 2 мес. назад #3982 от ddnik
ddnik создал тему: stm32f100 RTC регистры ALARM
Очередной потерянный день и даже ОЧЕНЬ внимательное изучение док не помогло...
Проект stm32f100 запускаю RTC от LSI, требуется независимый (в т.ч. от кратковременной потери питания или рестарта) отсчет интервала времени.
Как красивый вариант ставить на alarm.

для простоты написал из примера на библиотеке.
  PWR_BackupAccessCmd(ENABLE);
  BKP_DeInit();
  RCC_LSICmd(ENABLE);
  while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)  {}
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
  RCC_RTCCLKCmd(ENABLE);
  RTC_WaitForSynchro();
  RTC_WaitForLastTask();

  /* Set RTC prescaler: set RTC period to 0.1sec */
 RTC_SetPrescaler(4000-1); /* RTC period = RTCCLK/RTC_PR = (40.000 KHz)/(3999+1) */
 RTC_WaitForLastTask();

  RTC_SetCounter(0);
  RTC_WaitForLastTask();

  
  RTC_SetAlarm( 5000);
  RTC_WaitForLastTask();


Все работает только в регистрах RTC->ALRL, ALRL чисто... :(
Повторяю те-же действия руками отладчиком - есть значения в регистрах!

Перепробовал - 
- писать все регистры вместе 
RTC->CRL |= CRL_CNF_Set;
  
RTC->PRLH = 0;
RTC->PRLL = 3999;

RTC->CNTH=1;
RTC->CNTL=0x1000;

RTC->ALRH = 2;
RTC->ALRL = 2;

RTC->CRL &= CRL_CNF_Reset;
RTC_WaitForLastTask();

Прескалер есть , счетчик есть , аларм ...(пипипи)

Я, конечно, сделал занесение его значения в бекап регистр и программно проверяю когда закончится интервал - но интересно почему не работает?
Вроде в инете вижу примеры использования - Может это из-за LSI?
11 года 2 мес. назад #3988 от Денис Ягов
Денис Ягов ответил в теме Re: stm32f100 RTC регистры ALARM
Давайте для начала обратимся к мануалу (RM0041).
Описание регистров ALARM:
"
When the programmable counter reaches the 32-bit value stored in the RTC_ALR register,
RTC alarm register high (RTC_ALRH / RTC_ALRL)
an alarm is triggered and the RTC_alarmIT interrupt request is generated. This register is
write-protected by the RTOFF bit in the RTC_CR register, and a write operation is allowed if
the RTOFF value is ‘1’.
"
Самое интересное здесь:
 "Этот регистр с защитой от записи посредством бита RTOFF, запись возможна, когда его значение - 1"

Смотрим этот бит в регистре RTC->CRL:

" With this bit the RTC reports the status of the last write operation performed on its registers,
indicating if it has been completed or not. If its value is ‘0’ then it is not possible to write to any
of the RTC registers. This bit is read only.
0: Last write operation on RTC registers is still ongoing.
1: Last write operation on RTC registers terminated.
RTC operation OFF
RTOFF: "
Это регистр статуса (только для чтения), так вот, пока он равен нулю - запись невозможна.

А если обратиться к функциям стандартной библиотеки, то вот:
[iurl=http://forum.promelec.ru/group__RTC__Private__Functions.html#gaa0a406ef860d5231748c5f0d82673036]00207 [/iurl] void [iurl=http://forum.promelec.ru/group__RTC__Exported__Functions.html#gaa0a406ef860d5231748c5f0d82673036]RTC_WaitForLastTask [/iurl](void)
00208 {
00209   /* Loop until RTOFF flag is set */
00210   while ((
[iurl=http://forum.promelec.ru/group__Peripheral__declaration.html#ga5359a088f5d8b20ce74d920e46059304]RTC [/iurl]->CRL & [iurl=http://forum.promelec.ru/group__RTC__interrupts__flags.html#ga203dcbb991497e4d0e6722815f6db942]RTC_FLAG_RTOFF [/iurl]) == (uint16_t) [iurl=http://forum.promelec.ru/group__Exported__types.html#gga89136caac2e14c55151f527ac02daaffa589b7d94a3d91d145720e2fed0eb3a05]RESET [/iurl])
00211   {
00212   }
00213 }


Функция до очередной записи ждёт пока оный флаг даст добро.  
8)
11 года 2 мес. назад #3989 от Денис Ягов
Денис Ягов ответил в теме Re: stm32f100 RTC регистры ALARM
Ну и вот этого не видно в вашем коде:
RCC_APB1PeriphClockCmd ( RCC_APB1Periph_PWR | RCC_APB1Periph_BKP , ENABLE );
11 года 2 мес. назад #3993 от ddnik
ddnik ответил в теме Re: stm32f100 RTC регистры ALARM
Спасибо за ответ - но
- RTC_FLAF_RTOFF я конечно проверяю (первый вариант так и написан)
вот это кусочек:
//

  RTC_SetPrescaler(4000-1); /* RTC period = RTCCLK/RTC_PR = (40.000 KHz)/(3999+1) */
  RTC_WaitForLastTask();
  RTC_SetCounter(0);
  RTC_WaitForLastTask();
  RTC_SetAlarm( 5000);
  RTC_WaitForLastTask();
//

Разрешение клоков для RCC_APB1Periph_PWR и RCC_APB1Periph_BKP в тексте присутствуют (я обычно все клоки включаю в самом начале одновременно).

Мало того делал пошаговую трассировку (даже на уровне кода) в момент занесения значений в alarm регистры все нужные (описанные в доке) флаги в норме! а занесения как небло так и нет. :(
Что-то мешает - есть две гипотезы (проверить пока не могу - макет разобран временно) либо применение LSI а не LSE или отсутствие разрешение прерывания от alarm (не ставил мне это не надо было)

11 года 1 мес. назад #3995 от ddnik
ddnik ответил в теме Re: stm32f100 RTC регистры ALARM
Проверил гипотезы - без результата
Вот весь код с запуска для Дискавери F100

Тут уже и LSE и прерывание разрешено а результат тот-же.

//
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR+RCC_APB1Periph_USART2+RCC_APB1Periph_BKP, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA+RCC_APB2Periph_GPIOB+RCC_APB2Periph_AFIO, ENABLE);

  PWR_BackupAccessCmd(ENABLE);
  RCC_LSEConfig(RCC_LSE_ON);
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)  {}

  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
  RCC_RTCCLKCmd(ENABLE);
  RTC_WaitForSynchro();
  RTC_WaitForLastTask();
  RTC_ITConfig(RTC_IT_ALR, ENABLE);
  RTC_WaitForLastTask();

  RTC_SetPrescaler(4000-1); /* RTC period = RTCCLK/RTC_PR = (40.000 KHz)/(3999+1) */
  RTC_WaitForLastTask();
 
 RTC_SetCounter(0x110011);
 RTC_WaitForLastTask();
  RTC_WaitForSynchro();

  RTC_SetAlarm( 0x110911);
  RTC_WaitForLastTask();
  RTC_WaitForSynchro();


Вот состояние регистров RTC после данной процедуры:

11 года 1 мес. назад #3996 от Денис Ягов
Денис Ягов ответил в теме Re: stm32f100 RTC регистры ALARM
Добрый день.
В общем, проверил я на Primer-2 (отладка на базе STM32F103VET6).

У STM32F100 и 103 -одинаковая периферия RTC... Под боком, оказалась только отладка с STM32F103....

Рабочий код:
void RTC_Configuration(void)
{
  /* Enable PWR and BKP clocks */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  /* Allow access to BKP Domain */
  PWR_BackupAccessCmd(ENABLE);

  /* Reset Backup Domain */
  BKP_DeInit();

  /* Enable LSE */
  RCC_LSEConfig(RCC_LSE_ON);
  /* Wait till LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {}

  /* Select LSE as RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  /* Enable RTC Clock */
  RCC_RTCCLKCmd(ENABLE);

  /* Wait for RTC registers synchronization */
  RTC_WaitForSynchro();

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();

  /* Enable the RTC Second */
  RTC_ITConfig(RTC_IT_SEC, ENABLE);

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();

  /* Set RTC prescaler: set RTC period to 1sec */
  RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
 
  RTC_SetAlarm (0xFEDC);
 
  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
 
  RTC_SetAlarm (0x1000);

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
 
  RTC_SetAlarm (0x2000);
}


Значения регистров меняются.
Проект под среду Ride7 - во вложении
+ скан объективного контроля.

Пока не могу сказать почему у вас не работает.
Время создания страницы: 0.099 секунд
Работает на Kunena форум