ブレッドボードで簡単PSoC
by K.I
2006/06/16 〜
Index
- 8PINのPSoC、 CY8C27143を使って何か作りたいと思って、買ってあったんだけど、ずっとそのままになってた。
- これはXRES端子が無いから、どうやって書き込んだら良いんだろとか思ってたんだけど。
- PastelMagicのBBSを覗いてみると
- ectoyfanさんやJUNKBOXさんの書込みから、XRESが無い奴は接続しなくても良いらしいってことが分かった。
- まぁ、ちょっとハッキリしない事もあるけど、これはやってみれば良い事だよね。
- 話題になってる、Designer4.3β版もも試してみたいなぁ。。
- ピン数は8ピンと少ないけど、CY8C27443とかと内部の構成は同じなので、同じ回路が組める。
- 当然、配線も少なくて済むから楽チンだ。
- でも、ピン数が少ないので作ることが出来るアプリケーションがかなり限られてしまう欠点もあるけど。。
1こちらもPSoCの電子工作、いろいろ試されているようです。
[top]
- まずは、書き込めるかどうか確かめるために、LEDを点滅させてみる。
→MiniProgは裏返しに繋いでるので注意!
- PSoC Designerを起動して、新規プロジェクトを作成。
- Select Base Partで、CY8C27143-24PXIを選ぶ。
- PSoCとしては邪道2かもしれないけど、DeviceEditorを使わずに、ApricationEditorのプログラムだけでやってみる。
- プログラムは、これだけ。
- 確かに点滅してます。→約100kHz..これじゃ点滅とは言えないけどね。。
- おまけで、CY8C27443でもやってみよう。
- LEDは同じポートに繋いでるので、プログラムの変更は必要ない3。
- 右側にMiniProgを繋いだ方が配線が簡単になるなぁ。
- ということで、CY8C27143も組み直してみた。ちょっとだけスッキリしたかな。
- 27143はXRESを繋がないけど、見比べてみて分かるように、ほとんどピン配置は一緒。
- 配線には秋月のブレッドボード・ジャンパーワイヤキットを使ってる。
- これを基本セットにして、いろいろ作ると良さそうだな〜。
2ポート設定は、DesignerのDeviceエディタでやるのが正道なんだろうけど。。
3プロジェクトは作り直す必要があるけど。
[top]
- 新しい PSoC DesignerのBeta版が出たので、試しに使ってみよう。
- 元々、Designer4.2と$10キットのCライセンスが入っている状態だが、そのままインストールしてみる。
- やってみると、4.2をアンインストールしないとインストール出来ないということなので、アンインストールする。
- それで、改めてインストールする。今度は無事インストール出来たようだ。。
Registering LPTICE driver
- 何か、上記のような小さなウィンドウが出たままになってる。まぁ良いか。。
- Cのコンパイルを試してみるが、問題無く出来るようだ。→ライセンスは、とりあえず引き継がれるのね。
- 4.3では、新しいモジュールが追加されている。
- 他にもあるかもしれないが、以下のようなものがある。
- LED →これが噂の、ただのLED。。アイコンに変な輪っかがついてる
- 7SegLED →意外と便利かもしれないが、LCDを使うことが多いからなぁ。
- 輪っか付きのアイコンは、Placeの必要が無い(出来ない)みたいだ
→ 今後は、こんな風に輪っかアイコンで動作を区別するのかしらん?元からこうだっけ?
- SleepTimer →スリープが簡単に使えるんだろうか?(これ元からあったかも。。。)
- これらは、全部ソフトウェアモジュールなので、デジタルブロック、アナログブロックを消費しない。
- ぶっちゃけ、タダのサブルーチンなんだけど、モジュールになっているとプログラムを部品としてイメージし易い気がする。
- ということで、スリープとLEDを使ったプロジェクトを作ってみる。SleepTimerのサンプルそのまま。
- でも、以下のエラーでコンパイルに失敗する。
Starting MAKE...
creating project.mk
C:\PROGRA~1\CYPRES~1\PSOCDE~1\tools\make: *** No rule to make target `lib/SLEEP~.INC'. Stop.
lib/led_1.asm
lib/psocconfig.asm
lib/psocconfigtbl.asm
C:\PROGRA~1\CYPRES~1\PSOCDE~1\tools\make: *** No rule to make target `lib/SLEEP~.INC', needed by `lib/obj/sleeptimer_1.o'. Stop.
- なんだこれ?さっきの変なウィンドウの所為かな?再インストールでリペアしてみる。
- やっぱりダメだ。Build Allしてもダメでした。
- このエラー前にも見たことあるなぁ。
- 確かプロジェクトのクローン作成で、8文字以上のファイル名を付けた時に出たんだっけ。
- でも、今度は標準のモジュール名だしなぁ。
- ダメ元でモジュール名を、SleepTimer_1→Sleep_1と短くしてみる。
- 今度はコンパイル出来た! でも、こんな単純なBUGって普通はなさそう。
- 自分の環境の問題かなぁ。ソースをネットワークドライブに置いてるからかしらん?
#include "m8c.h"
#include "PSoCAPI.h"
void main()
{
M8C_EnableGInt ; // Turn on interrupts
Sleep_1_Start();
Sleep_1_SetInterval(Sleep_1_64_HZ); // Set interrupt to a
Sleep_1_EnableInt(); // 64 Hz rate
LED_1_Start();
// The following loop should loop no faster than 8 Hz (64/8)
while(1) {
Sleep_1_SyncWait(32, Sleep_1_WAIT_RELOAD);
LED_1_Invert();
}
}
- これだけで、ちゃんと1秒間隔で、LEDが点滅する。
- SleepTimerモジュール、なかなか良いね。
- でも、Designer4.3のリリースノートに、SleepTimer載ってないな〜。これは元から有ったのかぁ。
- いつのまにか、Designer4.3は正式リリースしてるし。。。
- LEDモジュールの使い勝手は、自分的には、ちょっと微妙かな。。
- でもI/O設定を間違えずに行えるのと、プログラムが見やすくなるってところは良いのかな。。
[top]
- 8ピンのPSoCでは、ピン数制限からシリアルに入出力を行うアプリケーションが多くなる。
- まずUARTを使って、PCのCOMポートに繋いでみよう。
- 入出力は6ピンしかないので、MiniProgが接続されているポートをシリアルインターフェースに使う。
- LEDを、P0[5]に接続する。
つまり、配線はLEDの点滅回路と全く同じということだ。
- で、MiniProgの代わりに、RS232Cドライバを繋ぎ換えることが出来るようなコネクタを作成した。
→MiniProgの代わりに、Comポートへ接続するアダプタを作っておくと便利。
- UARTは以前 試したことはあるが、結構、端折っている4ところもあるので、たまには真面目に設定から記述してみる。
- UARTの通信速度を9600bpsとすると、UARTモジュールは×8のクロックを必要とするので、
- VC3=24MHz/12/26/8=9615.4≒9600bpsということにする。
- DeviceEditorのGlobalResourceで、以下のように設定する。
- これは、9600bpsのボーレートクロック発生用だ。
Global Resource | Value |
VC1=SysClk/N | 12 |
VC3 Source | VC1 |
VC3 Divider | 26 |
- UARTモジュールを配置したら、以下のように設定。
User Module Parameters | Value | 説明 |
Clock | VC3 | VC3=24MHz/12/26/8=9600bps |
RX Input | Row_0_Input_1 | GlobalInOdd1経由でP1[1]に繋ぐので.. |
TX Output | Row_0_Output_0 | GlobalOutOdd0経由でP1[0]に繋ぐので.. |
TX Interrupt Mode | TXComplete | よく分からないので適当に |
ClockSync | Sync to SysClk | まぁ SysClk に合わせとけば良いか。。 |
RxCmdBuffer | Enable | 当然バッファが無いとダメでしょう |
RxBufferSize | 16 | デフォルトのまま |
CommandTerminator | 13 | コマンドの終りはリターンコード |
Param_Delimiter | 32 | コマンドの区切りはスペース |
IgnoreCharsBelow | 32 | スペースは基本的に無視するってことか? |
Enable_BackSpace | Backspace | 何となくバックスペースを有効にしてみる |
RX Output | None | よく分からないのでNone |
RX Clock Out | None | 同上 |
TX Clock Out | None | 同上 |
InvertRX Input | Normal | RXを反転しない |
- 説明を書いてみると、結構イイカゲンに設定してることが良くわかるなぁ。。。
- まずシリアルインターフェースのコマンドを決めよう。
コマンド | パラメータ | 戻り値 | 説明 |
R | なし | 起動メッセージ表示 | リセット |
O | 0 or 1 | なし | LEDの消灯・点灯(0で点灯、1で消灯) |
I | なし | LEDの状態 | LEDの状態を調べる |
X | なし | 反転後のLEDの状態 | LEDの状態を反転 |
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
// ---- Main program
void main()
{
char *cmd,*para; // Parameter pointer
reset: // reset command
// ---- UART setup
UART_1_CmdReset(); // Initialize receiver/cmd buf.
UART_1_IntCntl(UART_1_ENABLE_RX_INT); // Enable RX interrupts
UART_1_Start(UART_1_PARITY_NONE); // Enable UART
UART_1_CPutString("\r\nWelcome to PSoC UART program by K.I\r\n");
// ---- LED setup
LED_1_Start(); // maybe GPIO setup
// ---- UART loop
while(1) {
if (UART_1_bCmdCheck()) { // Wait for command
if (cmd = UART_1_szGetParam()) { // get command
switch (*cmd) {
case 'R': // Reset
goto reset;
case 'O': // LED Output
if (para = UART_1_szGetParam()) {
if (!strcmp(para,"1"))
LED_1_Switch(1);
else
LED_1_Switch(0);
}
break;
case 'I': // LED Input
UART_1_PutChar('0'+LED_1_GetState());
UART_1_PutCRLF();
break;
case 'X': // LED Invert
LED_1_Invert();
UART_1_PutChar('0'+LED_1_GetState());
UART_1_PutCRLF();
break;
}
}
UART_1_CmdReset(); // Reset command buffer
}
}
}
- これで良いんじゃないかと思うんだけど、Txを表示するが、Rxがコマンドを全く受け付けない。
- 以前にも似たようなことがあった。その時は、RxをGlobalOutパスに繋いでたんだけど。。。
- USB-RS232Cアダプタ経由で、さらにRS232Cドライバを通して、PSoCに接続している。
- COM1から普通のシリアルケーブルで、RS232Cドライバを通して、RxとTxを直結してみる。
- 今度は、ハイパーターミナルで打った文字は、そのまま表示される。
- これなら、大丈夫とやってみたが、やっぱりRxがダメ。参った。
- プログラムをもう一度、眺める。サンプルと見比べる。。。。。ん。あ”ーーーー。
- ということで、プログラム直したら、動きました。
- 以前作った奴をカットペーストして作ってたので、抜けちゃってたよ。。答え→6
- 関係ないところも、ちょっとだけ手直する。PSoCのUARTモジュールって、やっぱり使いやすいな〜。
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
// ---- Main program
void main()
{
char *cmd,*para; // Parameter pointer
reset: // reset command
// ---- UART setup
UART_1_CmdReset(); // Initialize receiver/cmd buf.
UART_1_IntCntl(UART_1_ENABLE_RX_INT); // Enable RX interrupts
UART_1_Start(UART_1_PARITY_NONE); // Enable UART
UART_1_CPutString("\r\nWelcome to PSoC UART program by K.I\r\n");
M8C_EnableGInt ; // Turn on interrupts! →これが抜けてた。。
// ---- LED setup
LED_1_Start(); // maybe GPIO setup
// ---- UART loop
while(1) {
if (UART_1_bCmdCheck()) { // Wait for command
if (cmd = UART_1_szGetParam()) { // get command
switch (*cmd) {
case 'R': // Reset
case 'r': // Reset
UART_1_CPutString(">Reset \r\n");
goto reset;
case 'O': // LED Output
case 'o': // LED Output
if (para = UART_1_szGetParam()) {
UART_1_CPutString(">Output ");
UART_1_PutString(para);
UART_1_PutCRLF();
LED_1_Switch(atoi(para));
}
break;
case 'I': // LED Input
case 'i': // LED Input
UART_1_CPutString(">input ");
UART_1_PutChar('0'+LED_1_GetState());
UART_1_PutCRLF();
break;
case 'X': // LED Invert
case 'x': // LED Invert
UART_1_CPutString(">invert ");
LED_1_Invert();
UART_1_PutChar('0'+LED_1_GetState());
UART_1_PutCRLF();
break;
}
}
UART_1_CmdReset(); // Reset command buffer
}
}
}
4久々に見ると自分でもどうやったのか良く分からん書き方してるなー。反省。
5何でこうなるんだろ?これはこれでちょっと疑問なんだけど。。
6グローバル割込み許可が抜けてました。
[top]
- Gセンサの2番ピンをVDDに接続する必要7がある。5番ピンはGND。
- そういえば、PSoCのA/Dモジュールって全く使ったことが無かったなぁ。どれを使えば良いんだろ?
- DeviceEditorでADCモジュールを物色8してみる。。。
- おぉ、TRIADCって、3つ一度にデータ取り込むのかぁ。3軸Gセンサーにぴったりじゃん!
- 8bitで十分だから、TRIADC8モジュールを使うことにする。
- バッファとして1倍のPGAを通して、A/Dに入力するように配線する。
- で、コマンドインターフェースを考えてみる。UARTのプログラムに、gコマンド(gセンサモード)を追加しただけ。
コマンド | パラメータ | 戻り値 | 説明 |
R | なし | 起動メッセージ表示 | リセット |
O | 0 or 1 | なし | LEDの消灯・点灯(0で点灯、1で消灯) |
I | なし | LEDの状態 | LEDの状態を調べる |
X | なし | 反転後のLEDの状態 | LEDの状態を反転 |
G | なし | X,Y,ZのA/D出力値 | 再度Gコマンドを入れるまで、値を連続表示する |
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include <stdlib.h>
// ---- Main program
void main()
{
char *cmd,*para; // Parameter pointer
char line[10];
char g1,g2,g3; // G sensor result
char mode=0;
reset: // reset command
// ---- UART setup
UART_1_CmdReset(); // Initialize receiver/cmd buf.
UART_1_IntCntl(UART_1_ENABLE_RX_INT); // Enable RX interrupts
UART_1_Start(UART_1_PARITY_NONE); // Enable UART
UART_1_CPutString("\r\nWelcome to PSoC UART program by K.I\r\n");
M8C_EnableGInt ; // Turn on interrupts!
// ---- TRIACD8 setup
TRIADC8_1_Start(TRIADC8_1_HIGHPOWER); // Turn on Analog section
TRIADC8_1_GetSamples(); // Start ADC to read continuously
// ---- LED setup
LED_1_Start(); // maybe GPIO setup
// ---- UART loop
while(1) {
if (UART_1_bCmdCheck()) { // Wait for command
if (cmd = UART_1_szGetParam()) { // get command
switch (*cmd) {
case 'r': // Reset
UART_1_CPutString(">Reset \r\n");
goto reset;
case 'o': // LED Output
if (para = UART_1_szGetParam()) {
UART_1_CPutString(">Output ");
UART_1_PutString(para);
UART_1_PutCRLF();
LED_1_Switch(atoi(para));
}
break;
case 'i': // LED Input
UART_1_CPutString(">input ");
UART_1_PutChar('0'+LED_1_GetState());
UART_1_PutCRLF();
break;
case 'x': // LED Invert
UART_1_CPutString(">invert ");
LED_1_Invert();
UART_1_PutChar('0'+LED_1_GetState());
UART_1_PutCRLF();
break;
case 'g': // Gsensor mode
mode ^= 1; // switch mode
break;
}
}
UART_1_CmdReset(); // Reset command buffer
}
if (mode) {
UART_1_CPutString(">gsensor ");
while(TRIADC8_1_fIsDataAvailable() == 0); // Wait for ready
g1 = TRIADC8_1_cGetData1(); // ADC Input1
g2 = TRIADC8_1_cGetData2(); // ADC Input2
g3 = TRIADC8_1_cGetData3ClearFlag(); // ADC Input3 & clear flag
UART_1_PutString(itoa(line,g1,10));
UART_1_PutChar(',');
UART_1_PutString(itoa(line,g2,10));
UART_1_PutChar(',');
UART_1_PutString(itoa(line,g3,10));
UART_1_PutChar('\r');
}
}
}
- 動かしてみると、A/Dのデータは取れているみたいなんだけど。。。
- A/Dの値が適当に変動している。フローティングに近い感じがする。
- サンプリングが速過ぎるのか?
- VC1=SysClo/12だから2MHz。データシートでは8MHzだからOKだと思うけど、VC2=VC1/16を使うことにする。
- RefMuxはVdd/2±BandGaじゃダメかも。
- アナログ関連のパワーを上げておく必要はあるかも。。
- 以前、これで引っかかったことがあったような気がする。
- それで、グローバルリソースは、UARTの設定に加えて、
Global Resource | Value |
VC2=VC1/N | 16 |
Analog Power | SC On/Ref High |
Ref Mux | [Vdd/2]+/-[Vdd/2] |
Op-Amp Bias | High |
A_Buff_Power | High |
User Module Parameters | Value | 説明 |
ADC Input1 | ACB00 | PGA1を通してデータ入力 |
ADC Input2 | ACB01 | PGA2を通してデータ入力 |
ADC Input3 | ACB02 | PGA3を通してデータ入力 |
ClockPhase1 | Norm | これは普通で良いはず。。 |
ClockPhase2 | Norm | 同上 |
ClockPhase3 | Norm | 同上 |
Clock | VC2 | 少し遅くしてみる |
DataFormat | Unsigned | 0〜255出力とする |
- 特に問題なさそう。っていうか、設定することあまりないよなぁ。
User Module Parameters | Value | 説明 |
Gain | 1.000 | 単なる入力バッファなので増幅しない |
Input | AnalogColumn_InputMUX_0 | これは各ポートにうまく接続するだけ |
Reference | AGND | これはVdd/2を基準にすれば良いので |
AnalogBus | Disable | 外部にアナログ出力しないので |
- で、再度挑戦したがダメでした。サンプリング周波数を色々変えてみるが全然変化なし。
- Gセンサの出力電圧を確認する
- 入力ポートを全部、VDDに繋いで見る。
- えっ?全然、影響ないや。。やっぱりA/D動いてないのか。。。
- なんだかんだで、1日悩む。どうして、A/D変換動かないのかなぁ。
- あれ、そういえば、TRIADC8ってスタートしてたっけ
- 。。ちゃんと、スタートしてるよなぁ。
- 。。。。。
- PGA1〜3をスタートさせれば、OKでした。
- うーん、これ前にもやっちゃったことあるよなぁ。モジュール設定で、AutoStartとか設定出来れば良いのに。。
- あ〜ぁ、グローバル割込み許可の抜けとPGAのスタート忘れで、随分と無駄に悩んじゃったよ。。
- 出力表示はこんな感じで、数値は常に2〜3ぐらい変動しているが、思ったより安定している。
>gsensor 134,131,189
- 地上にいる場合9は、常に重力加速度1G(9.8m/s2)が掛かっている。
- で、センサを逆さまにしてやれば、Z軸に-1G掛かることになるから、
- おぉ!ちゃんと、Z軸方向の数値が変ってる!
>gsensor 134,137,90
- 今度は、ちゃんとY軸が検出されてるな。。
>gsensor 135,187,140
- それじゃ、方向を変えて立ててみる。
- X軸も問題ないね〜。
>gsensor 81,134,138
- 秋月の3軸Gセンサ、なかなか使いやすいGセンサみたいだ。
- 今回、PSoCのA/Dモジュールを、初めて使ったけど扱いやすい感じだなー。
- ブレッドボードも配線を短くしようとすると、パズルみたいで結構面白かった。
- 配線のチェックも記録も残しやすいし。
- 今度から、このやり方で行こう!
- まぁ、適当なプログラムですが、一応は参考になるかもしれないので。
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include <stdlib.h>
// ---- Main program
void main()
{
char *cmd,*para; // Parameter pointer
char line[10];
char gx,gy,gz; // G sensor result
char mode=0;
reset: // reset command
// ---- UART setup
UART_1_CmdReset(); // Initialize receiver/cmd buf.
UART_1_IntCntl(UART_1_ENABLE_RX_INT); // Enable RX interrupts
UART_1_Start(UART_1_PARITY_NONE); // Enable UART
UART_1_CPutString("\r\nWelcome to PSoC Gsensor program by K.I\r\n");
M8C_EnableGInt ; // Turn on interrupts!
// ---- TRIACD8 setup
TRIADC8_1_Start(TRIADC8_1_HIGHPOWER); // Turn on Analog section
TRIADC8_1_GetSamples(); // Start ADC to read continuously
// ---- PGA setup
PGA_1_Start(PGA_1_HIGHPOWER);
PGA_2_Start(PGA_2_HIGHPOWER);
PGA_3_Start(PGA_3_HIGHPOWER);
// ---- LED setup
LED_1_Start(); // maybe GPIO setup
// ---- UART loop
while(1) {
if (UART_1_bCmdCheck()) { // Wait for command
if (cmd = UART_1_szGetParam()) { // get command
switch (*cmd) {
case 'R': // Reset
case 'r': // Reset
UART_1_CPutString(">Reset \r\n");
goto reset;
case 'O': // LED Output
case 'o': // LED Output
if (para = UART_1_szGetParam()) {
UART_1_CPutString(">Output ");
UART_1_PutString(para);
UART_1_PutCRLF();
LED_1_Switch(atoi(para));
}
break;
case 'I': // LED Input
case 'i': // LED Input
UART_1_CPutString(">input ");
UART_1_PutChar('0'+LED_1_GetState());
UART_1_PutCRLF();
break;
case 'X': // LED Invert
case 'x': // LED Invert
UART_1_CPutString(">invert ");
LED_1_Invert();
UART_1_PutChar('0'+LED_1_GetState());
UART_1_PutCRLF();
break;
case 'G': //Gsensor mode
case 'g': //Gsensor mode
mode ^= 1;
UART_1_PutCRLF();
break;
}
}
UART_1_CmdReset(); // Reset command buffer
}
if (mode) {
UART_1_CPutString(">gsensor ");
while(TRIADC8_1_fIsDataAvailable() == 0); // Wait for ready
gz = TRIADC8_1_cGetData1(); // ADC Input1
gx = TRIADC8_1_cGetData2(); // ADC Input2
gy = TRIADC8_1_cGetData3ClearFlag(); // ADC Input3 & clear flag
UART_1_PutString(itoa(line,gx,10));
UART_1_PutChar(',');
UART_1_PutString(itoa(line,gy,10));
UART_1_PutChar(',');
UART_1_PutString(itoa(line,gz,10));
UART_1_CPutString(" \r");
}
}
}
- 小さなブレッドボードだと、28PINのCY8C27443では無理かなと思ったけど、何とか配線出来そうな感じ。
→秋月の配線材を切ったり曲げたりしないで配線するように配置を工夫した
- 難しいかと思ったが、やってみると何とかなるもんだなぁ。
- CY8C27143で作ったプロジェクトから、CloneでBasePartをCY8C27443に設定する。
- 8PINと全く同じにしたかったが、ちょっと難しかったのでDeviceEditorでLEDを P0_5→P1_3に変更。
- でも、LEDがモジュール化されているので、プログラムは変更なしで動作しました!
- LEDをモジュール化する利点は、こういうところにも有るんだなー。
7回路図間違ってたので直しました(090123)。
8モジュールを良く知らなくても取りあえず探せるのがPSoCの良いところ。
9多くの人は、そうだと思いますが。。。
10自分は設定ミスで約3日掛かりました。まぁ、普通はこんなに失敗しないよな。。
[top]
- っていっても、こればっかりは8PINのPSoCじゃ無理っぽい。
- それに秋月のLCDって、2列になってるのでブレッドボードで扱いにくいんだよね。
- それでも、試しにLCDを繋いでみたいってことは、多いよね。
- PSoCEval1キットに含まれるLCD(SO1602)は、シングルインラインになっている。
- ピン配置の資料がリンク切れで見つからなかったので、テスターでちょっと調べてみる。
→Cypressのキットに付属するLCD、この配置って海外ではポピュラーなのかなぁ
LCD | ← | PSoC | ← |
1 | Gnd | 14 | Vss |
2 | Vdd | 28 | Vdd |
3 | VO | | |
4 | RS | 6 | P2_5 |
5 | R/W | 23 | P2_6 |
6 | E | 22 | P2_4 |
7 | ? | | |
8 | ? | | |
9 | ? | | |
10 | ? | | |
11 | D4 | 20 | P2_0 |
12 | D5 | 8 | P2_1 |
13 | ? | | |
14 | ? | | |
15 | D6 | 21 | P2_2 |
16 | D7 | 7 | P2_3 |
- これだと、ブレッドボードでも使える。まぁ、これをピン数の多いブレッドボードで使うのが正統かな。
- 但し、ちょっと無駄にピン数が多いので、このピン配置を標準とするのはちょっと抵抗あるかなぁ。
- でも、とりあえず小さなブレッドボードで実験したい。
- 秋月の16文字×2のLCDを、PSoCに接続するためのアダプタを作ってみよう11。
- フラットケーブルに圧着する端子を使って、以下のように接続しているだけ12。
LCD | ← | PSoC | ← |
1 | Vdd | 28 | Vdd |
2 | Vss | 14 | Vss |
3 | VO | | Vss |
4 | RS | 6 | P2_5 |
5 | R/W | 23 | P2_6 |
6 | E | 22 | P2_4 |
7 | D0 | | |
8 | D1 | | |
9 | D2 | | |
10 | D3 | | |
11 | D4 | 20 | P2_0 |
12 | D5 | 8 | P2_1 |
13 | D6 | 21 | P2_2 |
14 | D7 | 7 | P2_3 |
- とりあえず、無難に13Port2に繋ぐことにする。
- コントラスト調整のVo端子は、今回は面倒なのでVssに直結したが、10KΩ程度の抵抗を通してVssに接続した方が良い。
- CypressのLCDのピン配置と比較して、VddとVssが逆なので注意!
- 他にも20文字のLCD等では、Vdd,Vssが逆配列のものがある14ので、最初に良く確認する必要がある。
11ただ単に、小さいブレッドボードでLCDを使いたい!というだけの理由で作ったようなもんだけど。。
12でも、あまりスマートじゃないよな〜。もっといい方法ないかしらん?
13Port0はアナログ関係で使うし、Port1はPSoCの書込みに使うので。
14何で電源が逆配列のものがあるんだろう。他の端子は全て共通の配置なのに電源だけ逆にするのは理解出来ないな〜。
[top]
- 8PINじゃLCDは無理なので、28PINのCY8C27443を使う。
- 8PINのCY8C27143で作ったGセンサ用プロジェクトから、 CloneでBasePartをCY8C27443に設定する。
- DeviceEditorでLEDを P0_5→ P1_3に変更。
- LCDモジュールを追加、Port2に設定・BarGraphをEnableにしておく
- LCDモジュールは、ソフトモジュールなのでDeviceEditorによる配線は不要で、ハードウェアのブロックは消費しない。
- UARTは今回使わないけど、そのままでOK!
- モジュールをプログラムでスタートしなければ、使われることは無い。
- もちろん、UARTをスタートすれば、そのまま使えます。
- こういう時の事を考えると、モジュールが自動的にスタートしないっていう仕様は、良いのかもしれないなぁ。
- LCDモジュールをスタートして、LCD表示ルーチンを呼び出すだけ。
- 折角なので、バーグラフを使ってみました。
- 80〜180の変動を20レベル程度でということで、とりあえず x/5-16 というイイカゲンな変換式で表示してます。
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include <stdlib.h>
void main()
{
char line[10];
char gx,gy,gz; // G sensor result
M8C_EnableGInt ; // Turn on interrupts!
// ---- TRIACD8 setup
TRIADC8_1_Start(TRIADC8_1_HIGHPOWER); // Turn on Analog section
TRIADC8_1_GetSamples(); // Start ADC to read continuously
// ---- PGA setup
PGA_1_Start(PGA_1_HIGHPOWER);
PGA_2_Start(PGA_2_HIGHPOWER);
PGA_3_Start(PGA_3_HIGHPOWER);
// ---- LED setup
LED_1_Start(); // GPIO setup
// ---- LCD setup
LCD_1_Start(); // Initialize LCD
// LCD_1_Init();
LCD_1_InitBG(LCD_1_SOLID_BG);
while(1) {
while(TRIADC8_1_fIsDataAvailable() == 0); // Wait for ready
gx = TRIADC8_1_cGetData1(); // ADC Input1
gz = TRIADC8_1_cGetData2(); // ADC Input2
gy = TRIADC8_1_cGetData3ClearFlag(); // ADC Input3 & clear flag
LCD_1_Position(0,1);
LCD_1_PrHexByte(gx);
LCD_1_DrawBG(1,1,4,gx>=80?gx/5-16:0);
LCD_1_Position(0,6);
LCD_1_PrHexByte(gy);
LCD_1_DrawBG(1,6,4,gy>=80?gy/5-16:0);
LCD_1_Position(0,11);
LCD_1_PrHexByte(gz);
LCD_1_DrawBG(1,11,4,gz>=80?gz/5-16:0);
LED_1_Invert();
}
}
- 今回は、結構すんなり動いた。
- 写真では、傾けられるように、板にテープで貼り付けてあります。
→傾きに合わせてバーグラフが動くのが面白い
- Gセンサって、思ったより面白いセンサーだな〜。いろいろ応用が出来そうだ。
- TRIADC8のクロックは、デジタルモジュールと、アナログモジュールにそれぞれ与える必要があるが、まぁ、あまり考えずに同じクロックを入れてる。
Global Resource | Value |
VC1=SysClk/N | 12 |
VC2=VC1/N | 16 |
- クロック設定は、上記のようになっており、デジタル・アナログ共にVC2を設定している。
- ユーザモジュール設定で、デジタルClock=VC1にしておいて、アナログブロックにマルチプレクサで設定するClock=VC2にしてみる。
- やはり値は小さめになってしまうし、ちょっと変動が大きくて、LCDだと下位桁が読みにくい状態。
7* 6* 9*
- 逆に、デジタルClock=VC2にしておいて、アナログClock=VC1にしてみる。
- さらに変動が大きい感じで、LCDだと下位桁が読み取れない状態。
8* 7* B*
- 試しに、デジタルClock=VC1,アナログClock=VC1
- あれ?ちょっとかなり小さめの値だなぁ。
6E 69 9B
- 念のためデジタルClock=VC2,アナログClock=VC2に戻してみる
- ふーむ。やはりクロックに影響されるみたいだ。
81 7C B9
- VC2のクロック分周をVC1/1にしてやっても同じはずだよね。
- 良かった!まぁ、これで違っちゃ困るけどね。
6E 69 9B
- じゃ、クロックをもっと遅くすると、どうなるんだ?
- とりあえず簡単に試せるところで、VC1=SysClk/16にしてみる
82 7C B9
- これは変化なし。まぁ、これ以上遅くても、大きな違いは無さそうだ。
- でもなんでだろう?TRIADCのDataClockは8MHzまでの筈なので、余裕があるはずだしなぁ。
- LCD表示があるから、サンプリングの間隔は結構あるし。。ありすぎるのかな?
- ループの最後で、フラグをクリアしてみる。
TRIADC8_1_ClearFlag();
。。。変らないね。そゆことじゃないのか。。
- まぁ、デジタルクロックとアナログクロックは同じ方が良さそう。
- クロックが違っても動かない訳じゃないが不安定にみえる。
- それにクロックはあまり速く無い方が良さそうだ15。
15ちゃんとした結論出せなかったなぁ。。
[top]
[電子工作関連に戻る]