2013年9月1日日曜日

MCU Gear のプログラム:その2 LPC1114FN28 編


MCUGear® のサンプルプログラムを参考に簡単な動作説明をします。

多少説明が間違っているかもしれません、その場合予告なく修正する可能性がありますのでご容赦ください。
かなり詳しく説明したつもりです。パッと見、分量が多い様ですが当たり前のことも多く書いています。気長に読んでみてください。

まずはスイッチを読んでLEDを光らせるというところをやりたいと思います。

目標は動画のような雰囲気です。
LPC1114FN28はベースボードの下のマイコンボードに入っています。



回路のイメージは以下のような雰囲気です。(青い小さな四角は抵抗です。LEDに+3.3Vをかけて抵抗は220Ω、スイッチに1KΩ使っています。LEDの種類によっては変化しますので適宜計算してみてください。)この回路を実現するための再配線をしてみましょう。



LPC1114FN28のサンプルコードのmain.cについて見ていきましょう。(※mbed、K25Z版の方がより見やすいと思いますので、プログラムが理解しにくいの方は、そちらを参考にしてください)


最初に#define部分に、どのサンプルを使うかが書いてあります。

最も基本的なユニバーサルモジュール2だけを使ってみましょう。


//define your module and function

//1=ON, 0=OFF
#define SimpleUART 0
#define AD12bit2 0
#define AD12bit8 0
#define DA12bit 0
#define LCDM 0
#define SigHold 0
#define Universal2 1

#define MultiFunctionModule  0

#define PWM_MODE 0
#define AD_MODE 0
#define I2C_MODE 0

上記のように設定するとユニバーサルモジュール部分だけが有効になります。(ただし、SPIの情報はそのまま残りますが今回は使わないので無視してください)


早速main()関数内を見てみましょう。

SystemCoreClockUpdate(); 
PLL0CFG/CCLKCFGレジスタを読み出し、CPUクロック値をSystemCoreClock変数に設定します。単純に「このマイコンのクロック周波数はいくつですよ」って言うのを全体に知らせていると考えておいてください。

SysTick_Config(SystemCoreClock/10000); //Timer (1/10000) Sec = 0.1 msec
は0.1msecタイマーを作り出しています。これはmwait01(~);と呼び出すと、~に10と入れると1msec動作を待つことができる関数を使えるようにしています。お好みで使ってみてください。mwait01(~); はcommon.cで定義されています。


init_I2C();
I2Cの初期化をします。MCUGearでは位置把握や再配線の命令を送る際にI2Cを利用しています。I2Cで配線し終わると普通のデジタル回路として利用できる仕組みです。I2Cは1MHzで動かせますが、実際には1.3MHzくらいでも動かせました。サンプルではおよそ1MHz程度で動作しています。
I2C.hの


#define I2SCLH_HS_SCLH 0x0000000F  // Fast Plus I2C SCL Duty Cycle High Reg 
#define I2SCLL_HS_SCLL 0x0000000F  // Fast Plus I2C SCL Duty Cycle Low Reg 

の定数を小さくすると周波数が速くなります。

ModuleIOConfig();
これはモジュールに割り振るためのマイコンのIOを設定しています。main.c の下に関数があります。サンプルプログラムが動くように設定されていますが、自分のシステムに合わせて改造してください。関数内を少しのぞいてみましょう。

LPC_IOCON->PIO0_3 = 0xd0; でPIO0_3を通常のIOとして設定し、
LPC_GPIO0->DIR  |= (1<<3);で出力ピンに設定しています。

LPC_GPIO0->DIR  &= ~ (1<<3);で入力ピンにも設定しています。


注意したいのは
LPC_IOCON->R_PIO1_0 = 0xd1;
このようにR_がついたピンは入れる値が違うので注意してください。



//SPI setting
SSP_IOConfig(0);//port 0 PIO0_8 _9 _6 _2
SSP_Init(0);
ここはSPI通信の設定で今回は使わないので無視してください。



