STM32G4のOPAMPを使ってみる

お久しぶりです。もりゅーです。
もう少し更新頻度上げたいですねえ・・・

さて今回は、最近流通し始めたSTM32G4についてです。

STM32G4シリーズ

https://www.st.com/ja/microcontrollers-microprocessors/stm32g4-series.html

"DSPおよびFPU命令による高い性能と高度な機能を備えたミックスド・シグナル・マイコン"らしいです。
ADC/DACを始めとする豊富なアナログペリフェラルを搭載しており、モータ制御なんかに適していそうですね。

その中でも今回はプログラマブル・ゲイン・オペアンプについて、備忘録がてら書いていこうと思います。

プログラマブル・ゲイン・オペアンプ(PGA)とは

その名の通り、ゲインをプログラム上から変更できるオペアンプです。STM32はいくつかのシリーズには搭載されていますが、
G4は数・設定ゲイン・帯域等が優れているようです。

f:id:Moryu_io:20190811140017p:plain
STM32 Application note AN5310より

簡単な使い方

とりあえずCubeIDEとnucleoG474REを用いて、最も簡単な非反転増幅でPGAを試してみます。

1. CubeMXでの設定 Nucleoボード

STM32G4は最新のCubeMXじゃないと存在しないみたいです。アップデートして、nucleoG474REを選択します。
この後にちょろちょろ出てくる設定はデフォルトで大丈夫のはずです。
f:id:Moryu_io:20190811140355p:plain

2. OPAMPペリフェラル設定

今回は、マイコン内部で
・OPAMPの出力とマイナス入力
・OPAMPの出力とADCチャンネル
を接続し、OPAMPのプラス入力電圧(PB0)を増幅することとします。

まず使用するOPAMPをOPAMP3とし、以下のように設定します。ゲインはとりあえず4倍で。
f:id:Moryu_io:20190811140806p:plain

OPAMP出力をADCに入れる設定は以下です。
OPAMP3の場合はADC3に「VOPAMP3 Channel」というのがあるので、それを使用します。
f:id:Moryu_io:20190811141433p:plain

また、参照用として、OPAMPプラス入力電圧を監視するADCも追加しときます。
これはADC1_Channel1を使用しました。特に意味はありません。
ADC回りについては以下のブログがよくまとまっています。よく参考にさせていただいております。
gsmcustomeffects.hatenablog.com


設定が終わったらコードを生成します。

3.コード

とりあえずOPAMPが動いていることを確認したかったので、最低限のコードのみ記載します。
ADCなどと同じように、HAL_OPAMP_StartでOPAMP機能と開始できます。
あとはADCの値を取ってくれば、OKという感じ。

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */
  

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC3_Init();
  MX_OPAMP3_Init();
  MX_USART1_UART_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
  uint32_t _u32_bframp_value = 0;
  uint32_t _u32_aftamp_value = 0;
  HAL_ADC_Start(&hadc1);
  HAL_ADC_Start(&hadc3);
  HAL_OPAMP_Start(&hopamp3);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  HAL_Delay(1000);
	  if(HAL_ADC_PollForConversion(&hadc1,100) != HAL_OK){

	  }else {
		  _u32_bframp_value = HAL_ADC_GetValue(&hadc1);
	  }

	  if(HAL_ADC_PollForConversion(&hadc3,100) != HAL_OK){

	  }else {
		  _u32_aftamp_value = HAL_ADC_GetValue(&hadc3);
	  }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

4. 配線

Aliexpressで買った電源を雑に繋いでいきます。
f:id:Moryu_io:20190811143503j:plain

5. 結果

デバッガで確認。0.5Vぐらいを4倍増幅している。
_u32_bframp_value が増幅前0.5V = 620ぐらい
_u32_aftamp_value が増幅後2.0V = 2480ぐらい
f:id:Moryu_io:20190811142503p:plain

フィルタリングしてないのでこんなもんでしょうか。今度、出力を外部ピンにして見てみます。

まとめ

STM32G4のPGAを使ってみました。多分それっぽく動いているっぽいです。
マイクロマウスだったら、壁センサの増幅に使えそうですね。
個人的にはBLDCの勉強中なので、ベクトル制御に使ってみたい感じがします。


ちなみに、OPAMPのMODEはいろいろありますので、詳細を知りたい方、他のモードを使いたい方は
Application Note: AN5306やレファレンスマニュアルを読んでください。
反転増幅にして、レファレンス電圧をDACにするとか、いろいろ便利なのがあります。

以上、何か質問があればコメントかTwitter: Moryu_ioまで。