Knowledge
   

MiniEval1でA/D変換

いよいよA/D変換〜ということで、まずは一番簡単そうなSAR6というモジュールを使って、A/D変換の勉強です。


2005/10/11

PSoC・A/D変換をしてみる(下調べ中)

A/D変換 User Module
今度は、A/D変換をしてみようと思っているのですが、せっかくなので、サンプルを見ながら自分のやってみたいのを作り始めてみました。 う〜ん、なかなか意味がわからないです。英語のマニュアルはこういう時、つらいです。んで、いくつか気づいた事がありましたので、 メモしておきます。

SAR6
アナログからデジタルに変換するユーザモジュールは何種類かあるのですが、今回は、ぱっと見、シンプルそうなSARを使ってみようと思います。 アプリケーションノート(AN2239)に、A/Dコンバータの特徴が書いてあるのですが、「SAR」は、「Analog Switched Capacitor PSoC Blocks」 のことのようです。「逐次比較レジスタ」…きっと、「逐次変換していくADコンバータ」ということかな。よく読むと、 「このタイプのコンバータは高速であるが、変換から変換完了の要求に対する入力が安定するまで、CPUを100%使用する」と書いてありますので、 きっと、CPUからあれこれしてA/D変換するのでしょう。その分、デジタルブロックなどを使用しません。

んで、MiniEval1には、PORT0[1]にボリュームが実装されているので、これを読み取ってみようと作り始めたのですが、 あら?ダイレクトに選べるポートには制限があるのね…しかも、PORT0[1]は選べないようです。たぶん、増幅器とかを経由したら大丈夫そうなんですが、 直につなげるのは…

SCREEN SHOT まずは、ASC10にPlace(配置)してみました。そうすると…。
SCREEN SHOT 選べるのはこれだけです。ポート直に接続できるのは「PORT2[3]」のみです。
SCREEN SHOT まずは、ASD20にPlace(配置)してみました。そうすると…。
SCREEN SHOT 選べるのはこれだけです。残念ながらPORT直には接続できません。

こんな感じで、順番にPlaceしていってみたら(きっとマニュアルのどこかに書いてあるんでしょうけど、う〜ん、どこかな〜)、 ポート直に接続できるのは、ASC10がPORT2[3]、ASC23がPORT2[0]で、他には接続できないことがわかりました。 使い方から考えたら、直に接続する事はあまり無いと思いますので特に不便では無いんでしょうが、 設計時にはちょっと覚えておいた方がよさそうです。

それにしても、「Sample Clock」って、どれくらいのクロックを入れたらいいんでしょう???

 

2005/10/19

PSoC・A/D変換をしてみる(やや悩み中)

「公開練習会 in ポートメッセなごや」
PSoCをお供に某国へ出張してます(ここは暖かいので、風邪を引いている身としてはちょっとうれしかったりして)。 なんか、出張している時の方が、仕事が早く終われる気がする…。というわけで、やりかけだったA/D変換の続きです。

それはそうと、みんなのやす@大同工業大学さんから、「公開練習会 in ポートメッセなごや」のお知らせ! 今度はスケジュールOK!です。しかもロボファイト2の前の週なので、すごくいいタイミングです。いや〜、気合入ります。 ARUMO-SiR、持っていきます〜。荷物に余裕があったらG-Tuneも持ってきます。

とりあえず作って見る。
PSoCの方、とりあえずA/D変換のプログラムを作ってみました。MiniEval1のボリュームをまわすと、 4つのLEDがレベルメータのように点灯するというものです。SAR6のSample Clockに何を入れていいのかは相変わらずよくわからないので、 適当にやってみます。また、前回の調査で、SAR6をどこに割り当てても、PORT2[0]から信号を直接取り込むのは無理なことがわかりましたので、 PGA(Programmable Gain Amplifier)という、アナログ信号増幅モジュール(オペアンプの増幅回路かな)を倍率1にして組み込み、 その出力をSAR6に入力するようにします。そして、最後にA/D変換結果をプログラムで取り出し、 「PSoCのMiniEval1でLED点灯」で行った方法と同じ方法でLED点灯させるようにします。

それでは、まずProjectを作ります。