//Baseboard setting
init_BASEboard();
これはベースボードの初期化をするところです。興味のある方は中身をのぞいてみてください。とりあえずおまじないだと思って通り過ぎてください。


//2 connector Universal module setting
MCUGear Uni2M;
IOUni2M(&Uni2M, N_VDD_VDD_VDD);
ここでは、MCUGear上でUni2Mという名前をユニバーサルモジュール2だと紐づけするところです。
N_VDD_VDD_VDD はユニバーサルモジュール2の裏面に設定したアドレスが入ります。ここではVDD = +3V3、 VSS = GND と定義されているので覚えておいてください。
また「N_」は コントロール用のI2CデバイスPCA9674、「A_」は  コントロール用のI2CデバイスPCA9674Aを表しています。
※A_VDD_VSS_VSSはベースボードのアドレスとかぶってしまうので設定できません。



では、IOUni2M 関数内部を見てみましょう。

void IOUni2M(MCUGear *mcugear, char address){
mcugear->address = address;
mcugear->PinNum = 8;
//detect module
detectModule(mcugear);
    savePinSetting(mcugear, 0, IO_LPC1114FN_17, IO_REG_IN_DIR); //PIO1_8 input
    savePinSetting(mcugear, 1, IO_LPC1114FN_18, IO_REG_IN_DIR); //PIO1_9 input
    savePinSetting(mcugear, 2, IO_LPC1114FN_4, IO_REG_OUT_DIR); //R_PIO0_11 output
    savePinSetting(mcugear, 3, IO_LPC1114FN_9, IO_REG_OUT_DIR); //R_PIO1_0 output
    savePinSetting(mcugear, 4, IO_LPC1114FN_10, IO_REG_OUT_DIR); //R_PIO1_1 output
    savePinSetting(mcugear, 5, IO_LPC1114FN_11, IO_REG_OUT_DIR); //R_PIO1_2 output
    savePinSetting(mcugear, 6, IO_LPC1114FN_13, IO_REG_OUT_DIR); //R_PIO1_4 output
    savePinSetting(mcugear, 7, IO_LPC1114FN_14, IO_REG_OUT_DIR); //R_PIO1_5 output

    mcugear->Bank = 0;


}


オリジナルの設定を作るときは、以下の手順を順番に行ってください。

1、引数で渡されたアドレスの設定をして、mcugear->address = address;

2、mcugear->PinNum = 8; これはユニバーサルモジュール2にマイコンのピンをいくつ割り当てるのかを入れます。ここでは8個のマイコンのピンを割り振ってみようと思います。

3、detectModule(mcugear); は先ほど設定したアドレスのモジュールがどこにあるのかを探して、MCUGear構造体に位置を登録してくれる関数です。

4、savePinSetting(mcugear, 0, IO_LPC1114FN_17, IO_REG_IN_DIR);
   ・・・
     savePinSetting(mcugear, 2, IO_LPC1114FN_4, IO_REG_OUT_DIR);
   ・・・
 は指定したモジュールの0番ピンにLPC1114FNのどの端子番号を割り振ったかを入れます。最後の IO_REG_OUT_DIR はどの出力ピンを割り振りますという意味です。これが入力ピンであれば IO_REG_IN_DIR と記載してください。
ここでは0と1番にinput 残りはoutputに設定しています。

5、 mcugear->Bank = 0; は、MCUGearにはバンクというレイヤーのようなものが存在しています。これは再配線する祭に、あらかじめ決まった配線をベースボードに登録しておき、レイヤーの切り替え命令だけで高速に配線を切り替えるためのものです。Bankは0~7まで設定でいますが、LPC1114FN28のサンプルプログラムでは他のバンク切り替えの動きはできません。また、非常に複雑な動きをするので上級者向けです。(「マイコン端子の分岐は出来ない」ということを考えながら使ってください。)
mbedやK25Zなどで自動的に動作させるかを選択できるようにしていますので、そちらでお試しください。



