STM32 RTC Alarm

Başlatan yldzelektronik, 13 Temmuz 2017, 09:00:42

yldzelektronik

Merhaba,

Stm32L100 disco üzerinde çalışıyorum ve rtc ile alarm kurmaya çalışıyorum.

RTC'yi sağlıklı bir şekilde çalıştırdığımı düşünüyorum.

init kodları;

/**
  * @brief RTC MSP Initialization
  *        This function configures the hardware resources used in this example
  * @param hrtc: RTC handle pointer
  * 
  * @note  Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select 
  *        the RTC clock source; in this case the Backup domain will be reset in  
  *        order to modify the RTC Clock source, as consequence RTC registers (including 
  *        the backup registers) and RCC_BDCR register are set to their reset values.
  *             
  * @retval None
  */
void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
{
   RCC_OscInitTypeDef        RCC_OscInitStruct = { 0 };
   RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct = { 0 };

#ifdef RTC_CLOCK_SOURCE_LSE
{
   RCC_OscInitStruct.LSEState 		= RCC_LSE_ON;
   RCC_OscInitStruct.LSEState 		= RCC_LSE_OFF;
   RCC_OscInitStruct.PLL.PLLState 	= RCC_PLL_NONE;

   PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
   RCC_OscInitStruct.OscillatorType =  RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
}
#elif defined ( RTC_CLOCK_SOURCE_LSI )
{
   RCC_OscInitStruct.LSIState 		= RCC_LSI_ON;
   RCC_OscInitStruct.LSEState 		= RCC_LSI_OFF;
   RCC_OscInitStruct.PLL.PLLState 	= RCC_PLL_NONE;
   RCC_OscInitStruct.OscillatorType =  RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;

   PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
}
#else
	#error Please select the RTC Clock source inside the rtc.h file
#endif /*RTC_CLOCK_SOURCE_LSE*/

   PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;

   if( HAL_RCC_OscConfig( &RCC_OscInitStruct ) != HAL_OK )
   {
      Error_Handler();
   }

   if( HAL_RCCEx_PeriphCLKConfig( &PeriphClkInitStruct ) != HAL_OK )
   {
      Error_Handler();
   }

   /*##-2- Enable RTC peripheral Clocks #######################################*/
   /* Enable RTC Clock */
   __HAL_RCC_RTC_ENABLE();

   /*##-4- Configure the NVIC for RTC Alarm ###################################*/
   HAL_NVIC_SetPriority( RTC_Alarm_IRQn, 0x03, 0 );
   HAL_NVIC_EnableIRQ( RTC_Alarm_IRQn );
}
/*-----------------------------------------------------------------------------*/

/**
* @brief RTC Initialization
*        This function configures the hardware resources used in this example
* @param hrtc: RTC handle pointer
*
* @note  Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
*        the RTC clock source; in this case the Backup domain will be reset in
*        order to modify the RTC Clock source, as consequence RTC registers (including
*        the backup registers) and RCC_BDCR register are set to their reset values.
*
* @retval None
*/
void HW_RTC_Init( void )
{
	/* Enable Power Clock */
	__HAL_RCC_PWR_CLK_ENABLE();

	/* Allow Access to RTC Backup domaine */
	HAL_PWR_EnableBkUpAccess();

   RtcHandle.Instance = RTC;

   /* Configure RTC prescaler and RTC data registers */
   /* RTC configured as follows:
   	- Hour Format    = Format 24
   	- Asynch Prediv  = Value according to source clock
   	- Synch Prediv   = Value according to source clock
   	- OutPut         = Output Disable
   	- OutPutPolarity = High Polarity
   	- OutPutType     = Open Drain
   */
   RtcHandle.Init.SynchPrediv    = RTC_SYNCH_PREDIV;
   RtcHandle.Init.HourFormat     = RTC_HOURFORMAT_24;
   RtcHandle.Init.AsynchPrediv   = RTC_ASYNCH_PREDIV;
   RtcHandle.Init.OutPut         = RTC_OUTPUT_DISABLE;
   RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
   RtcHandle.Init.OutPutType     = RTC_OUTPUT_TYPE_OPENDRAIN;

   if ( HAL_RTC_Init( &RtcHandle ) != HAL_OK )
   {
      /* Initialization Error */
      Error_Handler();
   }
}
/*-----------------------------------------------------------------------------*/