SCREEN SHOT
クリックで拡大します。
まずはどうするんだっけ?えっと、最初はとにかく「New Project」ですね。Project名は、レベルメータということで、 「LevMeter」にしてみました。
SCREEN SHOT
クリックで拡大します。
例によって「CY8C27443-24PXI」と「C」ファイルの生成を選択して「完了」をします。
SCREEN SHOT
クリックで拡大します。
はい、これで見慣れた「Device Editor」の「Selection」画面になりました。
SCREEN SHOT
クリックで拡大します。
それでは、A/D変換の「SAR6」と、増幅器の「PGA」を選択します(PGAは、増幅器といいながら、減衰もできるようです)。 「SAR6」は「ADCs」の中にあります。また、「PGA」は「Amplifiers」の中にあります。
SCREEN SHOT
クリックで拡大します。
で、「Interconnect」に切り替えて、まずは「Global Resources」の設定をします。 「Interconnect」に切り替えるには、メニューの「Config」−「Interconnect」と操作してください。 MiniEval1のボリュームは、5Vにぶら下がっていますので、0〜5Vの変化をすることになります。 そんなわけで「Ref Mux」を「[Vdd/2]+/-[Vdd/2]」と設定します。 あれこれ調べてみたら、どうもこれは「[Vdd/2]を中心として±」という意味のようです。なんだかわかりにくい表現ですね。 何かもっと深い意味があるんでしょうか…。マニュアルを見ても「Vss to Vdd」という表記があり、 この方がわかりやすいような気がします。
SCREEN SHOT
クリックで拡大します。
さて、ユーザモジュール、「PGA_1」と「SAR6_1」を「Place」します。どこに入るかわからなくても、 Device Editorが、勝手に入るべきところに入れてくれますので、順番に「Place」していけばOKです。
SCREEN SHOT
クリックで拡大します。
まずは「PGA_1」の方から設定します。「Gain」は直訳すると「利得」です。今回は、増幅する必要はありませんので、 「1.000」(1倍だから変化無し)を選択します。「Input」は「AnalogColumn_InputMUX_0」を選択します。 これについては、後で説明します。「Reference」は「VSS」としました。何がいいのか良くわからなかったんですが、 とりあえずボリュームが「VDD(+5V)とVSSに接続されている」ということで、これを選択しました。 で、最後の「AnalogBus」は、今回、出力を「SAR6_1」に接続するだけですので「Disable」(無効)とします。
SCREEN SHOT
クリックで拡大します。
「AnalogColumn_InputMUX0」ですが、これは、アナログ入力切替器と考えればよさそうです。 これを選択する事により、「PGA_1」の「Input」と「AnalogColumn_InputMUX0」が接続されます。 そして、その先にはポートがあります。
SCREEN SHOT
クリックで拡大します。
「AnalogColumn_InputMUX0」の接続先ポート(ピン)を設定します。ボリュームはPORT0[1]に実装されていますので、 「AnalogColumn_InputMUX0」を左クリックして選択メニューを表示し、PORT0[1]を設定します…って、最初からPORT0[1]になってました。 ま、ま、まずは操作手順を覚えるということで、はい。
SCREEN SHOT
クリックで拡大します。
続いて「SAR6_1」の方も設定します。「Selected User Modules」に表示されている「SAR6_1」を選択するとパラメータ設定表示がされます。 で、「SignalSource」(入力元)は「ACB00」にします。「ACB00ってなんぞや?」と思われるかもしれませんが、 先ほど「PGA_1」がPlaceされたブロックの上の部分を良く見ると、「ACB00」って書いてあると思います。 なんの略かは良くわかりませんが、これを指しています。つまり、この設定で「PGA_1の出力をSAR6_1へ入力」できるようになります。
SCREEN SHOT
クリックで拡大します。
というわけで、画面は左のような表示になったと思います。マウスカーソルのところに「1」って簡単に書いてありますが、 これは「VC1」のことです。「VC1」は、CPU_Clockを分周する回路?です。 その先は、3つのアナログブロックに接続されていますので、当然「PGA_1」にも接続されているわけでえすが、 ユーザーモジュールデータシートで確認すると、「PGA」はクロック不要のようですので、特に問題は無さそうです。 また、「SAR6_1」の出力先が無いですが、これは、プログラムの方から関数呼び出しによって取り出します。
SCREEN SHOT
クリックで拡大します。
最後にポートの設定をします。今回、LEDを点灯させますので、PORT2[0]からPORT2[3]までを「Strong」に変更します。 これで、LEDを点灯できるようになります。それでは最後に、「Generate Application」して「Application Editor」に切り替えます。
SCREEN SHOT
クリックで拡大します。
それでは、「main.c」を開いてプログラムを書きます。
SCREEN SHOT
クリックで拡大します。
さて、何を書いたらいいんだろう???というわけで、ドキュメントを見てみます。 ツールバーの「User Module Mini Bar」に「ADCs」と「SAR6」と設定してデータシートを呼び出すと…
SCREEN SHOT
クリックで拡大します。
「User Module Datasheet」が表示されます。で、「Sample」タブをクリックすると、まずはアセンブラのサンプル、 少し下にスクロールすると、Cのサンプルが表示されます。「SAR6_SetPower(3)」して「SAR6_cGetSample()」すればよさそうです。 実際に設定したUser Moduleの名前は「SAR6_1」ですので、プログラムを書くときには「SAR6_1_SetPower(3)」となります。 でも「3」ってなんでしょう…。さらに「API」タブをクリックすると、関数の仕様などがでてきます。 英語なのが難点ですが、どうやら「SAR6_HIGHPOWER」という意味のようです。せっかく定義されているようですので、 実際にコーディングするときは、「SAR6_1_HIGHPOWER」と書くことにします。 よく見ると、「SAR6_Start()」ってのもあるんですが、これはやらなくていいのかな?ま、まずはサンプルどおりにします。

同様にして、「PGA」の方を調べると「PGA_Start()」しておけばいいということがわかります。 こうやって使い方を調べます。

