LoginSignup
1

More than 5 years have passed since last update.

posted at

updated at

[STM32] PVDによるマイコン電源電圧の監視

この記事は、高知工科大 Advent Calendar 2017の12日目の記事です。

はじめに

Mbedからマイコンを始めた私ですが、最近はSTM32を少しずつ勉強しています。
そんな中で便利そうだなと思った機能について、HALの日本語記事があまりなさそうだったので紹介します。

概要

STM32 HALによる、PVD(Programmable Voltage Detection: プログラマブル電圧検出器)を用いたマイコン電源電圧の監視。

PVDについて

ざっくりいえば、電源電圧が設定した値を 下回った or/and 上回った 場合にイベントを発生させる機能です。

  • マイコンのVDD電圧を監視
  • イベント発生時の動作をカスタマイズできる
  • 2.2-2.9Vの範囲でしきい値を設定可能

4531_20171208_STM32F303_リファレン.png

API

構造体

PWR_PVDTypeDef

- PVDLevel
PWR_PVDLEVEL_0   (2.2V)
PWR_PVDLEVEL_1   (2.3V)
PWR_PVDLEVEL_2   (2.4V)
PWR_PVDLEVEL_3   (2.5V)
PWR_PVDLEVEL_4   (2.6V)
PWR_PVDLEVEL_5   (2.7V)
PWR_PVDLEVEL_6   (2.8V)
PWR_PVDLEVEL_7   (2.9V)

- Mode
PWR_PVD_MODE_NORMAL
PWR_PVD_MODE_IT_RISING
PWR_PVD_MODE_IT_FALLING
PWR_PVD_MODE_IT_RISING_FALLING
PWR_PVD_MODE_EVENT_RISING
PWR_PVD_MODE_EVENT_FALLING
PWR_PVD_MODE_EVENT_RISING_FALLING

関数

HAL_PWR_ConfigPVD(PWR_PVDTypeDef* sConfigPVD)
PWR_CRレジスタに設定を書き込む

HAL_PWR_EnablePVD(void)
PVDの有効化

HAL_PWR_DisablePVD(void)
PVDの無効化

HAL_PWR_PVDCallback(void)
コールバック関数

PVDの使い方

今回は割り込みを用いて、電圧が下回っている場合にLEDが点灯するようにしました。

はじめに、CubeMXでPVD割り込みを有効にします。
設定は、Configuration > System > NVIC で現れるダイアログの、NVICタブにあるPVD interrupt through EXTI line 16の右横に:white_check_mark:チェックを入れることで有効になります。
4535_20171212__Unknown_LI.jpg

コードを生成して、処理を書き加えます。

こんなかんじになりました。CubeMXの初期化関数風に書いてみましたがどうでしょう。

#define PWR_CSR_PVDO 0x04 /* CSR PVDO bit */

static void PVD_Init(void) {

    PWR_PVDTypeDef PVD_InitStruct;

    /* PWR Interface Clock Enable */
    __HAL_RCC_PWR_CLK_ENABLE();

    /* Configure PVD */
    PVD_InitStruct.PVDLevel = PWR_PVDLEVEL_7; // 2.9V
    PVD_InitStruct.Mode = PWR_PVD_MODE_IT_RISING_FALLING;
    HAL_PWR_ConfigPVD(&PVD_InitStruct);

    HAL_PWR_EnablePVD();
}

void HAL_PWR_PVDCallback() {
    /* Indicate PVDO bit Status */
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, (PWR->CSR & PWR_CSR_PVDO));
}

__HAL_RCC_PWR_CLK_ENABLE()でPWRインターフェイスにクロックを供給します。
私はこれが必要なことを知らず、しばらく悩みました:innocent:
クロックを供給しないと、設定レジスタに書き込みができません。

構造体の各フィールドに設定する値を入力し、HAL_PWR_PVDCallbackでレジスタに設定を書き込みます。

最後に、HAL_PWR_EnablePVDでPVDを有効化します。

今回は、ModeをPWR_PVD_MODE_IT_RISING_FALLINGとしているので、電圧がしきい値を下回った場合と上回った場合に割り込みが起こります。
コールバック関数内では、PVDOレジスタを読み、レジスタの値をそのままLEDに出力しています。


正常に設定できているかを確認するためには、プログラムを起動してデバッガでレジスタを覗きます。

まず、PWRにクロックが供給されているかを確認します。
APB1ペリフェラルクロック有効レジスタ(RCC > APB1ENR)内のPWREN[bit 28]が1となっていればOKです。

4534_20171212_workspace_v2.0 (2).png

次に、PVDの設定を確認します。
電圧制御レジスタ(PWR > CR)内のPVDE[bit 4]が1となっていればPVDが有効です。また、PLS[bit 7-5]はPVDのしきい値電圧設定ビットで、000から111の間でそれぞれ2.2Vから2.9Vのしきい値電圧に対応しています。今回は2.9Vに設定しているので、111となっていれば正常です。

4533_20171212_workspace_v2.0_LI.jpg

動かしてみた

条件

  • STM32F303RET6
  • STM32CubeF3 1.9.0
  • SW4STM32 + OpenOCD
  • しきい値 : 2.9V
  • 立ち上がり/立ち下がり割り込み

マイコンを載せた基板に安定化電源から電源を供給し、マルチメータでマイコン電源電圧を確認しながら安定化電源の電圧を上げ下げしてみました。

結果

しきい値の上から徐々に電圧を下げていくと、2.85VでLEDが点灯。その後、徐々に電圧を上げていくと、2.90VでLEDが消灯しました。

考察

リファレンスマニュアルには 100mVのヒステリシス とありますが、実際のヒステリシスは50mV程度でした。HALのドキュメントには PVD threshold around 2.9 V と書いてあるので、PVDは正確な電圧を検知するものではないということなのでしょう。
4531_20171208_STM32F303_リファレン.png

他のモードについて

ソースコード中のModeをNormal、Eventにして、他の条件は変えずに同様に実験をしてみました。

Normalはコールバックが発生しなかったので、割り込みではなくポーリングしたい場合に使用するのかな?
また、Eventもコールバックが発生しませんでした。Eventはなんのためのモードなのでしょう…(誰か教えて)

まとめ

PVDによる電圧監視を実装できた。
HALへの理解を深めた。

あとがき

今年はAdvent Calendarの期日に間に合わせることができました!:confetti_ball:
公式ドキュメントの絶妙な不親切さに翻弄されながらも、動かせるところまで持っていけたので良かったです。

実は、本当にやりたかったネタは別にあったりするのですが、、、いい具合に煮詰まったら投稿したいと思います。

誤字脱字、内容の間違い等あればご指摘いただければありがたいです。

参考資料

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
1