春雨日記 about me tags

タイマとDMAを使って一定周期でのADCデータ取り込みを行ってみました.

マイコンを使ったアプリケーションを作る上で,一定周期でデータを取得し,それを処理したいという機会は結構あると思います.

今回は,研究を行う上でそこそこ正確な連続データが必要となったため試してみました.

はじめに

使用するボード: Nucleo-64 L476(STM32L476RGT6)

他は中華ボードしか持ってないのでこれがスタンダードです笑

CubeMX設定

では,CubeMXを設定します.

クロックは予め80MHzにしてあります.適宜設定して下さい.

1.ADC

今回はIN1のみを使用します.

パラメータは写真の感じで設定して下さい.

Continuous ConversionはDisabledにして下さい

これを入れていると,HAL_ADC_Start_DMAをした瞬間ADCのクロックに従ってバッファを埋めてしまいます.(=タイマが関係無くなる)

あと重要なのはExternal Triggerで,External Trigger Conversion SourceTimer N Trigger Out eventにします.

L476ではTIM1,3,8,15あたりが利用可能ですが,利用頻度を考えると15あたりにしておくのが無難かなと思います.

External Trigger Conversion Edgeはrisingでいいです.

あとはいつも通りDMAを有効にします.

2.TIM

次はタイマです.

設定箇所はClock Sourceとパラメータです.チャネルは何も設定しません.

今回は200uS毎にスキャンするため,

  • Prescaler: 79 -> 1MHz
  • Counter Period: 199 -> 200カウント=200uS

となっています.

auto-reload preloadも有効にします.

最後に,Trigger Event Selection TRGOUpdate Eventにします. これでADCで使用されるようになります.

プログラム(main.c)

上の方

1
2
3
4
/* USER CODE BEGIN PV */
volatile uint16_t adc_data[1024] = {0};
uint8_t uart_char[64] = {0};
/* USER CODE END PV */

int main()内

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
 /* USER CODE BEGIN 2 */
  sprintf(uart_char,"start\n");
  HAL_UART_Transmit(&huart2, uart_char, strlen(uart_char), 100);

  HAL_ADC_Start_DMA(&hadc1, adc_data, 1000);
  HAL_TIM_Base_Start(&htim3);

  uint32_t count;
  while ((count = __HAL_DMA_GET_COUNTER(hadc1.DMA_Handle)) > 10);

  HAL_TIM_Base_Stop(&htim3);
  HAL_ADC_Stop_DMA(&hadc1);

  for(uint16_t i = 0; i < 1000; i++){
	  sprintf(uart_char,"%u,%u\n",i,adc_data[i]);
	  HAL_UART_Transmit(&huart2, uart_char, strlen(uart_char), 100);
  }
  /* USER CODE END 2 */

__HAL_DMA_GET_COUNTERはDMAの残りバッファ数を返す関数らしいのですが,なぜか5~8ぐらいをずっとウロウロしていて0にならなかったのでやっつけの>10にしてあります.

その雑さもあって取得したデータの後方数個は0になります.

あと連続動作は想定してないので,使用したい場合はADCのDMAContinousRequestを有効にするといいんじゃないかと思います.

動作確認

ADALM2000で60Hz,3.2Vpp,オフセット1.6Vのsin波を出して,ADCで読んでみます.

一応正しそうな波形ですが,何か下が潰れてますね.ADCの仕様でしょうか

200uS*1000ポイント=0.2Sということで,5Hzのsin波を見てみました.

一周期取れているので200uSというのも正しそうです.

おわりに

中華のSTM32H750VBT6ボードを買ってみましたが,キャッシュとかDMAとかがF4/L4と比べものにならないほど複雑です….

そのかわり480MHzという圧倒的なスピードで動作するのですが. まるでパソコンだなぁ(?)

参考文献

https://qiita.com/amutou/items/b7e6ffc42d2ce2b7f260

https://jp7fkf.hatenablog.jp/entry/20200603/1591186190

日本語の情報があって助かりました…