SCREEN SHOT
クリックで拡大します。
「SAR6」は、「-32〜31」で値を返します。これを、4つのLED+全消灯の5つの状態で表すようにプログラムを書いて見ました。 ひたすらSAR6から値を読みまくり、if文で値をチェックしてLEDを点灯/消灯しているだけです。
  CHAR  cData;

  PGA_1_Start(PGA_1_HIGHPOWER);
  SAR6_1_SetPower(SAR6_1_HIGHPOWER);

  while( 1 ){
    cData = SAR6_1_cGetSample();
    if( cData > -20 )  PRT2DR |= 0x01;    //  LED P2[0] ON
      else        PRT2DR &= ~0x01;        //  LED P2[0] OFF
    if( cData > -8 )  PRT2DR |= 0x02;     //  LED P2[1] ON
      else        PRT2DR &= ~0x02;        //  LED P2[1] OFF
    if( cData > 10 )  PRT2DR |= 0x04;     //  LED P2[2] ON
      else        PRT2DR &= ~0x04;        //  LED P2[2] OFF
    if( cData > 22 )  PRT2DR |= 0x08;     //  LED P2[3] ON
      else        PRT2DR &= ~0x08;        //  LED P2[3] OFF
  }
SCREEN SHOT
クリックで拡大します。
そんでは「Bulid」してプログラムも書きこんで、実行まで一気にやってしまいましょ (「2005/10/07 PSoCのMiniEval1でLED点灯」を参考にしてください)。

あれ?なんか変ですね…。ボリュームをぐりぐりすると、確かにLEDはちらちらするのですが、 思ったような動きでは無いです。0.5Vしか電圧が無いのにLEDが3つも点灯しています。ホントは全部消灯するはず。 ひょっとしてボリュームがガリガリしているのかな〜と思って、 試しにテスタをつないで電圧を測ってみましたが、電圧はちゃんと変わっています。

SCREEN SHOT
クリックで拡大します。
というわけで、再びSAR6のユーザーデータシートとにらめっこ…したものの、これだ!という設定は見つけられませんでしたが、 考えてみれば、設定できるのは「Sample Clock」だけです。「VC1」が入力されていますので、「VC1=SysClk/N」を適当にふやしてみると… お、なんかそれっぽくなってきました。

「6」ぐらいで、なんか微妙に点滅してる感じですが、ボリュームの動きにあわせてきれいに変化するようになりました。 どうも、入力している「Sample Clock」が速すぎるようです。そういうわけで、「8」にしたら、ぴたっと動くようになりました。 う〜ん、きっとどこかに書いてある、またはそれがわかるような文章があると思うのですが、どこに書いてあるんだろう?

 

2005/10/20

PSoC・SAR6に入れるクロック

相変わらずわかりませぬ。
ドキュメントを読むと、クロックは最大333kHzと書いてあるのを見つけました。でも、そのとおりに24MHzを分周すると、 72分周しないといけません。「VC1=SysClk/N」だけでは16までしか分周できませんので、さらにVC1の出力をVC2に入れて分周しないといけなくなります。 VC3を使えば256まで分周できるので一気に分周できますが、今度は、SAR6に入力することができません。う〜ん。

SCREEN SHOT
クリックで拡大します。

ひょっとして結果オーライかな?と思いつつも、あまりにもかけ離れているので、ひょっとしたら、「VC1=SysClk/N」の「SysClk」は、 「CPU_Clock」のことかな〜なんて思い始めました。ほら、「CPU_Clcok」って、「3_MHz(SysClk/8)」(デフォルト)になっているじゃないですか。 これで8分周したら64分周なので結構近い値になります。ということは、「CPU_Clock」を上げたらうまくいかなくなるんじゃないかな〜と、 早速実験してみました。こういうのがさくさくっとできるあたりがPSoCですね!

結果は…変わらず。うまくいっているようです。う〜む、不思議だ。

2005/10/21追記:別のプログラムを組んでいたら、やっぱ、「VC1=SysClk/N」の「SysClk」は、CPU_Clockの意味な気がしてきました (CPU_Clockが24_MHzだとうまくいかないのに、3MHzにしたらうまくいくようになったケース発生!)。

2005/10/21追記:さらに追記ですが…「えいや!」で、PWMによるLED点滅のプログラムを作って「CPU_Clock」を変更しながら様子を見てみました。 う〜ん、「VC1=SysClk/N」の「SysClk」は、やっぱり「SysClk」みたいです。ま、とりあえず、SAR6には333KHzを入れるのが手堅そう。

2005/10/21追記:またまた追記ですが…ドキュメントから、「VC1=SysClk/N」の「SysClk」は「SysClk」であることを確認しました。 ここに切り抜いて載せてもいいのかな…「Architectural Description」のところに、「PSoCクロックソースの概要」を説明する図がありまして、 SysClockが、それぞれ「CPU CLK」(マニュアルどおり記載)、「VC1」、「VC2」、「VC3」に入力されていることが書かれています。

 


SISO-LAB Knowledge