こんにちは。Yukiです。

今回は、Nucleo-F303K8でADC変換してみました。

 

いつも通り、HALを使わないで、やってみたいと思います。

 

 

 

  ADCを使用するためのピン選び

 

今回は、Nucleo-F303K8に書いてあるA0で、アナログ入力してみたいと思います。

 

A0はSTM32F303K8マイコンのPA0に接続されています。

PA0はADC1_IN1に接続されています。

 

ということで、今回は、ADC1_IN1が重要なキーワードになります。

 

 

 

  ADCを使用する手順

 

今回は、PAポートを使うということから、ポートAにクロックを入力する必要があります。

       //ポートAクロック入力(有効)

       RCC->AHBENR |= (1 << 17);

 

 

次に、ADCにクロックを入力する必要があります。

       //ADC12クロック入力(有効)

       RCC->AHBENR |= (1 << 28);

 

 

次に、サンプル時間を設定します。

今回は、ADC1_IN1のサンプル時間を19.5ADCとします。

       //ADC1 サンプル時間 19.5ADC

       ADC1->SMPR1 |= (1 << 5);

       ADC1->SMPR1 |= (1 << 3)

 

 

次に、ADCに与えるクロックをHSIにします。

//ADCクロックHSIに

ADC12_COMMON->CCR |= (1 << 16);

 

 

 

次に、ADCのキャリブレーションをします。

これは、しなくても問題ありませんが、することで、精度が上がる(らしい)です。

まず、ADCの電圧レギュレータを有効にします。

//ADC電圧レギュレータを移行状態(00)に

ADC1->CR &= (~(1 << 28));

ADC1->CR &= (~(1 << 29));

 

//ADC電圧レギュレータを有効(01)に

ADC1->CR |= (1 << 28);

 

//電圧レギュレータが起動するまで待機

//(delay関数を作成したら、変更予定)

for(volatile int i = 0;i <= 10000;i++){

    asm("NOP");

}

 

なお、for文で、時間稼ぎしていますが、本来は、delay関数などを作るべきです。

これは、後日delay関数を作ろうと思います。

 

 

次に、ADCのキャリブレーションを開始します。

キャリブレーションが終了すれば、ADCALビットが自動でクリアされます。

ということで、whileで回します。

//ADC キャリブレーションスタート

ADC1->CR |= (1 << 31);

//ADC1 キャリブレーションが終了するまで待機

while(ADC1->CR & (1 << 31));

 

 

最後に、ADC電圧レギュレータを無効にします。

(無効にしなくても良いのですが、消費電力の関係で無効化しといた方が良いらしいです)

 

 

//ADC電圧レギュレータを移行状態(00)に

ADC1->CR &= (~(1 << 28));

ADC1->CR &= (~(1 << 29));

 

//ADC電圧レギュレータを無効に

ADC1->CR |= (1 << 29);

 

これで、ADCのキャリブレーションは終了です。

最後にADCを有効にします。

//ADC有効

ADC1->CR |= (1 << 0);

 

//ADCが有効になるまで待つ

while(!(ADC1->ISR & 0x01));

これで、ADCの初期化は終了です。

 

 

 

  ADCの回路図

 

Nucleoのシンボルを作る気が起きなくて、掲載できません(すみません)

 

今回は、可変抵抗を使っていますが、A0に接続しています。

 

 

 

  実験の様子

 

とりあえず、こんな感じで、他になんにも付けていません。

 

 

  結果

 

こんな感じで、ADC出来ました。

 

より精度を上げるために、右側に2ビットシフトしてみました。

結構、いい感じですね。

 

 

 

  ソースコード配布

 

今回も、Google Driveでの配布です。

 

 

以前まであった、uart1関連は、削除しました。(不要になったため)

なお、ファイルは別にしているので、uart関連は残っています。

(こうしておくと、PCを初期化した時の、リストアが楽なんですよね)

 

なお、uart2で新たに、uart2_num_print関数を追加しました。

int型の数字データを、uart2に出力します。

 

 

 

  余談1

 

このマイコン(STM32F303)は、ADCを駆動するためのクロックが2系統あるマイコンです。

1系統は、PLLを通したクロックの供給。(標準)

もう1系統はHCLKクロックからの供給です。

ただし、HSIクロックのみで動作させる場合、PLLが無効のため、動作しません。

 

これで、1日溶かしました…。

 

 

 

  余談2

 

最近、知人に、「レジスタ操作するなら、Nucleoマイコン使う必要ないじゃんw」

って的確なツッコミを受けました。

確か、Nucleoマイコンってmbed環境で開発できるんでしたっけ?

Nucleoマイコンとか使わずに、ST-LINKを買って、STM32マイコン開発しようかな?