Sim's blog

電子工作はじめてみました

A/D変換してみる

2007-05-08 00:44:08 | V850
V850には10bit分解能のA/D変換があります。チャネルは12個あるみたいですが、A/D変換自体は1つで切り替えながら使うようです。

A/D変換の説明はユーザーズマニュアルの13章に載っています。色々な変換モードがあるみたいです。
トリガーモードは、ソフトウェアトリガ、外部トリガ、タイマトリガの3つから選びます。
動作モードは連続セレクト、連続スキャン、ワンショットセレクト、ワンショットスキャンの4つから選びます。スキャンは複数ポートの変換、セレクトは単独ポートの変換、ワンショットは1回だけ変換して次のトリガを待ちます。連続は変換が終わったら次の変換を自動でします。

とりあえずappliletで作ってみます。たぶん一番単純そうなソフトトリガ(開始はソフトから指定)、ワンショットセレクトモード(指定したポートを1回だけA/D変換)、通常変換(高速変換もある)、(ポーリングの仕方が分からないので)A/Dの割り込み許可を選びました。APIはAD_Init(), AD_Start(), AD_Stop(), AD_Read()を使うようです。

半固定抵抗で分圧した値をアナログ入力端子チャネル0(AN0)に入力してみます。AN0はCON2の1pinです。半固定抵抗なのでドライバーで回すと電圧が変わります。

appliletは割り込み処理ルーチンをAD_user.cの中に作ってくれます。A/D変換が完了したという割り込みなので変換終了を通知するだけです。
__interrupt void MD_INTAD( void )
{
    extern volatile int rdy;
	
    rdy = 1; // 変換終了
}

メインは、A/D変換してから結果を表示する無限ループです。100ミリ秒待っているのは、表示が速すぎてLCDが読めないからです。
#define MAX_VOLT 3250      // 実測3.25V
volatile int rdy;          // 変換完了フラグ

void  main( void )
{
    unsigned short val;
    int v;

    lcd_init();            // LCD初期化

    while(1){
        rdy = 0;
        AD_Start();        // 変換開始
        while(!rdy) ;      // 変換完了まで待つ
        AD_Read(&val);     // 変換結果を読む

        v = (MAX_VOLT * (int)val) >> 10; // mVに変換

        lcd_puthex4(val); // 変換結果の16進出力
        lcd_putc(' ');

        lcd_putdec(v);    // mV値の10進出力
        lcd_puts("mV        ");
        
        ms_wait(100);     // 100m秒待つ
    }
}


LCDの左側の16進4桁が読み取った値です。10bitなので000~3ffの範囲になります。右側の10進5桁はmVです。1画面に4つ履歴が残るようになっています。テスターの値と較べると上位2桁くらいが信用できそうです。下の方の桁は結構ばらついています。appliletにあった変換時間を長くすると精度があがるのかもしれません(今回は最短の3.25u秒)。

A/D変換はすぐできたのですが表示を作るのに手間取りました。LCDはあちこちアドレスを動かしながら動かすとなぜか表示位置が乱れてしまいます。文字だけを出力しているぶんには乱れないので、無駄な空白を出力しています。busyを見たり、ちゃんとwaitを入れたりすると乱れないのかもしれません。

最新の画像もっと見る

コメントを投稿