PSoCを使ってみよう

by K.I
2004/06/01 〜

Index


概要

CypressのPSoCを使ってみる。気の向いた時だけやるから、なかなか進まないかも。 これはワンチップマイコンだが、アナログのモジュールがいろいろ載っていて組み合わせて使えるらしい。良く分かんないが、面白そうだと思っていたけど、なかなか手が出なかった。
[top]

Invention Board

PastelMagicの桑野さんが、おまけで基板を送ってくれていた。これはファームが違うみたいでInvention_Boardとしては使えない。差替えすれば動くようだが、パッケージもピン配置も全然違うし、ちょっと難しそうだ。とりあえず、これはとっておいて別に基板を作成することにする。

互換基板の作成

開発用キットのファームが焼いてある64013は、SOICとPDIPで全然ピン配置が違っている。それに配線が結構省略されていてなんか分かり難いので、PDIP用に書き直してみた。 改めて見てみると必要な配線は結構少ない。これならブレッドボードでも十分組めそうだ。

PSoCをデザインする

部品を集めて配線も終わったので、 PastelMagicの解説を見ながら、その通りにやってみた。

プログラムする

とりあえずの感想

ファームの換装


1欲しくて探してみたけど売ってるところは少ない。Digi-Keyだと買えそうだけど手数料とか送料が高い。
2新しいことをやると大概はうまく行かないので、簡単に諦めてしまうことが多い。うまく行くと調子にのって失敗することもあるけど。。。

[top]

いろいろやってみよう

Compiler keyを入れて、Cも使えることを確認した。 とりあえずPICでやってることと同じことをやってみようかな3

LCDモジュールを使ってみる

で、あっさり表示出来た。まぁ、PICで使い慣れてるということもあるけど。

温度センサモジュール

FlashTempモジュールを使ってみる。でも、ちょっといまいち。
#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules

void main()
{
        char    i;
        char    t;
        
        M8C_EnableGInt;                 //これは必要なのか?
        LCD_1_Start();
        LCD_1_Position(0,4);
        LCD_1_PrCString("PSoC test");
        LCD_1_Position(1,2);
        LCD_1_PrCString("FlashTemp");

        FlashTemp_1_Start();            //スタートさせる
        while (TRUE) {
          if (FlashTemp_1_fIsData()) {  //flsDataが1になるまで待つ
            t = FlashTemp_1_cGetData(); //データ取り込み
            if (!i++) {                 //表示が速過ぎるので
              LCD_1_Position(1,12);
              LCD_1_PrHexInt(t);        //256回に1回だけ表示
            }
            FlashTemp_1_Start();        //またスタートする
          }
        }
}
Parameter Value Min Max
Column Clock 24M/16/2=750k 125k 960k
(VC2) 24M/16/4=375k
24M/16/8=187.5k
Sample Rate 375k/255/4=368 900sps
Global Resource
CPU clock 24MHz(SysClk/1)
32K_Select Internal
PLL_Mode Diable
Sleep_Timer 512_Hz
VC1=SysClk/N 16
VC2=VC1/N 8
VC3 Source SysClk/1
VC3 Divider 1
SysClk Source Internal 24_MHz
SysClk*2 Disable No
Analog Power SC On/Ref Low
Ref MUX (Vdd/2) ± BandGap
(2 BandGap) ± BandGap
AGndBypass Disable
Op-Amp Bias Low
A_Buff_Power Low
SwitchModePump OFF
Trip Voltage(LVD(SMP)) 4.64V(5.00V)
LVD Throttle Back Disable
Supply Voltage 5.0V
Watchdog Enable Disable

シリアル通信

と思っていましたが、良くデータシートを見ると、Resolutionは3.3℃になってる。。。 つまり、これで良いんですねー。 ということで、貰い物ですが、とりあえずはシリアル通信も確認出来ました。

FlashTempで零下はどうなるの?

離散的な数値を返すことから、摂氏のデータを返すと一応納得したものの、零下になるとどうなるか追試してみました。

I2Cに挑戦中

#include <m8c.h>        // part specific constants and macros  
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules  

BYTE rxBuf[8];  
const BYTE txCBuf[] = { 0x0D,    // Register-address 0x0D  
                        0x83 };  // CLKOUT frequency 1Hz

void main()  
{  
        BYTE status;                 // I2C communication status  

        I2Cm_1_Start();              // Initialize I2C Master interface  

        // Set CLKOUT frequency 1Hz (Slave-address 0x51)
        status = I2Cm_1_bWriteCBytes(0x51,txCBuf,2,I2Cm_1_CompleteXfer);  

        I2Cm_1_SendStop();  
}

SMPを使ってみたい

PSoCならPWMモジュールとTr1個でも出来そうだけど、やっぱり専用の端子があって簡単に出来るのは良いなぁ。 これは、何か根本的に足りないものがありそうだ。スイッチングを確認してみよう。

クロックを遅くしてみる

クロックによる電流消費か。。。そうかもしれないなぁ。

SMPのインダクタ