Ancak alarm konusunu anlamadım.Mesela bir aydan daha uzun süreli alarm kurabiliyor muyuz?Benim anladığım kurulamıyor.Mesela 20.10.2025 12:45:20 ye alarm kuramıyorum.Çünkü alarm registerleri sadece saat dakika saniye ve gün seçmenize müsade ediyor.

Diyelim ki ben hangi gün olduğuna bakmaksızın 12:25:35 e saat kurmak istiyorum.Hangi günde olduğu önemli değil.Her gün bu saatte alarm oluşsun.
Bir de her pazartesi 12:25:35 te alarm çalışsın.
Bir de her ayın 3 ünde 12:25:35 te alarm çalışsın.

Bu 3 senaryo için nasıl kurmamız gerekiyor?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

MrDarK

STM32L0 Referance dosyasının RTC alarm bölümünde yazdığına göre;

The ALRAF is set to 1 if the calendar subseconds, seconds, minutes, hours, date or day match the values programmed in the alarm registers RTC_ALRMASSR and RTC_ALRMAR


Söylediğin gibi alarm özelliği salise saniye dakika saat veya gün seçebilirsin. Zaten buraya yazılan değer RTC'nin registerları ile kıyaslanacak (maskeleneceği) değer oluyor. Ne zaman ki maskelenecek değerle eşit olursa o zaman alarm oluşturacaktır.

Hergün 12:25:35'e alarm kurmak istiyorsan ve henüz mcu'nun RTC'si 12:25:35'e ulaşmamış ise RTC'nin gün registerını okuyup örn bugün 13 temmuz alarm olarak gün kısmına 13 saat dakika saniye kısmına da 12:25:35 yazıp alarmı kurabilirsin. Alarm interrupt oluştuğunda ise interrupt içinde birsonraki gün için kurulacak alarmı gün kısmı 14 olacak saat dakika saniye kısmını da 12:25:35 yaptın mı bu şekilde gün fark etmeksizin her gün 12:25:35 alarm kurmuş olursun. Gün kısmını arttırken artık yıl ve ay günlerine dikkat etmen artışta yeterlidir. Örn Ayın 30 veya 31 çekmesi, Ayın son gününden ilk gününe geçişi ve Şubat ayı için artık yıl fonksiyonunu kullanabilirsin.

Her pazartesi 12:25:35 te alarm çalışsın. Mevcut ayda ulaşacağın ilk pazartesi gününü bulup sonrasında üstte anlatılan yöntem ile günü 7 birim arttırarak interrupt içinde alarmı tekrar kurmak.

Her ayın 3 ünde 12:25:35 te alarm çalışsın. Bu zaten alarm fonksiyonlarındaki saniye dakika saat veya gün formatının hepsini içerdiği için her ay bu işlem olacaktır. Bunun için ek birşey yapmana gerek yok
Picproje Eğitim Gönüllüleri ~ MrDarK

yldzelektronik

Yanıt için teşekkürler.


Benim AN4759, refence manual, data sheet ten anladığım kadarıyla aslında, her üç senaryo için de özel bir çabaya girmeme gerek yok.Yalnıza bahsettiğim modları doğru şekilde kurabilirsem, her senaryoyu gerçekleyebilirim.





Burada dediğine göre bu modları doğru kurabilirsen bu senaryolar çalışacaktır.Yanlış mı düşünüyorum?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

yldzelektronik

#3
Sorunum bu senaryolara göre alarm üretememekti.Ancak şuan API'yi daha iyi anladım.


HAL Lib ile gelen macrolar içinde alarm maskeleri için;
#define RTC_ALARMMASK_NONE                (0x00000000U)
#define RTC_ALARMMASK_DATEWEEKDAY         RTC_ALRMAR_MSK4
#define RTC_ALARMMASK_HOURS               RTC_ALRMAR_MSK3
#define RTC_ALARMMASK_MINUTES             RTC_ALRMAR_MSK2
#define RTC_ALARMMASK_SECONDS             RTC_ALRMAR_MSK1
#define RTC_ALARMMASK_ALL                 (0x80808080U)

şeklinde tanımlar var. Siz kodda alarm struct içindeki alarmmask üyesine bu macroları "|" (or/veya) ile koyarsanız, alarm için farklı filtreler koyabilirsiniz.Mesela güne saate dakikaya değil sadece saniyeyi eşleşirse alarm üret demek istiyorsanız;
Alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_HOURS | RTC_ALARMMASK_MINUTES;

demeniz gerekiyor. Her set ettiğiniz bir ignore olacak.Görmezden gelinecek.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.