STM32のStandardPeripheralLibraryを使うとき、 各Peripheralの初期化構造体をちゃんと初期化していなかったので問題が起こりました。

起こった問題

STM32F4でADCの結果は右詰めで格納するように設定したのに、なぜかADC3のADC結果が左詰めで格納されているということが起こりました。

設定しているところのコード

ADC_InitTypeDef  ADC_InitStructure;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC3, &ADC_InitStructure);

原因

ADC_InitTypeDef構造体には上のコードで設定した以外のメンバがいくらかありますが、 そいつらを初期化していないのが原因でした。

ADC_Init()の中身を見ていると、こういう部分があります。

ADC_DataAlignはADC_ExternalTrigConvやADC_ExternalTrigConvEdgeなどといった、 今回は設定していなかった値たちとORがとられています。

ADC_InitStructureはスタック上の変数で、生成しても値は初期化されない(変な値入っている)ので ADC_ExternalTrigConvやADC_ExternalTrigConvEdgeにも変な値が入ったままADC_Initに渡されてしまいます。 その結果思惑とは違う値にレジスタが設定されてしまうので、予想外な動きをしていました。

解決策

初期化構造体を

ADC_StructInit(&ADC_InitStructure);

として、初期値に初期化してから設定していくと思った通りに動きました。 (このための関数だったのか)

もしくはADC_InitTypeDefに含まれるメンバすべてに値を設定するのでも大丈夫でした。

覚えておくこと

STM32のStandardPeripheralLibraryを使うとき、 各Peripheralの初期化構造体はちゃんと初期化する。