STM32 (DMAでAD変換)
1.本日の内容
(1) STM32マイコン(nucleof401re)を使用して、DMAを使用してAD変換を行う。
動作:
STM32マイコン(nucleof401)でAD変換(DMA使用) pic.twitter.com/vZ54UFj9xH
— Project OKI (@oki_project) 2023年3月11日
※AD変換のDMAとは
複数のセンサの値を取り込みたい場合、
通常のAD変換で変換し順番に読み出しを行うと、効率が悪く時間がかかる。
そこで、複数の入力の対応や高速に処理したい場合、DMA転送を行うとよい。
DMAは、Direct Memory Accessの略で、
CPUを介さずにデバイス間でデータ転送を行うことができる技術のことである。
CPUがデジタルデータを処理する必要がなくなり、処理速度が向上できる。
AD変換時、DMAにより格納するためのメモリ領域を指定し、
DMAコントローラによって自動的にデータを転送するように設定する。
これにより、AD変換結果を高速かつ効率的に処理することができる。
・目次
2.内容
(1) やる内容の詳細
・CubeIDEでAD変換及びDMAの設定を行う。
・AD変換を行い、PA4(A2)とPB0(A3)の電圧を読み取る。
・読み取った値をTeratermに表示する。
(2) CubeIDEの設定
・File→New ProjectでSTM32F401を選択し、新しいプロジェクトを作成する。
→参照:CubeIDEの使い方(起動~デバック実行) - Project_OKI’s diary
・カウント確認用にprintfを使用する為、下記記事のUARTのピンを設定する。
→STM32マイコン_2(UART通信:TeraTermにHellow表示) - Project_OKI’s diary
・CubeIDEのAD変換とDMAの設定 (※CubeMXもCubeIDEも基本設定内容は同じ)
(a) Pin設定画面のPA4をADC1_IN4、PB0をADC1_IN8に設定する。
(b) Analog→ADC1を選択→DMA Settingタブに移動する。
(c) Addを押し、DMA RequestをADC1に設定する。
(d) Parameter Settingタブに移動し、下記設定にする。
項目 | 説明 | |
---|---|---|
Mode | Independent mode | |
Clock Prescaler | PCLK2 divided by 2 | |
Resolution | 12bit(15 ADC Clock cycles) | |
Data Alignment | Right alignment | |
Scan Conversion Mode | Enable | |
Continuous Conversion Mode | Disable | |
Discontinuous Conversion Mode | Disable。 | |
DMA Continuous Requests | Enable | |
End Of Conversion Selection | EOS flag at the end of all conversions | |
ADC_Regular_ConversionMode | ||
Number Of Conversion | 2 | |
External Trigger Conversion Source | Regular Conversion launched by software | |
External Trigger Conversion Edge | none | |
Rank | 1 | |
Channel | Channel4 | |
Sampling Time | 3 Cycles | |
Rank | 2 | |
Channel | Channel8 | |
Sampling Time | 3 Cycles | |
ADC_Injected_ConversionMode | ||
Number Of Conversions | 0 | |
WatchDog | ||
Enable Analog WatchDog Mod | ☐ |
(e) NVIC Settingタブに移動し、ADC1 global interruptのEnabledにチェックを入れる。
(g) System→NVICを選択し、ADC1 global interruptとUSART2 global interruptの
Preemption Priorityを1にする。
(h) 黄色い歯車マークを押し、ソースの生成を行う。
(i) main.cファイルが開かれたら、トンカチマークを押し、ビルドする。
→エラーなどが出ないことを確認する。
(3) プログラムの作成
動作:
・以下の動作をループする。
・AD変換(DMA)スタート
・printfでPA4の値を出力
・printfでPB0の値を出力
・AD変換(DMA)終了
・1000ms待つ。
※printfについては、下記記事を参照。
この記事のprintf.c及びprintf.hを使用している。
/* USER CODE BEGIN Includes */ #include "printf.h" /* USER CODE END Includes */
/* USER CODE BEGIN PD */ //AD変換の数 #define ADSIZE 2 /* USER CODE END PD */
/* USER CODE BEGIN 0 */ //AD変換用変数の用意 uint16_t adcval[ADSIZE]; /* USER CODE END 0 */
/* USER CODE BEGIN 2 */ setbuf(stdout,NULL); printf("START"); /* USER CODE END 2 */
/* USER CODE BEGIN 3 */ HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adcval,ADSIZE); printf("ADC1=%d\n",adcval[0]); printf("ADC2=%d\n",adcval[1]); HAL_ADC_Stop_DMA(&hadc1); HAL_Delay(1000); } /* USER CODE END 3 */
/* USER CODE BEGIN 4 */ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { if (hadc->Instance == ADC1) { printf("ADC END\n"); } } /* USER CODE END 4 */
(4) プログラムの説明
uint32_t *pData: DMA転送用のデータバッファへのポインタ
uint32_t Length: DMA転送のデータ数(バイト数)
3.関連記事
・STM32マイコン_2(UART通信:TeraTermにHellow表示) - Project_OKI’s diary
・STM32マイコン_3(UART通信:複数文字送信) - Project_OKI’s diary
・STM32マイコン_4(NVICの設定内容) - Project_OKI’s diary
・STM32マイコン_5(スイッチ入力とLED点灯、消灯) - Project_OKI’s diary
その他:
・CubeIDEの使い方(起動~デバック実行) - Project_OKI’s diary
C言語:
・組み込みの為のC言語基礎知識1(printf) - Project_OKI’s diary
・C言語基礎知識2(for分で処理を繰り返す) - Project_OKI’s diary
・C言語基礎知識3(配列) - Project_OKI’s diary