良いお手本がありました。
Nucleo F303K8 でなぞってみます。
UM1956を見て,使うピンを決めました。PA4 と PA3 を接続することにします。隣り合っているのでショートピンが便利ですね。
PIN Arduino STM32
7 A5 PA6 DAC2_OUT1 UnBuffer
8 A2 PA5 DAC1_OUT2 UnBuffer
9 A3 PA4 DAC1_OUT1
10 A2 PA3 ADC1_IN4
...
ioc設定
まだきちんと設定していないので黄色くなっています
DAC設定
ADC設定
- IN4 が Single とのことですがまあOKとしましょう。
- ADCを繰り返したり,複数チャンネル一気に変換したりといろいろできますが,一番基本的なものとしておきます。
- Clock Prescaler だけ変更しました。多分一番精度が良い,低速のものにしました。
テスト結果
STのwikiでは1変数のDMAを使っていましたが,ここでは変換終了を待つ方式にします。
0x800 をDACに設定し,0x7fc が得られました。
/* USER CODE BEGIN 2 */
HAL_DAC_SetValue(&hdac1, DAC1_CHANNEL_1, DAC_ALIGN_12B_R, 0x800);
HAL_DAC_Start(&hdac1, DAC1_CHANNEL_1);
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
uint32_t d=HAL_ADC_GetValue(&hadc1);
/* USER CODE END 2 */
ADC変換終了待ちと結果を取ってくる部分,以下のようにレジスターを直接見ても大丈夫でした。
while ( !(ADC1->ISR & (1<<2)) ) {} // wait until EOC is 1
uint32_t d=ADC1->DR;
変換精度と時間
クロック設定で値が変わるのでしょうか。やってみます。CPUは8MHz動作です。
| クロック設定 | 変換時間 | ADC結果 |
|---|---|---|
| clock div 4 | 56usec | 0x7fc |
| clock div 2 | 49usec | 0x800 |
| clock div 1 | 49usec | 0x809 |
| ADC専用クロック 16MHz | 45usec | 0x7e4 |
| ADC専用クロック 32MHz | 45usec | 0x7fd |
| ADC専用クロック 64MHz | 45usec | 0x81b |
CPUのクロックスピードを64MHzにしてみます。
| クロック設定 | 変換時間 | ADC結果 |
|---|---|---|
| ADC専用クロック 4MHz | 16usec | 0x7fe |
| ADC専用クロック 8MHz | 11usec | 0x807 |
| ADC専用クロック 16MHz | 9usec | 0x7e8 |
| ADC専用クロック 32MHz | 8usec | 0x7fb |
| ADC専用クロック 64MHz | 8usec | 0x7e9 |
ものすごく乱暴にまとめますと,
本件では,クロック設定でそれほど変換精度が変わるものではなく,変換スピードはクロックスピードに大きく依存する,と言えそうです。
DS9866によれば,12ビットADCのサンプリングレートは最大5.14Mspsとのことですから,もっと速くする設定があるようです。
補足
ADC専用クロックを使う場合,
こんな感じにします。
変換時間はTIM6を使いました。8MHz動作のときは,TIM6のプリスケーラーを8に,64MHz動作のときは64に設定しました。TIM6->CNTに経過時間 usec が入ります。HAL_ADC_Start()の時間は無視しています。
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
HAL_TIM_Base_Start(&htim6);
uint32_t s0=TIM6->CNT;
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
s0=TIM6->CNT - s0;




