SNSへはこちら

CH559マイコンをいじってみよう(7) - ADC

皆さん、ご無沙汰です。多忙によってしばらく記事の投稿をしていませんでした。
マイコンの仕事をしながら、自宅でマイコンをいじることがなくなっていましたが、徐々にこの趣味を再開していこうと思います。ひょっとしたら、これまでの記事以外にも、PC 関係の Tips も投稿するようになるかもです。趣味が多様化してきたなぁ。

...これまでのCH559記事に続きまして、ADC です。こちらはメチャクチャ楽なので速攻で記事が終わってしまいます。

ADC概要

  • チャネル数: A0 から A15 の16チャネル
  • 分解能: 10bit or 11bit で選べ、GND 〜 3.3V まで入力可能
    • ADC_EX_SW レジスタで設定できますが、今回はとりあえずデフォルト(10bit) でいきます。

初期化コード全景

ではまずこちらをご覧あれ。

void adc_init(void) {
    // #45: P1.2/AIN2
    ADC_SETUP |= 1 << 2; // Power on ADC module
    ADC_CK_SE = 4;
    ADC_CTRL = 0xF;

    P1_IE &= ~(1 << 2); // disable digital in and switch to analog
    P1_PU &= ~(1 << 2);
}

たったこれだけ。あとポートの設定もしていますね。

セクションに分けるほどでもないのでこのまま説明しますね。

まず ADC_SETUP ではペリフェラルをオンにします。最初にやる必要があるみたい。
続いて ADCC_CK_SE では ADC ペリフェラルに入力するクロックを分周しています。先のシステムクロック設定を使うならば入力は 48MHz となります。データシートでは「入力クロックは 1MHz 〜 12MHz にしてね」と書かれていたので最大クロックにしました。

ADC_CTRL を 0xF としたのはサンプリング期間をとりあえず MAX で設定したものです。つまり適当。

P1_IEP1_PU ではピンの設定をしています。それぞれアナログ入力設定と入力段のプルアップ無効化をしています。
IE と見ると「割り込み有効?」と思うかもしれませんが、今回ばかりは違って Input Enable だそうです。どういう意味よそれ。当該のビットを0にするとアナログ入力に切り替わるとのこと。今回は決め打ちで AIN2 に設定しました。

A/D値を読み出す関数

以下の実装で読み出せます。なんかデータシートの解説がやたらめったら分かりづらいのですが、単純実装で OK なようです。
関数にはチャネル番号を指定できるように引数を設けてありますが、今回は決め打ちで Channel 2 としているので、まあ2として固定で使ってくださいな。

unsigned int adc_get(unsigned char channel) {
    ADC_CHANN = 1 << channel;

    while( !(ADC_STAT & (1 << 4)) );
    ADC_STAT = 1 << 4; // Clear flag
    return (ADC_FIFO_H << 8) | ADC_FIFO_L;
}

ここではフラグを1つ見ています。至って普通ですね。これは変換が完了したら 1 になります。読みだした後は1を書いてクリアしています。

USB 以外のペリフェラルは大体出来ましたかね。感想としては とんでもねぇ地雷が各所に埋め込まれていたなと言った感じです。

他にも DMA 機能や DPTR が残っていますが、これは一旦置いておいて、ひとまず USB デバイスから実装していきたいと思います。