TIM3でタイミングを生成し、ADC1_IN6(PA6)で受信する。
CubeMXの設定
Pinoutタブ
ADC1のIN6にチェックを入れる。
TIM3のClock SourceをInternal Clockにする。
Configurationタブ
AnalogのADC1ボタンをクリック、ADC1 Configurationウインドウを開く。
Parameter Settingsタブを開く。
External Trigger Conversion SourceをTimer 3 Trigger Out eventにする。
DMA Settingsタブを開く。
Addをクリックし、DMA RequestをADC1にする。
ControlのTIM3ボタンをクリック、TIM3 Configurationウインドウを開く。
Parameter Settingsタブを開く。
Prescalerに84-1
、Counter Periodに1000-1
を設定する。
Trigger Event SelectionでUpdate Eventを選択する。
コードを書き出す。
ソースコード
constexpr size_t len(1000);
static uint16_t ADC_buff[len];
memset(ADC_buff, 0, sizeof(ADC_buff));
HAL_TIM_GenerateEvent(&htim3, TIM_EVENTSOURCE_UPDATE);
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC_buff, len);
HAL_TIM_Base_Start(&htim3);
while (__HAL_DMA_GET_COUNTER(hadc1.DMA_Handle) > 0)
{
osDelay(1);
}
HAL_TIM_Base_Stop(&htim3);
HAL_ADC_Stop_DMA(&hadc1);
for (size_t i(0); i < len; ++i)
{
printf("%u %hu\n", i, ADC_buff[i]);
}
結果
信号源には前回紹介したDACを使用している。ただし、DACはCircularで連続した正弦波を出力している。
ADC1kSPS/1kポイントなので1秒分の期間を見ている。DACからは1Hzの正弦波が出力されているので、狙い通りの周期でサンプリングできていることが分かる。
DACとADCのタイミングは合わせていないから、位相ずれが発生している。
その他
DACの場合、DMAをCircularにすれば延々と出力されるが、ADCはもう少し面倒な処理が必要よなる。またADCは得られたデータを解析するまでが仕事だから、Circularにするなら割り込みでリアルタイムにデータを解析する必要もある。