« MOS FETを使用したハイサイドスイッチ | トップページ | STM32 Primer2 V1.2 »

STM32 ADCの設定

前回記事「MOS FETを使用したハイサイドスイッチ」で、GPSモジュールの電源制御をOn-Off制御信号(サスペンド・レジューム信号)にて行えないかと記載しましたが、実験したところ結果はOKでした。使用したGPSモジュールのOn-Off制御信号は1.2Vロジックのため電圧変換の抵抗が必要ですが(1.8V→1.2V変換の分圧抵抗がモジュール内に入っているため、2.8V→1.2Vとなるように直列の抵抗を1本追加)、MOSFETを使う回路に比べて部品点数が少ないため、On-Off制御信号を使うことにしました。

電源制御は、On-Off pinにパルスを入力することによってサスペンド・レジュームがトグル動作しますが、GPSモジュールへサスペンド要求を出した後、本当に電源が落ちているかを確認したいと思いました。サスペンド動作は、モジュール内部で生成しているVCC(1.8V)が0Vになることで確認ができます。そのため、GPSモジュールのVCCをSTM32のADCでモニターしてサスペンド状態への移行を確認してからGPSアプリを終了することにします。

上記の理由から、STM32のADCを始めて使ってみました。STM32のペリフェラルはやたらと機能が多いと先人の方がブログに書いていますが、確かに「これでもか!」と言わんばかりの機能が入っています。NXP LPC17xxのマニュアルを見たのですが、STM32のADCはLPC17xxより機能が多く複雑です。

これだけの機能を使いこなせれば最強なのでしょうが、先ずは、必要最小限のAD変換機能を動かすための設定方法を記載します。

STM32 ADCの動作モード

動作モードを表にすると以下となります。

STM32ADC_Functions

ちなみに、今回使用した機能は紫の網掛け部分で、以下の内容となります

  • 入力として1chを使用
  • Single shot変換(変換毎にソフト指定のトリガーを出す)
  • サンプル時間は55.5 cycleを指定

AD変換のコード

先ずは、ADC初期設定のコードです。入力ピンに使用するGPIOもあわせて設定します。

/*******************************************************************************
* Function Name  : InitADC2
* Description    : Initialize ADC2 as single shot mode
*                  Set PC.4 (Primer2 Extention Connector Pin 11) as analog input
*
*******************************************************************************/
void InitADC2( void )
{
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef  ADC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);

    GPIO_StructInit (&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    /* ADC1 Configuration ------------------------------------------------------*/
    ADC_InitStructure.ADC_Mode                = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode        = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode  = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv    = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign           = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel        = 1; 
    ADC_Init( ADC2, &ADC_InitStructure );

    /* ADC2 regular channel14 configuration to sample time = 55.5 cycles */ 
    ADC_RegularChannelConfig( ADC2, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5);

    /* Enable ADC2  */
    ADC_Cmd(ADC2, ENABLE);

    /* Enable ADC2 reset calibaration register */   
    ADC_ResetCalibration(ADC2);

    /* Check the end of ADC1 reset calibration register */
    while(ADC_GetResetCalibrationStatus(ADC2));

    /* Start ADC2 calibaration */
    ADC_StartCalibration(ADC2);
    /* Check the end of ADC2 calibration */
    while(ADC_GetCalibrationStatus(ADC2)); 
}

上記以外にADCクロックの分周比を設定する必要がありますが、CircleOSが初期設定しているため割愛。生で使う場合は設定が必要です。

データー取得のコードは以下です。

/*******************************************************************************
* Function Name  : getCxAdc1Value
* Description    : Get ADC converted value of ADC2 ch-14 (CX_ADC1)
*                  Use single conversion mode
* Input          : NONE
* Return         : Converted value
*******************************************************************************/
u16 getCxAdc1Value(void)
{
    // Start ADC2 Software Conversion
    ADC_SoftwareStartConvCmd( ADC2, ENABLE );
    // Wait until conversion completion
    while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET);
    // Get the conversion value
    return ADC_GetConversionValue(ADC2);
}

思ったこと

ST Libraryの命名規則がしっかりしており(CMSISというやつですね)、名前から設定内容が分かるためコードの見通しはそこそこよいのですが初期化に20行程度必要って面倒ですね、、

初めてWindows APIの本を読んだときに、窓を1つ開くだけで40行近くのコードが必要なのにびっくりして、DOSの方がよっぽどプログラムは楽だと思ったのに似ています。最近のWindowsプログラミングは、C#/VBなんかのRAD(Rapid Application Development)ツールを使えば、窓を開くだけならプログラムコードはまったく不要で(GUIデザイナーで画面イメージを作るだけ)、複雑怪奇なWindows APIを意識することなくコーディングができます(その代わりに膨大なクラスライブラリの機能を把握するのが一苦労ですが)。

上記から、Arduinoやmbedのように、C++のオブジェクトを使ってデバイス初期設定などの下回りを隠蔽するコンセプトは捨てたものではないと思いました。ちなみに、mbedならADCの初期化と値の取得(上記のAD変換コード相当)は、以下のようにたったの2行ですみます。

AnalogIn ain(p20);         // コンストラクターの呼び出し(ADCの初期化)
float vol = ain.read();     // %値(0.0~1.0)として読み取り。ain.read_u16()だと12bitの生データーを取得できる

STM32の複雑なモード設定をオブジェクト化すると、メンバー変数(モードを保持するプロパティー値)が増えそうではありますが、CMSISよりコードの見通しがよくなると思います。ただ、オブジェクト化するということは、ハードの設定や動作を一定の枠に押し込むことになり、ハードの能力を使い切る必要に迫られれる組み込みプログラミングには適さない部分もあると思います。あと、オブジェクト指向だとコードサイズが大きくなってしまうでしょうか。

結局、Cでゴリゴリ書くのが今は王道なのかしら。

« MOS FETを使用したハイサイドスイッチ | トップページ | STM32 Primer2 V1.2 »

STM32-ARM」カテゴリの記事

コメント

> STM32のADCはLPC17xxより機能が多く複雑です。

そうなんですよね、思い付いた機能を全部入れてみましたって感じで、全く使いこなせる自信がありません(笑)。
でも、やっぱり魅力的です。今度ウインドウコンパレータを使ってみたいなと思う今日この頃です。

同じCortex M3でもライセンス先によって特徴が出ていて興味深いです。
データーシートを眺めて機能全体をチェックする根性はないのですが、Timerくらいは触ってみたいです。

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

« MOS FETを使用したハイサイドスイッチ | トップページ | STM32 Primer2 V1.2 »

2017年2月
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28        
無料ブログはココログ