Rubyと一緒(5) GR-CITRUSのADCの参照電圧、結局1種類じゃん?多分。

Joseph Halfmoon

特価品(見切り品?)のGR-CITRUSボード(RX631搭載)で組み込みRuby(mruby)してます。前回はDAC出力だったので、今回はADC入力を使ってみます。マニュアル拝見すると基準電圧が3種類、レゾリューションが2種類で合計4種もの動作モードがあるように見えます。でも回路図みるとそんな筈がないです。どゆこと?

いつもお世話になっておりますルネサス様の以下のページを拝見すると

GR-CITRUS 特設:クラス、メソッド早見表

analogRead(pin)メソッドの項に(以下引用させていただきます)

pin: ピン番号(14, 15, 16, 17) 0~675(3.3V)
後述のanalogReferenceで入力モード指定可能

と注釈が書かれてます。そして、analogReference(mode)の項には(再度引用)

0: 5.0V基準
1: 1.1V基準(内蔵電圧)
2: 3.3V基準
3: 3.3V基準, 12ビット分解能(0~4096)

と書かれておりますのじゃ。RX631とGR-CITRUS素人の年寄は上記をみて、基準電圧が3種類、ADコンバータも12ビット分解能と10ビット分解能(多分、書いてないけど)の2種類が使えるのか?と早合点してしまいました。

でもま、RX631のデータシートとGR-CITRUSの回路図を拝見させていただき、上記の認識を修正いたしましたぞ。

RX631搭載ADのハードウエア

RX631は、いずれも逐次比較型のADC、2ユニットを搭載しています。その電源と基準電圧端子をまとめると以下のようです。

AD名 レゾリューション AD電源 ADグランド AD参照+ AD参照-
S12ADa 12bit AVCC0 AVSS0 VREFH0 VREFL0
ADb 10bit VREFH VREFL VREFH VREFL

つまり12bit精度のS12ADaというユニットは、独立の電源、GNDと参照電圧+、-を持っており、10bitのADbは、電源、GNDがそのまま参照電圧としても使われる方式になっているようです。ただし、GR-CITRUSの回路図を参照すると、結局どちらも同じだ、ということが判明。

    • AVCC0、VREFH0、VREFL0、すべて3.3V電源
    • AVSS0、VREFH、VRERL、すべてGND

つまり3.3V電源が外部リファレンス電圧兼アナログ電源であります。なお、1.1Vのリファレンス電圧を内蔵しているのですが、RX631のドキュメントを拝見するに、この電圧を読み取ることはできそうなのですが、この電圧をAD変換のリファレンス電圧に使う方法は見当たりませんでした。なんだ、結局 参照電圧は3.3V電源の1択か?ホントか?

また、RX631のチップ端子とGR-CITRUSの外部端子の関係でいうと

S12ADa のAN000~AN003がそのままA0~A3端子に出ている

という関係です。よって使用可能なADCはS12ADaの方で10bitのADbの方はとりあえず忘れておいても良さそうです(ただし、A0~A3端子は、ボード背面の半田ジャンパにより接続先を変更可能。)

なお、細マケー話ですが、手元のGR-CITRUS回路図では マイコン端子名のVREFH0とVREFL0の”0”が抜けておりVREFH、VREFLと見分けがつかないっす。まあ、上記のような接続なのでどうでもいい話ですが。

今回実験のRuby(mruby)ソース

今回実験のソースが以下に。4種の「analogReferece()モード」を変更しながらadcの値を読んで標準出力に出力するだけのもの。

#!mruby
usb = Serial.new(0, 9600)
usb.println("ADC, Pin.A0")
adcmode = 0
duration = 2000
while true do
    usb.println("ADC mode: " + adcmode.to_s)
    analogReference(adcmode)
    adcin = analogRead(14)    
    usb.println("ADC read: " + adcin.to_s)
    adcmode = adcmode < 3 ? adcmode + 1 : 0
    delay(duration)
end

ここで最初、

analogRead(A0)

みたいな書き方をしたら、実行時エラー(ビルド時ではない)で落ちました。ボード上にもA0ってしっかりシルクで描かれているじゃん。互換性を意識?しているらしいArduinoじゃ、アナログ端子はA0って書けた気がする。知らんけど。

まあ、端子番号で

analogRead(14)

と書いたらすんなり通りました。よくある「フェイント」ね。ガタガタ言うなと。

実験結果とその考察

実験のために、A0端子の外側に抵抗とボリュームを取り付けました。どちらも1kΩです。固定抵抗で3.3Vに吊り上げ、ボリュームの片側はGNDに落としてあります。ブレッドボード写真が以下に。GR_CITRUS_AD_DUT

ボリュームは結構回転数が多いタイプなのでかなり細かく調整できます。ハンディDMMの電圧計をみながらA0に加わる電圧が 1.000 Vになるように調整いたしました。

ここで4モード(0から4)の測定値とそこから推定できる計算式を以下に列挙しました。

    • モード0、読み値 205、計算式 (205/1024) * 5.0 = 1.001 [V]
    • モード1、読み値 930、計算式 (930/1024) * 1.1 = 0.999 [V]
    • モード2、読み値 310、計算式 (310/1024) * 3.3 = 0.999 [V]
    • モード3、読み値 1240、計算式 (1240/4096) * 3.3 = 0.999 [V]

前述のハード調査の結果とまとめると以下のようかと

    1. 12ビットのADを使っているがモード0から2では10ビットの結果に換算している
    2. モード0では、存在しない5Vの参照電圧があるかのような値に換算している。結果レゾリューションは荒くなっている。推測するにArduinoの5V機に合わせたかった?(Arduinoでも3V IO電圧機ではそんな律儀な換算してないケド。)
    3. モード1では、内蔵の1.1V参照電圧を使っているような書きぶりだが、その実体はよくわからない。1.1Vの内蔵電圧を参照して計算で「補正」かけているのかも知れない。
    4. モード2では、3.3V電源をリファレンスに読み値を10ビットに換算している
    5. モード3では、3.3V電源をリファレンスに12ビットで読み取っている

なんだか複雑なモードを作ってくれてるのだが、内蔵の参照電圧のよみとり機能さえあれば、12ビットそのままで良いような気がします。やりすぎ感あり。

Rubyと一緒(4) GR-CITRUSでDAコンバータを使ってみる、やっぱ10ビットだわ へ戻る

Rubyと一緒(6) GR-CITRUS、digitalRead、ポーリングするしかない? へ進む