|
Author: akita
もくじ PSoCとはナニモノ? †語弊があるかもしれませんが、「周辺I/Oデバイスを自由に設定できるマイコン」です。PSoCの概要は、この分野の日本での第一人者(?)、桑野さんの解説が参考になるでしょう。 このPSoCを、とりあえずさわってみたいよ、という向きにおすすめなのが、PSoC First Touchです↓ こいつの中身は、2つ↓ 書き込み機(左)と、PSoCがのった小基板(右)。PCのUSBポートに書き込み機をつなぎ、小基板上のPSoCに、自分で作ったプログラムを書き込めます。小基板には、LED、明るさセンサ、ブザーなどがついていて、PSoCからつつけます。半田付けして基板を作らなくても、とりあえず遊べるのがお手軽ですね。 書き込み時は、↑こんなふうにドッキングして使います。 小基板に載っているものは、↑こんな感じ。 (技術情報)
例えばP0.1は、ポート0の1番、のピンを表しています。 開発ソフトウエアの導入 †まずはPSoCで遊ぶためのコンパイラなどの開発ソフトウエアを導入しておきましょう。以下のものを導入しておきます。 ※(2008/10/15追記:PSoC Designerがv5.0にバージョンアップしました。多少画面が変わっていますが、基本的には同じなので、適宜読み替えながら進めてください。
各ソフトウエアのインストールのうち、PSoC Programmerのインストール時には、デバイスドライバのインストール ウイザードが立ち上がりますので、とりあえず、すべて「はい」「次へ」を選んでおきます。 ※PSoC Designerのインストールの後半で、コンパイラ(HITECH-C)のインストールがありますので、Cancelしないように注意。 ※PSoC Designer5.0以上のバージョンを使う場合はCコンパイラが内部に付いているので、以下の内容を無視してください。 また、PSoCで末永く遊ぶためには、Cコンパイラが欠かせません。ただし、これは売り物です。MeRLのみなさんは、ライセンスがありますので、秋田へ相談してください。 ここにインストールマニュアルが置いてありました。 また、HITECH-Cコンパイラは、Forumがあるので、困ったことがあったら頼ってみるとよいでしょう。 試しになんか作ってみる:LEDと光センサ †これからやること †スタート→Cypress Microsystems→PSoC Designerで、PSoCでプログラムを書くためのアプリケーションPSoC Designerを立ち上げます。
この1.が、他のマイコンにはない、PSoCの特長といえます。マイコンは、一般にはタイマ、A/Dコンバータ、パルス出力、シリアル通信、などのいろいろな機能を持つ周辺I/Oデバイスが内蔵されていて、それをつかってマイコンは実世界とつながるわけですが、一般のマイコンは、この周辺I/Oデバイスの種類と数は、製品によって決まっています。つまり、A/Dコンバータが1個しかないマイコンは、いくらA/Dコンバータが2個ほしい!と思っても、どうしようもありません。ところが、PSoCは、(内部リソースが許す限り)好きな周辺I/Oデバイスを作り、それを使うことができます。例えばパルス発生回路が16個あるような、化け物のようなマイコンも、普通に作れます。 はじめに:プロジェクトの作成 †まず、PSoC Designerを立ち上げると、新しいプロジェクトをはじめるウイザードが始まるので、初期設定をしておきましょう。 ↓新しいプログラムを書くので、Start New Projectを選びます。 ↓プログラムファイルなどを置いておくディレクトリ(フォルダ)を指定し、プロジェクトの名前を決めます。たとえばled_testのようにしておきましょう。 ↓使うPSoCの種類を選ぶ画面になります。ViewCatalog?を押して、使うPSoCを選びます。 ↓こんな感じで、いろんなPSoCが一覧表で出てきます。今回使う、PSoC First Touchの小基板に載っているPSoCは、CY8C21434というやつですので、そいつを探して、Selectボタンを押します。 ↓めでたく、CY8C21434が選ばれました。ついでに、プログラムを書くのに使う言語を選びます。Cコンパイラを導入してあれば、迷わずCを選んでおきましょう。 使うモジュールを配置する †↓プロジェクトの作成がすむと、こんな感じの画面になると思います。これは、PSoCの周辺I/Oデバイスを設定するDevice Editorのうちの、使う周辺I/Oモジュールを選ぶUser Module Selection Viewというものです。(名前が長いですね) 今回は、次のような機能を持つものを作ってみることにします。
明るさセンサから明るさを読み取るにはA/Dコンバータを使います。またLEDの明るさを変えるには、PWM (Pulse Width Modulation)というモジュールを使います。これは、パルスの1周期のうちでON(1)の時間を変えることで、近似的にLEDの明るさを変える、というものです。(ONの時間の比率が高いほど、明るく光る) まずは、今回使う、A/DコンバータとPWMを、使えるように選んでおきましょう。 ↓左端に、使えるモジュールが並んでいます。このうち、PWMsを選び、その中のPWM8をダブルクリックします。そうすると、中央上側の枠の中に、PWM8モジュールが、PWM8_1という名前がついて現れます。 ↓同じように、ADCsの中のADC8を選んでおきましょう。名前はADC8_1となります。 使うモジュールを配線する †これで、使いたいモジュールを選び終わったので、こいつらを、実際に使えるように配置をします。その配置は、Device Editorの、Interconnect Viewという画面で行います。 ↑の右端のボタンを押して、Interconnect View画面に移ります。 ↓Interconnect View画面では、四角と縦線、横線がたくさんありますね。四角はモジュールを構成するブロックが配置される場所、縦線と横線は配線で、これらをうまくつないで、ブロックどうしや、PSoCの外のI/Oピンとつなぎます。この画面は、ADC8_1を1回クリックした状態ですが、ADC8_1で使うブロックが、薄く水色と緑の枠がかかっています。 このまま、ADC8_1を右クリックしてPlaceを選べば、実際にPSoCの中で配置されて使えるようになるのですが、今回は、ちょっと事情により、配置する場所を変えます。 ↑この(1)のボタンで、次に配置可能な場所に移ります。 ↓このような状態になったら、さきほどの(2)のボタンを押して配置(Place)します。 ↓ADC8_1が配置されました。配置されたブロックが、ADC8_1の枠と同じ青色になっています。 ↓同じように、PWM8_1も配置しておきます。このPWM8_1は、どこでもかまいません。 ちなみにInterconnectView?画面では、次のようにして画面を拡大したり移動したりできます。
次は、ADC8_1とPWM_1を、PSoCの外につながるピンに接続します。さきほどの表を見ると、明るさセンサはP0.6に、青LEDはP1.2につながっていることがわかるので、これにあわせましょう。 まずADC_8の入力をP0.6につなぐため、次の2段階をふみます。 ↓AnalogColumnInputSelect_1がP0.4になっているので、それを選びます。 ↓出てくるメニューからPort0_6を選ぶと、こうなります。 ↓次に、ADC8_1のADC Inputと書いてあるところをクリックすると、ADC8_1の入力をどこにつなぐかを選ぶメニューが出てきます。 ↓このメニューから、AnalogColumn? InputSelect_1(さっき、Port0_6を選んだやつ)を選ぶと、そこにつながります。配線を追いかけて、Port0_6につながっていることを確認しておきましょう。 次に、PWM8_1の出力を、青LEDがつながっているP1.2につなぎます。 ↓InterconnectView?画面の右上の方に並んでいるI/Oピンのうち、Port_1_2をクリックすると、そのピンをどこにつなぐか選ぶメニューが出てきます。ここから、GlobalOutOdd_2を選びます。(左上の方にも並んでいますが、こいつらは入力ピンとして使うときに使います) ↓このGlobalOutOdd_2というのは、右の方に縦に並んでいる配線のうちの1本で、こんなかんじでPort_1_2が接続されます。(上に書いてあるGOOというのが、GlobalOutOdd?の略) ↓次に、PWM8_1の下に並んでいる横線(Row_0_Ouptut_2)と、さきほどの縦線(GlobalOutOdd_2)をつなぐことにします。 ↓Row_0_Output_2の右端についている四角をクリックすると、こんな画面が現れます。このうち、GlobalOutOdd_2につながっている三角を選ぶと、その三角(バッファ)を使うかを選ぶメニューが現れるので、GlobalOutOdd_2を選びます。(デフォルトでは、このバッファはOffになっているので、結果としてRow_0_Output_2とGlobalOutOdd_2はつながっていない) ↓Row_0_Ouptut_2とGlobalOutOdd_2がつながりました。 ↓最後に、PWM8_1の出力(CompareOut?)を、横線(Row_0_output_2)につないでおきます。PWM8_1のCompareOut?をクリックすると、その出力をどこにつなぐかを選ぶメニューが出てくるので、Row_0_Ouptut_2を選んでおきます。 ↓PWM8_1のCompareOut?出力が、Row_0_Output_2につながりました。 ↓だいぶまわりくどかったですが、結果として、PWM8_1のCompareOut?出力が、青LEDがつながっているPort1_2につながっていることを確認しておきましょう。 使うモジュールを設定する †配置したPWM8_1とADC8_1に必要な設定をしておきます。まず、クロック周りの設定をします。 ↓左上の方に、PSoC全体に関係する設定をする箇所があります。この中のVC1=SysClk?/N のところを16にしておきます。 PSoCの内蔵クロック(24MHz)を何分の1かに分周してVC1という名前のクロック信号として使うのですが、この分周比を16とすることで、VC1は24MHz/16=1.5MHzのクロック信号となることになります。 続いて、PWM8_1の設定を行います。主な設定項目は、
PWM8_1を上の枠の中で選ぶと、PWM8_1のパラメータの設定画面が左端中央に出てきます。とりあえず↓このように設定しておきます。 この例では、PWM8_1で使うクロック信号がVC1(さきほど1.5MHzに設定しました)、周期が255カウント、となっています。PWM8_1から出てくるパルスの周波数は、クロック信号をこの周期分カウントするのにかかる時間がそのパルスの周期なので、1.5MHz/256=5.9kHzとなります。 [けっこうはまることが多いので注意]ちなみにここにClockSync?という項目があります。これは、モジュールに与えられるクロック(ここではVC1)を、システムクロック(SYSCLK=24MHz)に同期させるかどうか、という選択です。無難なのは、Unsynchronized(同期させない)、あるいはSync to SYSCLK(SYSCLK=24MHzに同期)です。デフォルトのUse SYSCLK Directだと、せっかくClock源をVC1にしていても、文字通りSYSCLKが使われてしまい、PWM8_1は24MHzのクロックで動いてしまうので、注意。(デフォルトがこのDirectというのは、いかがなものか、と個人的には思いますが、しょうがない) 続いて、ADC8_1の設定をしましょう。 といいつつ、ADC8_1は、けっこう複雑なので、そのデータシートに目を通しておきましょう。メニューバーの中に、モジュールのデータシートを見るボタン(↓の右端)があるので、ADC8を選んで押してみましょう。 だーっと読んでみると、与えるべきクロック周波数が書かれている箇所があります↓ ADC8には、0.24MHz〜2.4MHzのクロックを与える必要があることがわかります。今の場合は、さきほどのVC1が1.5MHzでしたから、さしあたって、このVC1を与えればよさそうです。 ↓これらをふまえて、ADC8_1の設定を以下のようにしておきましょう。 これで、使うモジュール(PWM8_1とADC8_1)の設定がおわりました。この設定に基づいて、プログラムを書き始めるために、Config -> Generate Application を実行しておきます。 ・・・長かったですね。 プログラムを書く †↑このボタンの、左から2番目のボタン(青っぽい)を押すと、プログラムを書くためのApplication Editor画面↓になります。 ↓左端のSource Filesの中のmain.cをダブルクリックすると、プログラムを書くべきmain.cが現れます。 さて、いよいよプログラムを書くわけですが、今回はメインでやることは非常に単純で、
↓というわけで、こんなプログラムになります。 最初のほうのPWM8_1_Start()は、PWM8_1モジュールを使い始める関数、その次のM8C_EnableGInt〜ADC8_1_StartADC()までは、ADC8_1モジュールを使い始めるまでのおまじない、です(実はADC8_1のデータシートに載っているサンプルのまんま) メインのwhileループは、次のとおりです
ちなみにPWM8_1_WritePuseWidth?などの関数は、PWM8のデータシートに載っています。各データシートのサンプルコード(Sample Code)が参考になりそうですね。 プログラムを書き終わったら、Build → Buildでコンパイルします。 ↑無事コンパイルがおわったら、めでたしめでたし。エラーが出た場合は、そのエラーメッセージを参考に、デバッグしましょう。 書き込み †いよいよ、作成したプログラムをPSoC First Touchの小基板のPSoCに書き込んで動作させてみましょう。 PSoC First Touchの2つの部分をドッキングした状態で、PCのUSBポートに接続すると、ドライバをインストールする画面が現れるので、自動的にインストール、を選べば、あとは自動でドライバが入るはずなので、終わるまで待ちます。 ↓PSoC DesignerのProgram → Program partを選ぶと、書き込みを行うPSoC Programmerが立ち上がります。 ↓左上の方のPortから、使う書き込み機を選びます。 ↓無事選ばれました。ついでに、書き込み対象のPSoCであるCY8C21434を選ぶため、Device Familyは21x34を、DeviceはCY8C21434を選んでおきます。 ↓作成したプログラムをコンパイルした結果を開くため、File Loadを押すと、書き込みするファイルを選ぶ画面が現れるので、いま作ったプログラムのプロジェクトのディレクトリ(フォルダ)の下のフォルダoutputの中にある、*.hex(この場合はled_test.hex)を選んでおきます。 ↓Programを押せば、プログラムの書き込みがはじまるので、少し待ちます。(10秒くらい?) ↓書き込みが終わるとき、なぜかChecksum Failedと出るようですが、ちゃんと書き込みができているようなので、気にしないことにします。 書き込みが終わると、すぐにプログラムの動作は始まっています。どんな感じでしょう? 例題1 †
CapSense?で遊ぶ †PSoC(の一部)では、容量検知型の、タッチセンサを使えます。ポチポチおすスイッチの代わりに、電極に触れるだけでスイッチの代わりにできたり、あるいは複数並べて、触れている位置を検知するスライダーにもできます。 このタッチセンサの機能は、CapSense?というモジュールを配置することで、簡単に使えます。 新しいプロジェクトを始めたあと、ユーザモジュールの選択のときに、CapSensors?の中のCSDというモジュールを選びます。 続いて、CSDモジュールを配置後、CSD_1を右クリックして現れるメニューの中から、「CSD Wizard」を選ぶと、↓このような画面が現れます。 これは、タッチセンサとして使うボタンの数と、そのボタンの代わりに使う電極をPSoCのどのピンにつなぐかを指定します。 ↓ここに、右側の中からP2[0]をドラッグすると、SW0という名前のタッチセンサとしてP2[0]につながっている電極(青色のビニール線)を使う指定ができるので、OKを押して終了します。 ↓続いて、CSDモジュールの設定を、次のようにしておきます。Modulator Capatitor, Feedbank Resistorは、この基板ではこのピンにコンデンサと抵抗がついているので、この通りに指定します。Referenceは、VBG(内蔵のBandgap Reference)を使います。 ついでに、LEDがつなげたPWM8モジュールも配置し、最初の例と同じように設定・配線しておきます。 ↓その後、次のようなプログラムを書いてみましょう。(実はCSDモジュールのデータシートのSampleCode?のほぼパクりです) 最初の方はおまじないですが、関数名が、そのまんまの名前なので、だいたいやっていることはわかるかと思います。要は、初期化をしたあと、while(1)の中で、タッチセンサの値を読んでいます。 このタッチセンサは、ある程度、ですが、電極までの距離もわかります。 さらにCSDモジュールは、複数の並んでいる電極をつないで、指がどの位置に触れているかという場所を求めることもできます。(Slide機能) ↓CSD Wizardで、N Slidersを1にしてみましょう。下の方に、構成するスライダを構成する電極数を入れる場所があります。この小基板にはP2[1]〜P2[7]に7個の並んだ電極がつながっていますので、それぞれ指定しておきます。また、その7個の電極の並びで、指が触れている位置を、何段階で検出するか、をResolutionとして指定できます。今回は、PWM8_1の分解能と同じ8ビット(255)としておきましょう。 ↓プログラムは、タッチセンサの場合とほぼ同じです。スライダの位置(触れている場所)は、CSD1_wGetCentroidPos?(k)で求められます。(ただしk=1が、1つめのスライダ)今回は、その値が0〜255で求められることにしていました(先ほどのResolution)ので、そのままPWM8_1のデューティー比として書き込んでいます。 タイマ割り込み †割り込みを使うと、main()関数の中のwhile(1)ループをまわしながら、定期的にある関数を実行したり、あるいは何かの入力があったときにある関数を実行する、ということができます。 割り込みの使い方の例として、タイマ割り込みを使って、定期的にLEDの明るさを変えてみましょう。 次のステップをふんでみてください。
(注意)HI-TECHのコンパイラでコンパイルすると、アドレス割り当てしてください、っていうWarningがでますが、これは自動でしてくれるので無視してかまいません。 書き込み器からの独立 †お気づきの方も多いと思いますが、書き込みを終わったあとは、書き込み機は、特にすることはありません。しいていえば、小基板に電源を供給しているだけです。 つまり。 電源さえつなげば、小基板を切り離して動作させることができるわけです。 書き込み機につながるコネクタに、ヘッダピンをつないで、First Touch Document.pdfに載っているピン配置を参考に、VCCとGNDの間に+5Vを供給すればOKです。
ケーブル側のUSBコネクタ↓には4本の端子がありますが、差し込む先のほうから見て、下の写真で、右端が+5V、左端がGNDです。 ↓手持ちの不要なUSBケーブルを切断して作ってもいいですし、USBコネクタに自分でビニール線をつないでもOKです。こういうのを1本持っておくとよいでしょう。 USBコネクタの反対側、自分の機器につなぐ側のコネクタは、なんでもよいのですが、MeRL標準としては、いわゆるφ2.1mm DCプラグ↓、をおすすめします。 これにそろえておくと、みんなで使い回しができて便利です。 自分の機器側には、↑の受け側(ジャック)を穴あき基板などに取り付け、その基板上に小基板をつなぐコネクタなどをつけると完成です。 PCとの遭遇 †FirstTouch?の小基板は、いろいろなセンサがついていますが、PCとつないで、いじれると、楽しそうです。 PCのシリアルポートは、RS232という規格にそっていて、0と1を、それぞれ+7V以上、ー7V以下、という電圧で表すことになっています。 また、最近のPCは、シリアルポート(COMポート)がないものが増えてきて、USB-シリアル(COMポート)変換器、というのを使えば、シリアルポートの代わりに使えるのですが、先ほどの電圧レベルの関係で、マイコンには直接つなげません。この電圧レベルの変換をしているIC(MAX232というやつが有名)も市販されているのですが、PCとつなぐマイコン機器をつくるたびに、このICを使うのは、ちょっと面倒です。 そこで、USBから、マイコンのI/Oポートと同じ電圧レベル(いわゆるTTLレベル:1=+5V程度、0=0V)の調歩同期式シリアルに変換するICが市販されていますので、それをつかって、USBからマイコンの調歩同期式シリアルポートにつなぐアダプタをMeRLで準備しています↓。 黒い4ピンのコネクタをマイコン側に、USBコネクタ(miniB)をPCのUSBポートへつなぎます。PC側では↓このドライバを使うと、COMポートとして扱えます。(割り当てられるCOMポートの番号は、接続後にデバイスマネージャのポート、の中に現れるCP210x...についている番号で確認する) なおマイコンと調歩同期式シリアル通信を行うときには、1バイト単位でデータを送受信できると便利なことが多いので、↓このアプリを入れておくとよいでしょう。 マイコン側の基板(小基板をつなぐ基板など)には、4本の一列のピンヘッダを立て、順番に次のように接続します。(受信ピン、送信ピン、は、あとでPSoCで割り当てるので、後ほど・・・)
マイコンの中で調歩同期式シリアル通信を行うモジュールを、UART (Universal Asynchronous Receiver & Transmitter)と呼びます。PSoCも、Digital Communicationカテゴリの中にUARTというモジュールがあるので、これをつかえばPCと調歩同期式シリアル通信をすることができます。
PCから送ったデータに基づいて、LEDの明るさを変えられるようにすると、PSoCを征服した感があって、楽しいかもしれません。 |