3

STM32L151 の RTC アラーム割り込みに問題があります。プログラムで RTC アラーム割り込みを毎秒実行したいのですが、うまくいきません。私の主な機能:

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_IWDG_Init();
  MX_RTC_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();

  __HAL_RTC_ALARM_ENABLE_IT(&hrtc, RTC_IT_ALRA);

  while (1)
  {

  }
}

関数は RTC を設定します: MX_RTC_Init():

void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime;
  RTC_DateTypeDef sDate;
  RTC_AlarmTypeDef sAlarm;

  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  HAL_RTC_Init(&hrtc);

  sTime.Hours = 0x14;
  sTime.Minutes = 0;
  sTime.Seconds = 0;
  sTime.TimeFormat = RTC_HOURFORMAT12_AM;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  HAL_RTC_SetTime(&hrtc, &sTime, FORMAT_BCD);

  sDate.WeekDay = RTC_WEEKDAY_WEDNESDAY;
  sDate.Month = RTC_MONTH_AUGUST;
  sDate.Date = 0x24;
  sDate.Year = 0x16;

  HAL_RTC_SetDate(&hrtc, &sDate, FORMAT_BCD);

    /**Enable the Alarm A 
    */
  sAlarm.AlarmTime.Hours = 0;
  sAlarm.AlarmTime.Minutes = 0;
  sAlarm.AlarmTime.Seconds = 0;
  sAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM;
  sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  sAlarm.AlarmMask = RTC_ALARMMASK_SECONDS;
  sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  sAlarm.AlarmDateWeekDay = 1;
  sAlarm.Alarm = RTC_ALARM_A;
  HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BCD);

}

CubeMX を使用してプロジェクトを作成しました。何かアイデアやアドバイスはありますか?ありがとうございました

4

3 に答える 3

8

フィールドがマスクされている場合、アラームの日付をチェックするときに比較されません。したがって、SECONDS をマスクすると、DAY、HOUR、および MINUTE フィールドのみが比較されます。RTC で 1 秒の割り込みを実現する適切な方法は、すべてのアラーム マスクを使用することです。これは、この方法ではどのフィールドも比較されず、RTC が SECOND フィールドをインクリメントするとアラーム割り込みが生成されるためです。

sAlarm.AlarmMask = RTC_ALARMMASK_ALL;

また、これらすべてについては、ST がSTM32 F0、F2、F3、F4、および L1 シリーズの MCUアプリケーション ノートでハードウェア リアルタイム クロック (RTC) を使用する際に説明しています。

ここに画像の説明を入力

すべての割り込み後にアラームをリセットする必要がないため、これは非常に便利なソリューションです。

于 2016-09-18T11:04:17.463 に答える
1

設定sAlarm.AlarmMask = RTC_ALARMMASK_SECONDSしたように、時間の秒の値が一致するとRTCは割り込みを生成します。sAlarm.AlarmTime.Secondsこれは0あなたの場合です。したがって、コードをそのままにしておくと、ここで毎分割り込みが発生します。

毎秒割り込みが必要な場合は、割り込みハンドラーで次の秒でアラームを再度設定する必要があります。割り込みハンドラのコードは次のようになります。

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
    RTC_TimeTypeDef sTime;
    HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
    uint8_t next_second = sTime.Seconds++;
    if (next_second > 59) next_second = 0;

    RTC_AlarmTypeDef sAlarm;
    sAlarm.AlarmTime.Hours = 0;
    sAlarm.AlarmTime.Minutes = 0;
    sAlarm.AlarmTime.Seconds = RTC_ByteToBcd2(next_second);
    sAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM;
    sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
    sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
    sAlarm.AlarmMask = RTC_ALARMMASK_SECONDS;
    sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
    sAlarm.AlarmDateWeekDay = 1;
    sAlarm.Alarm = RTC_ALARM_A;
    HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BCD);
}

これが機能するには、RTC クロック (内部または外部 32K) が正しく設定されていることを確認する必要があります。

または、RTC のウェイクアップ機能を使用することもできます。より適切だと思います。または、メイン ループで、次のように を使用HAL_GetTickして、最後の処理から 1 秒が経過したことを確認できます。

static uint32_t last_second = 0;
void main(void)
{
   uint32_t current_second = HAL_GetTick();
   if (current_second - last_second > 1000)
   {
       last_second = current_second;

       //1 second has elapsed, do something
   }
}
于 2016-09-07T07:36:51.260 に答える