NUCLEO-F302R8 BEMFのAD変換
前回、とりあえずモータを回転させるプログラムを作成しました。
今回はモータから発生するBEMF(Back ElectroMotive Force)を測定するためのAD変換プログラムを作成します。
使用している評価ボードに誘導起電圧を検出する回路がついており、その出力がマイコンのポートに繋がっています。
そのポートでAD変換の設定を行うことで、モータから発生する誘導起電圧を測定できます。
BEMFについて
図のようにモータ回転子の磁石が各相のコイルに近づく、離れることで誘導起電圧が発生します。これがBEMFです。
磁石が離れるときに中性点から外向きの電圧が発生します。AD変換で使用するポートから見て正の電圧になり、AD変換して測定できます。
リファレンス
- マイコンのRM(リファレンスマニュアル)
- マイコンのDS(データシート)
- DS: https://www.st.com/resource/en/datasheet/stm32f302r6.pdf
- マイコンのPin配置やポートの機能一覧、HW特性
- マイコンのPM(プログラミングマニュアル)
- モータドライバーボードの製品シート
- IHM: https://www.st.com/resource/en/data_brief/x-nucleo-ihm07m1.pdf
- マイコンとの接続が分かる回路図
HW構成
モータドライバーボードの製品シートに記載されているBEMFの回路図です。
- BEMFは10KΩと2.2KΩの抵抗により分圧されます。2.2KΩはGPIO_BEMF(PC9)をHighにすることで無効化できます。
- BEMFはマイコンポートのPC3,PB0,PA7に接続されています。
- AD変換のリファレンス電圧はVref-: 0V, Vref+: 3.3Vです。
IHM
Page4 BEMF detection - six step
Page5 BEMF six-step
ポート
- BEMF 誘導起電圧
- BEMFのAD変換で使用するポートです。
- BEMF1: PC3 ADC1_IN9: U相の誘導起電圧
- BEMF2: PB0 ADC1_IN11: V相の誘導起電圧
- BEMF3: PA7 ADC1_IN15: W相の誘導起電圧
- ポートとAD変換チャネルの対応はDS: Table 13. STM32F302x6/8 pin definitionsを参照
- BEMFのAD変換で使用するポートです。
- 相電流
- 今回は使用していませんが、モータの相電流を検出する回路も付いています。メモとして記載しておきます。
- PhA: PA0 ADC_IN1: U相の電流
- PhB: PC1 ADC_IN7: V相の電流
- PhC: PC0 ADC_IN6: W相の電流
- 今回は使用していませんが、モータの相電流を検出する回路も付いています。メモとして記載しておきます。
AD変換の手順
- 初期化
- ADCクロックの有効化
- GPIOをADCモードに設定
- 電圧レギュレータ(ADVREGEN)の有効化
- チャネルのモード設定
- キャリブレーション
- ADCの有効化
- 変換処理
- サンプリング時間と分解能の設定
- 変換シーケンスの設定
- AD変換モードの設定
- AD変換開始/終了
- AD変換結果読み出し
初期化
ADCクロックの有効化
ADCとAD変換ポートとして使用するGPIOのクロックを有効にします。
ADCのクロックはデュアルクロックドメインアーキテクチャとなっており、二つのクロックを使用します。
- ADCがAHBとの通信で使用するクロック。AHBバスと同じクロックになる。
- AD変換で使用するクロック。以下のどちらかを設定できる。
- Asynchronous clock mode: AHBバスと異なるクロック
- Synchronous clock mode: AHBバスと同じクロック
- RCC_AHBENR
- ADC12EN: 1: ADC1 and ADC2 clock enabled
- ADCがAHBとの通信で使用するクロックを有効。
- GPIOA: 1b: I/O port A clock enabled
- GPIOB: 1b: I/O port B clock enabled
- GPIOC: 1b: I/O port C clock enabled
- AD変換ポートとして使用するGPIOA,B,Cのクロックを有効
- ADC12EN: 1: ADC1 and ADC2 clock enabled
さらに、AD変換で使用するクロックを設定します。今回はAHBバスと同じクロックを使用します。
- ADCx_CCR
- CKMODE: 02b: HCLK/2 (Synchronous clock mode)
- AHBと同じクロックであるHCLKを2分周したクロックを使用します。
- 01b: HCLK/1は今の設定では使用できません。HPRE(AHB prescaler)を0b: 分周なしで使用しているからです。RMのCKMODEの説明から、Synchronous clock modeではSYSCLK(システムクロック)の半分以下の周波数に下げる必要がありそうです。
- CKMODE: 02b: CK_ADCx (Asynchronous clock mode)で使用するときの分周を設定するレジスタがRCC_CFGR2です。今回は使いません。メモです。
- CKMODE: 02b: HCLK/2 (Synchronous clock mode)
RM: 9.2.8 ADC clock
RM: 15.3.3 Clocks
GPIOをADCモードに設定
AD変換するBEMFを入力するGPIOを設定します。
- GPIOx_MODER
- GPIOC_MODER3: 11b: Analog mode
- BEMF1で使用するポートをAnalog modeに設定します。
- GPIOB_MODER0: 11b: Analog mode
- BEMF2で使用するポートをAnalog modeに設定します。
- GPIOA_MODER7: 11b: Analog mode
- BEMF3で使用するポートをAnalog modeに設定します。
- GPIOC_MODER3: 11b: Analog mode
電圧レギュレータ(ADVREGEN)の有効化
電圧レギュレータを有効にします。
- ADCx_CR
- ADVREGEN
- 10b: ADC Voltage regulator disabled
- 電圧レギュレータが無効の状態です。
- リセット時もこの状態です。
- 00b: Intermediate state
- 有効/無効を切り替える場合は一度この状態にします。
- 01b: ADC Voltage regulator enabled
- 電圧レギュレータが有効の状態です。
- ただし、有効化してすぐに電圧レギュレータは動作できず、TADCVREG_STUP(約10us)待つ必要があります。
- 10b: ADC Voltage regulator disabled
- ADVREGEN
RM: 15.3.6 ADC voltage regulator (ADVREGEN)
チャネルのモード設定
以下の二つのモードがあります。今回はシングルエンドモードに設定します。
- シングルエンドモード
- 入力電圧(ADC_INi)とV-refの差が変換される。iはチャネル番号。
- 単純にAD変換したい場合はこのモード。
- ディファレンシャルモード
- 入力電圧(ADC_INi)と入力電圧(ADC_INi+1)の差が変換される。
- 差動電圧を変換したい場合はこのモード。
- ADCx_DIFSEL
- DIFSEL: all 0b: single ended mode
- 全てのチャネルをシングルエンドモードに設定します。
- DIFSEL: all 0b: single ended mode
15.3.7 Single-ended and differential input channels
キャリブレーション
リセット時にマイコン内の部品による誤差を補正するためにキャリブレーションを行います。キャリブレーションが完了するまでADCを有効にできません。
前項のシングルエンドとディファレンシャルでキャリブレーションが異なります。キャリブレーション前にADCALDIFでどちらのキャリブレーションを行うか設定します。
- ADCx_CR
- ADCALDIF: 0b: Writing ADCAL will launch a calibration in Single-ended inputs Mode.
- キャリブレーションをシングルエンドモードで行います。
- ADCALDIF: 0b: Writing ADCAL will launch a calibration in Single-ended inputs Mode.
ADCALに1を書き込むとキャリブレーションが開始します。ただし、ADCが無効の状態(ADEN=0)でキャリブレーションを開始しないといけません。
ADCALが0になるとキャリブレーションが完了です。
- ADCx_CR
- ADCAL: 1b: Write 1 to calibrate the ADC. Read at 1 means that a calibration in progress
- キャリブレーション中です。
- ADCAL: 0b: Calibration complete
- キャリブレーション完了です。
- ADCAL: 1b: Write 1 to calibrate the ADC. Read at 1 means that a calibration in progress
キャリブレ-ションされたデータは以下のレジスタに保存されます。これをNVMに保存して、次のリセットからはNVMに保存したデータを以下のレジスタに書き込むことでキャリブレーションすることが可能です。
- ADCx_CALFACT
- CALFACT_S: Calibration Factors In Single-Ended mode
- CALFACT_D: Calibration Factors in differential mode
15.3.8 Calibration (ADCAL, ADCALDIF, ADCx_CALFACT)
ADCの有効化
ADCを有効にすることでAD変換ができるようになります。
ADENに1を設定するとADCの有効化がスタートします。ADRDYが1になるとADCの有効化が完了して、AD変換ができる状態になります。
- ADCx_CR
- ADEN: Write 1 to enable the ADC.
- 1をセットすると、ADCが有効になります。
- ADEN: Write 1 to enable the ADC.
- ADCx_ISR
- ADRDY
- ADRDYが1になるとAD変換の準備が完了となります。ADRDYはソフトウェアで0に戻す必要があります。ADRDYが1になるまで待ち、1になったらADRDYを0にセットします。
- ADRDY
15.3.9 ADC on-off control (ADEN, ADDIS, ADRDY)
変換処理
これ以降はADCが有効になってから行う必要があります。
RM: 15.3.10 Constraints when writing the ADC control bits
AD変換開始までの設定はスキップ可能です。
サンプリング時間と分解能の設定
AD変換のサンプリング時間と分解能を設定します。
今回はデフォルトの設定で使用します。
- サンプリング時間 Tsmpl: 1.5 ADC clock cycles
- 分解能: 12bit
- 1bitの電圧値: (Vref+ - Vref-) / 2^12 = 3.3 / 4096 = 0.8[mV]
- 量子化時間(12bit) Tsar: 12.5 ADC clock cycles
- AD変換の時間: (Tsmpl + Tsar) = 14 ADC clock cycles
RM: 15.3.16 Timing
- ADCx_SMPR1
- SMP: 000b: 1.5 ADC clock cycles
- デフォルトの設定です。今後調整するかもしれません。
- SMP: 000b: 1.5 ADC clock cycles
- ADCx_CFGR
- RES: 00b: 12-bit
- デフォルトの設定です。今後調整するかもしれません。
- RES: 00b: 12-bit
・サンプリング時間と外部入力インピーダンス
外部入力インピーダンスが高いとサンプリング時間を長くする必要があります。外部入力インピーダンスはAD変換される電圧を出力する回路の出力インピーダンスです。
DS: Table 67. Maximum ADC RAIN
RM: 15.3.12 Channel-wise programmable sampling time (SMPR1, SMPR2)
・分解能
分解能を下げることでAD変換の時間を短くすることができます。
RM: 15.3.22 Programmable resolution (RES) - fast conversion mode
変換シーケンスの設定
AD変換を行うチャネルを選択してシーケンスを作成します。
AD変換を実行すると、シーケンス内のチャネルが順番にAD変換されます。
- ADCx_SQR1
- L(Regular channel sequence length): 0000b: 1 conversion
- シーケンスで変換するチャネルの数を設定します。今回は0を設定して、1回のAD変換トリガで1チャネルだけ変換します。
- SQ1: チャネル番号(0x09: IN9 or 0x0B: IN11 or 0x0F: IN15)
- シーケンスの1番目で変換するチャネルを設定します。AD変換毎にチャネルを設定します。
- 定義外のチャネル番号(1~18以外、0も定義外)を使用しないように。
- L(Regular channel sequence length): 0000b: 1 conversion
AD変換モードの設定
AD変換のモードが2種類あり、選択できます。
- Single conversion mode
- 1つのAD変換のトリガで1度だけAD変換を行います。
- 必要な時だけAD変換を行うので、Continuous conversion modeより消費電力が小さいです。
- Continuous conversion mode
- 1つのAD変換のトリガでAD変換を継続して行います。
- 常にAD変換を行うので、Single conversion modeより消費電力を大きくなります。
今回はSingle conversion modeにします。
- ADCx_CFGR
- CONT: 0b: Single conversion mode
- デフォルトのままで使用します。
- CONT: 0b: Single conversion mode
RM: 15.3.13 Single conversion mode (CONT=0) RM: 15.3.14 Continuous conversion mode (CONT=1)
AD変換開始/終了
AD変換を開始するときはADSTARTに1を設定します。
全てのチャネルのAD変換が完了するとADSTARTが0になります。逆に言えば、ADSTARTが1の場合は何れかのチャネルがAD変換中です。
ただし、Continuous conversion modeの場合は自動でADSTARTが0になりません。ADSTPを設定してAD変換を止めます。
- ADCx_CR
- ADSTART
- 0b: No ADC regular conversion is ongoing
- 1b: ADC regular conversion is ongoing
- ADSTP
- 0b: No ADC stop regular conversion command ongoing
- 1b: ADC stop regular conversion command ongoing
- 今回は使用していないです。メモです。
- ADSTART
AD変換の結果はADCx_DRに格納されます。このレジスタはADCに一つで、各チャネルで共有します。つまり、次のAD変換が完了するまでにAD変換結果を読み出す必要があります。
- ADCx_DR
変換が完了したことを確認する方法には二つの案があります。
- EOCは割込みを使用します。EOCの割込みはEOCが1になったら発生します。割込みでAD変換結果の読み出しを行います。
- ループでEOCやADSTARTを参照して、完了を示す値になるまで待ちます。EOCやADSTARTをビジーループになりますが、AD変換は数10μsで完了するので、許容できるなら実装が簡単な方法です。
EOCのレジスタは以下になります。今回はループでEOCが完了になるまで待ちます。EOCはDRレジスタを読み出すとマイコンがクリアします。
- ADCx_ISR
- EOC
- 0: Regular channel conversion not complete
- 1: Regular channel conversion complete
- EOC
RM: 15.3.15 Starting conversions (ADSTART, JADSTART)
コード
- ADC 初期化
- ADC 変換処理
- ADC 変換結果をUARTでPCに出力
動作確認
6step制御で動かしたときにBEMF1を測定した結果です。テラタームで受信したデータをログファイルに出力して、エクセルでグラフにしました。
1step: 1000[ms]
1step: 48[ms]
次回
- BEMFから回転数を計算して、フィードバック制御を行います。