while(1){
次にmain関数のループ部分に入ります。
まずモジュールに接続前にIOの状態をどうしたいのかを常に考えましょう。
そのまま接続すると、仮に別のモジュールで使っていた状態をそのままデバイスに伝えてしまうことになります。事前にIOの状態はHighにしたいので以下のように記述しておきます。

LPC_GPIO0->DATA |= (1<<11);

LPC_GPIO1->DATA |= (1<<0);
LPC_GPIO1->DATA |= (1<<1);
LPC_GPIO1->DATA |= (1<<2);
LPC_GPIO1->DATA |= (1<<4);
LPC_GPIO1->DATA |= (1<<5);

次にモジュールと接続してみましょう。


//Universal module ------------------------------
connectModule(&Uni2M);
モジュールとマイコンを配線する関数です。先ほどのUni2Mと定義したものを入れています。
この処理が終わるとすでにマイコンとユニバーサルモジュールの接続が確立されています。
通常のデジタル回路だと考えてください。

//check switch0 PIO1_8

switch0 = LPC_GPIO1->MASKED_ACCESS [1<<8]>>8;
//check switch0 PIO1_9

switch1 = LPC_GPIO1->MASKED_ACCESS [1<<9]>>9;

まずは0番、1番ピンにスイッチを押すとグランドに落ちるような回路ををブレッドボードにつないでください。GNDで落とすときは適当な抵抗を挟みましょう。

ここでは、0番にPIO1_8 と 1番にPIO1_9がつながっていて、結果をwhile(1)の前で定義したswitch0 とswitch1に保存しています。

出力確認のLEDは+3.3Vから抵抗とLEDを取り付け、最後にIOにつなげます。IOがLowになると光る仕組みです。





スイッチ0がGNDに落ちるとLEDが光ります。


if(switch0){

LPC_GPIO0->DATA |= (1<<11); //High
}else{
LPC_GPIO0->DATA &= ~(1<<11); //Low
}

if(switch1){

LPC_GPIO1->DATA |= (1<<0); //High
}else{
LPC_GPIO1->DATA &= ~(1<<0); //Low

}

例えばLPC1114 の4番ピンR/PIO0_11を動かしてみましょう。先ほどのvoid IOUni2M(MCUGear *mcugear, char address)を参考にしてください。

LPC_GPIO0->DATA |= (1<<11); //High
とやれはユニバーサルモジュール2の0番ピンがHighになります。

LPC_GPIO0->DATA &= ~(1<<11); //Low
とやるとユニバーサルモジュール2の0番ピンがLowになります。

他にも色々な処理をさせて動かしてみてください。サンプルでは残り7ビットが2進数でカウントアップされるようなプログラムを入れてあります。
表示が見えに居場合は
タイマーを使った、mwait01(1000); などを入れてゆっくり動作を見てださい。 


disconnectModule(&Uni2M);
最後にモジュールのゲートを閉じる処理をします。


後は同様に
connectModule(&Uni2M);

従来のデジタル回路の処理

disconnectModule(&Uni2M);

という動きを繰り返すだけです。



※おまけです--------------------------------

if(A){
        B;
}else{
        C;
}

(A)? (B) : (C);
とプログラムで書いても同じことを意味しますが、プログラムメモリが稼げるようです。
可能なら
(switch0 == 1)? (LPC_GPIO0->DATA |= (1<<11)) : (LPC_GPIO0->DATA &= ~(1<<11));
(switch1 == 1)? (LPC_GPIO1->DATA |= (1<<0)) : (LPC_GPIO1->DATA &= ~(1<<0));
と書いた方が節約になるかもしれません。
-------------------------------------------------

次回は
「MCU Gear のプログラム:その3 LPC1114FN28 編 UART ( シリアル通信 でPCに文字とdouble型データを送る)」




0 件のコメント:

コメントを投稿