今回はSTM32マイコンのRTC初期化の注意点について紹介します。STM32マイコンの多くはVBAT端子を備えており、CR2032といった電池と32.768kHzといった水晶発振子を取り付けることでマイコンのメイン電源OFFでも時刻を保持することができます。また、ファームウェアの書き換え等を行っても時刻情報を保持することができるため、非常に便利です。
基本的な使い方としてはSTM32CubeMXで自動生成されるコードそのままで問題ありませんが、頻繁にマイコンのON/OFFを繰り返す場合、RTC初期化HAL_RTC_Init関数で時刻の遅延が発生する厄介なバグがあります。STフォーラムでもディスカッション(リンク切れ?)されています。HAL_RTC_Init関数内のクロック設定で既にRTCの初期化が完了している場合に再度、クロックが設定される際にクロックが一時的に停止して遅延が発生します。電源投入後に外部から時刻を取得して電源ONのまま永続的に使用する場合には問題ありませんが、頻繁に電源をON、OFFする場合、初期化HAL_RTC_Init関数によって毎回、遅延が発生するため、時刻の遅れが無視できなくなります。
初期化HAL_RTC_Init関数によって発生する遅延を防止するため、既にRTC設定がされている場合に初期化HAL_RTC_Init関数を実行しないという分岐処理を入れることで遅延を回避する設定が必要です。
■修正前
static void MX_RTC_Init(void)
{
~~~
HAL_RTC_Init(&hrtc)!=HAL_OK)
{
Error_Handler();
}
~~~
}
■修正後
static void MX_RTC_Init(void)
{
~~~
if((RCC->BDCR & RCC_BDCR_RTCEN)==0)//RTC初期化されていない場合
{
if(HAL_RTC_Init(&hrtc)!=HAL_OK)
{
Error_Handler();
}
}
else//RTC初期化済の場合
{
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_BKP_CLK_ENABLE();//シリーズによっては不要
__HAL_RCC_RTC_ENABLE();
HAL_NVIC_SetPriority(RTC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(RTC_IRQn);
}
~~~
}
上記の設定で初期化HAL_RTC_Init関数によって発生する遅延を防止することが可能です。最近のSTM32マイコンのシリーズでは遅延がほぼ無視できますが、比較的歴史の長いF0やF1シリーズ等では遅延が1秒程度と大きいようです。今後のHALライブラリのバージョンアップで遅延防止の処理を入れ込んでほしいですね。