реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> RTC STM32L151 прерывание, У меня получилось ! Выкладываю код !
MiklPolikov
сообщение Jun 2 2012, 14:21
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Три дня ломал мозг над RTC в STM32L151 , и наконец у меня всё получилось !
Выкладываю свой код для Keil, т.к. других тем про RTC тут не нашёл.

RTC какой-то очень привередлевый. Ньюансы вроде того что в регистр PRER нужно сделать ровно две записи , причём сначала младшие биты потом старшие,
то что регистры с датой и временем можно записать только таким же образом , то что системная частота должна быть в более чем 7 раз больше частоты таймера
в документации написаны.
Почему в начале обязательно нужно сбросить настройки таймера которые и так сброшены при запуске МК , а без этого таймер инициализируется и работает но прерывания не происходит , я так и не понял.



Код
////////////////////////////// Настраиваем RTC часы/////////////////////////////////////
void RTC_INIT(system_time__ system_time)
{                                              
   int RTC_DR_MASK=0;
  int RTC_TR_MASK=0;
  
  RCC->CSR|=RCC_CSR_RTCRST;    //
  RCC->CSR&=~RCC_CSR_RTCRST; // сбросили настройки RTC

  RCC->APB1ENR |= RCC_APB1ENR_PWREN;
  PWR->CR |= PWR_CR_DBP;

  RCC->CSR |= RCC_CSR_LSEON;      //включили генератор LSE 32768
  while(!(RCC->CSR & RCC_CSR_LSERDY)){} //ждём пока включится
  
  RCC->CSR|=RCC_CSR_RTCEN;    //включили RTC

  RCC->CSR|=RCC_CSR_RTCSEL_LSE; // подаём тактовую частоту LSE на RTC

  RTC->WRP=0xCA;
  RTC->WRP=0x53;  //отключаем защиту

  if(!(RTC->ISR & RTC_ISR_INITF))//если таймер ещё не в режиме инициализации
  {
     RTC->ISR|=RTC_ISR_INIT;
     while(!(RTC->ISR & RTC_ISR_INITF)){}//входим в режим инициализации
  }

  RTC->PRER=255;
  RTC->PRER|=(127<<16);// устанавливаем  делители, обязательно двумя записями.
  
  RTC_TR_MASK|=(system_time.minute%10)<<8; // единицы минут
  RTC_TR_MASK|=(system_time.minute/10)<<12; //есятки минут
  RTC_TR_MASK|=(system_time.hour%10)<<16; //единицы часов
  RTC_TR_MASK|=(system_time.hour/10)<<20;    //десятки часов
  
  RTC->TR=RTC_TR_MASK; //устанавливаем время
    
  RTC_DR_MASK|=(system_time.day%10)<<0; //единицы дней
  RTC_DR_MASK|=(system_time.day/10)<<4; // десятки дней
  RTC_DR_MASK|=(system_time.months%10)<<8; //единицы месяцев
  RTC_DR_MASK|=(system_time.months/10)<<12; // десятки месяцев
  RTC_DR_MASK|=((system_time.year-2000)%10)<<16;  //единицы годов
  RTC_DR_MASK|=((system_time.year-2000)/10)<<20;  //десятки годов
  
  RTC->DR=RTC_DR_MASK; //устанавливаем дату

  RTC->CR|=RTC_CR_WUTE; //    включили wakup таймер
  RTC->WUTR=0xFFFF;
  RTC->CR&=~RTC_CR_WUCKSEL_1;
  RTC->CR&=~RTC_CR_WUCKSEL_1;
  RTC->CR&=~RTC_CR_WUCKSEL_2; // выбрали для waikup таймера частоту LSE/16
  RTC->CR|=RTC_CR_WUTIE; //    разрешили прерывание от wakup таймера
  
  EXTI->IMR |= (1<<20);         //  прерывание  EXTI line 20
  EXTI->RTSR |= (1<<20);     //по переднему фронту
          
  NVIC_SetPriority(RTC_WKUP_IRQn, 5);
  NVIC_EnableIRQ(RTC_WKUP_IRQn);

  RTC->ISR&=~RTC_ISR_INIT; // выходим из режима инициализации.
}




////////////////////////прерывание wakup  от RTC////////////////////////////////
void RTC_WKUP_IRQHandler(void)
{
   EXTI->PR|=(1<<20); //
  RTC->ISR&=~RTC_ISR_WUTF; //сбрасываем флаг прерывания

  return;
}


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
Apparatchik
сообщение Dec 24 2012, 15:25
Сообщение #2





Группа: Участник
Сообщений: 8
Регистрация: 4-08-12
Пользователь №: 73 014



А у меня никак не выходит. Контроллер STM32L152RBT6 виснет (перестает срабатывать прерывание от SysTick). Что-то я упустил.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Dec 25 2012, 08:49
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Цитата(Apparatchik @ Dec 24 2012, 17:25) *
Контроллер STM32L152RBT6 виснет (перестает срабатывать прерывание от SysTick). Что-то я упустил.


С данным процом я не работал, но пытался сделать такое на AT91SAM7S256 (ядро ARM7TDMI). Там есть PIT (аналог Вашего SysTick) и RTC. Когда пытался включить оба разом - всё висло.
Оказалось, что оба они, грубо говоря, висят на одном прерывании (как я понял, у меня архитектура такая), и использовать их можно только по одному - или тот или другой. Может и я в чём-то неправ, не знаю.

В итоге сделал часики на отдельном таймере общего назначения biggrin.gif . Работает как часы laughing.gif .
Может и у Вас что-то родственное.


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
Apparatchik
сообщение Dec 26 2012, 15:44
Сообщение #4





Группа: Участник
Сообщений: 8
Регистрация: 4-08-12
Пользователь №: 73 014



Если обработчик прерывания один на несколько событий, то нужно проверять флаги в регистрах статуса всех событий, которые могут вызвать этот обработчик, выполнять нужное действия в зависимости от того, кто вызвал и сбрасывать флаг. По крайней мере так я понял по поводу STM32.

Часы я вроде запустил, но вроде в даташите упоминалось что они продолжают идти после системного зброса. Апаратный сброс кнопкой RESET должен их сбрасывать? у меня они идут сначала.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 00:05
Рейтинг@Mail.ru


Страница сгенерированна за 0.13082 секунд с 7
ELECTRONIX ©2004-2016