SMPのインダクタは、どれぐらいが良いのかな? PSoCの仕様では、2.2uH,1uFでの規定があるからそれぐらいか。
インダクタ test1 test2 test3
1uH 4.37V 4.87V 4.97V
2.2uH 4.61V 4.97V 4.97V
10uH 4.84V 4.93V 4.97V
100uH 4.03V 4.03V 4.04V
SMPの配線長がこんなに効くとは思わなかった。スイッチングの線は短い方が良いとは思うけど。。。ブレッドボードでは要注意だなぁ。
インダクタ 電流値
1uH 3.57mA
2.2uH 9.26mA
10uH --
100uH --
完全に壊れた訳じゃなさそうだけど、SMP端子はちょっとダメかも。。。

割込みしたい

とりあえず入力装置として、I/Oポートにタクトスイッチを配線する。

割込み許可

マニュアルを見ると、GPIOの割り込みは以下のようなステップでやれと書いてあるが、、 割込みの手順は、間違ってないんじゃないかな? やろうとしていることは、

Pull-Upはやめた

割込み設定自体は、そんなに間違ってなかったみたいだ。

Pull-Upのやり方

クリアする必要あるの?

割り込みが掛かるようになったのは良いんだけど、どうやってクリアするのか。

アセンブラで書いてみる

手詰りだ。。。仕方ない、割り込みをアセンブラで書いてみよう。

ljmpするだけでした

スリープしよう

電池駆動ならスリープは必須なので、これは試しておかないと。 なんか眠くなってきたので、今日はここまでにしておこう。

まるで暗号

SLEEPは良くわからないので、英文の説明を読むが余計分からなくなる。 とりあえず、関係ありそうな部分を適当にざっと意訳5したのをメモしておこう。頭の中で考えるよりはマシかも。。。(しかし、この英文はネイティブの人でもきっと分かり難いと思うなぁ。。。) SLEEPに関する記述が、また悩ましい。 RES_WDTへの書き込みは効果が無かった。しかし、この訳がある程度合ってるとすると、ちょっと変な仕様ではあるなぁ。Wake-Up後にSLEEP直後の命令が実行されるっていう処は関係あるかな?。。。。。うーん、わからん。でも眠いので寝る。

WDTでした

落ち着いて良く考えてみる。

EEPROMモジュール

データを記録するのに、PICではEEPROMを使うことが多いが、PSoCではEEPROMを持っていない。代わりに、プログラムメモリ上にデータを保存するソフトモジュールがあるので、それを使ってみよう。

テストプログラム

現状のテストプログラム。簡単だけど7、とりあえずGPIO割り込みとEEPROMモジュール、それにスリープも使ってるので、少しは何かの参考になるかもしれない。
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules
#include "psocgpioint.h"

#pragma interrupt_handler gpio_handler          //割り込みハンドラの指定

char line[21];                                  //20文字分のバッファ

unsigned char x=0;                              //X方向カーソル位置
unsigned char key;

void gpio_handler()     //GPIO割り込みハンドラ(スリープよりwake-up)
{
        PRT0DR ^= 0x03;                         //LED2個を単に反転させる
        key = ~PRT2DR;                          //キー入力
        if (key & Right_MASK) x = (x+1)%20;             //右カーソル移動
        if (key & Left_MASK)  x = (20+x-1)%20;          //左カーソル移動
        if (key & Up_MASK)   line[x] = (line[x]-'0'+1)%10+'0';    //データUp
        if (key & Down_MASK) line[x] = (10+line[x]-'0'-1)%10+'0'; //データdown
        if (key & OK_MASK)  E2PROM_1_bE2Write(0,line, 20, 25);  //Flash書き込み
        if (key & Cancel_MASK) E2PROM_1_E2Read( 0, line, 20 );  //Flash読み込み
}

void main()
{
        LCD_1_Start();                          //LCD設定
        LCD_1_Position(0,1);
        LCD_1_PrCString("PSoC EEPROM Module");  //1行目に表題表示

        PRT0DR  &= ~0x02;                       //LED1消灯
        PRT0DR  |=  0x01;                       //LED0点灯させる
        PRT2DR  |=  0xfc;                       //タクトスイッチ6個分プルアップ

        E2PROM_1_E2Read( 0, line, 20 );         //起動時にFlashを読んで表示
        INT_MSK0 = INT_MSK0_GPIO;               //GPIO割り込みを許可
        M8C_EnableGInt;                         //グローバル割り込み許可
                
        while(1) {
                LCD_1_Position(1,0);            //2行目に
                LCD_1_PrString(line);           //20文字分データ表示
                LCD_1_Position(1,x);                    //カーソル位置に移動
                CPU_SCR0 |= CPU_SCR0_SLEEP_MASK;        //スリープする
        }
}

LCDのカーソル表示

LCDモジュールでは、カーソルは表示されないように設定されてるみたいだ。
3というか、アナログは良く分かんないので。。。
4途中で配線短くしたからなぁ。ショットキの足でそのままInventionBoardを跨いで繋いでたのが失敗かな。。。
5あくまで、いい加減な意訳です。くれぐれも信用しないように。。。
6PICだったら0x2100に書き込んどけば良いよね。そんな感じでやりたいんだけど。。。
7分かってしまえば簡単なんだけど、ここまで分かるのに結構掛かったなぁ。。。

[top]

落書き


[top]

リンク

PSoC関連のリンクです。PastelMagicのBBSに出入りされている方が多いです。
comments powered by Disqus