今回はSTM32でのDMAを使用したAD変換について紹介します。
環境はこれまで同様、
・STM32F303K8
+SW4STM32(System Workbench for STM32)
+STM32CubeMX(HAL ライブラリ、F3 ver. 1.60)
です。
複数chをAD変換する場合はDMA転送を前提とするようです。
STM32CubeMXは下記のように設定してコードを出力しました。
コード例は下記の通り。
こちらのサイトのコード例を参考にさせて頂きました。
・変数系定義
uint32_t ADCValue;
int Number;
enum{ LENGTH = 1024 };
uint16_t ADCBuffer[LENGTH];
・AD変換後処理関数
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
//After AD Convert
}
int Number;
enum{ LENGTH = 1024 };
uint16_t ADCBuffer[LENGTH];
・AD変換後処理関数
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
//After AD Convert
}
・初期化後にADCの読み込みを開始させる
HAL_ADC_Start_DMA(&hadc1, ADCBuffer, LENGTH);
・AD変換の設定部分
/**Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 1;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/**Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 1;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/**Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
コードを書いてAD変換したところ、
1ch目しか読み込めない不具合に遭遇。
自動生成されたConfigure Regular Channelの部分を確認すると、
赤文字のch2の設定が部分的に抜けていました。
自動生成後されたCubeMXのコードは1ch目の設定のみ
されている状況で、2ch目については何も書かれていませんでした。
赤文字部分を追加して、再度実行すると
2ch分、出力されることが確認できました。
F3 CubeMXの不具合かもしれません。
今回の不具合を回避するような設定方法があるかもしれませんが、
希望通りの動作でない場合は自動生成された部分含めて、
地道にコードを確認することが必要ですね。
また、AD変換の注意点として、
DMA転送のバッファ定義(上の例ではADCBuffer)は
変数定義をuint16_tかint16_tの16bit長にすることです。
DMA設定で
Memory Increment: Enable
Memory Data Width: Half Word (16bit)
では16bitずつバッファメモリをシフトさせるため、
uint32_tなどの32bit長にすると
バッファが破壊されてAD変換値が桁外れに大きな値になってしまいます...