ラベル mbed の投稿を表示しています。 すべての投稿を表示
ラベル mbed の投稿を表示しています。 すべての投稿を表示

2013年12月3日火曜日

MCU Gear を高速化させる(概要)

MCU Gearにはマイコンの配線情報をベースボードに8つ記憶できるBANKというものを持っています。(レイヤーのような物だと考えておいてください)

モジュール複数を同時に接続状態にしておき、配線の切り替え頻度を減らすことで高速化できます。BANKを切り替える命令だけで、あらかじめ作っておいた配線情報が再現できます。





※BANKを使って動かすときの利点・注意点

1、同じBANKのモジュール同士が縦に積まれると、混線する可能性が出てくるため同じモジュール同士を縦に積層しないようにする必要があります。(プログラムのやり方によっては、モジュールの接続位置情報から自動的に危険を回避することも可能)

2、「配線は分岐できない」ので、たとえばSPIを一つのBANKで複数使いたいときは、同じ配線のSPIモジュールを縦に積み上げて、モジュールのゲート信号だけ変更して使います。(Raspberry Piのように、自動で動くチップセレクトピンが少なくても、1つのチップセレクトピンで複数積層できるのが利点です。)

3、パソコンのPCIバスのような物との違いは、基板(BANK)ごとに回路と配線情報が後から自由に入れ替え可能だということです。

EX)
 a、移動時はこの回路構成でマイコンに接続、定点観測時にはモータ部分の回路のみ切り他の回路は流用する等
 b、故障しやすいモジュールを見越してあらかじめ搭載しておき、壊れたら遠隔地から切替
 c、回路のリサイクル性が高いので、別の回路構成に切替可能


現状のサンプルプログラムではユーザーにとって安全のために一つのモジュールごとに配線しなおしていますが改造可能です。

また、mbedでは自動的に高速化するための #define boost というものが用意されています。積層の仕方によって、配線が混戦しないように自動的にBANKを使い分けてくれます。
(上記注意点2、に関しては自動的には行っていません)


2013年9月4日水曜日

MCU Gear のプログラム:その他プログラムで気を付ける点

MCU Gear ® を使ったプログラムの説明などを書いています


MCU Gearでも使っていますが、完全に同じプログラムで同じ動き、とはいかないようです。
MCU Gearで使うときに以下のような注意点があります。


1、クロック周波数
KL25Z はLPC1768の約半分なので、通信バス等のクロックを想定している値の倍にしないといけない。


2、KL25Z は通信バスのフォーマットが8ビットなので、SPIのフォーマットを任意で設定できない。
SPI通信は8ビットを複数回組み合わせて実現します。

ちなみに、LPC1114FN28 をLPCXpreaaso で動かす場合はSPIのフォーマットが変えられるようです。

3、KL25ZのUSBシリアル通信
KL25ZではPTA0、PTA1がPCとのシリアル通信で使われるので、PCのシリアル通信を使いたい場合は、他のデバイスとの接続に使ってはいけない。

mbedで従来のライブラリを使うときの注意点
mbedのLCDモジュールは、インスタンスを生成する時に初期化信号を出しています。
MCU Gearを使うときにはまずLCDに配線をしてからインスタンスを生成して初期化する必要があります。

サンプルプログラムではインスタンスの生成をLCDM.connectModule();の後に行っています。
mbed系は呼び出したときに初期化するものもあるので注意してください。

グローバルで定義するためには初期化関数を用意する必要があります。


Multifunction Module LPC1110FD20 のサンプルコードの説明 (3つのモード)

MCU Gear ® を使ったプログラムの説明などを書いています

Multifunction Module (マルチファンクションモジュール)はLPC1110マイコンを搭載したモジュールです。


PWM 機能も使えるので、動画のようにサーボモーターも動かせます。
動画は12bit 2ch ADモジュールに距離センサー(GP2Y0A21YK)を取り付け、LCDで値を表示しながらサーボを回してみました。もちろんモジュールを重ねても動きます。



サンプルソースではMCUGearを通して、SPI通信 16bitフォーマットでデータのやり取りをし、3つのモード(AD変換、PWM、I2C)のサンプルを用意しました。プログラムの中身を見ながらいろいろ楽しんでみてください。


マイコンとUARTも接続可能ですが、モジュールを切り替えるため単純なSPIを推奨します。SPI使用時は補助としてUARTピンを2つのデジタルIOとしても使えます。簡単な機能を分担させるために使用できますが、サンプルプログラムでは特に言及していません。


サンプルプログラムのI2C.hなどで通信速度設定の変更をしています。このプログラムはあくまでも動作確認用なので、ご自分のシステムで動作させる際はユーザーマニュアルなどを見ながら自作してください。

MCU Gear 側 (ベースボードに接続されている端子)

0pin PIO0_8/MISO/CT16B0_MAT0
1pin PIO0_9/MOSI/CT16B0_MAT1
2pin PIO0_6/SCK0
3pin PIO0_2/SSEL0/CT16B0_CAP0
4pin PIO1_6/RXD/CT32B0_MAT0
5pin PIO1_7/TXD/CT32B0_MAT1

モジュールの外部ピン(実際に出力ピンとして使えるもの)

0pin  R/PIO1_1/AD2/CT32B1_MAT0
1pin  R/PIO1_2/AD3/CT32B1_MAT1
2pin  SWDIO/PIO1_3/AD4/CT32B1_MAT2
3pin  SWCLK/PIO0_10/SCK0/CT16B0_MAT2
4pin  PIO0_5/SDA
5pin  PIO0_4/SCL

ピンの種類を見るとわかりますが、以下のような機能が使用可能である。

5つのデジタル入出力(内二つはオープンドレイン)
3つのAD変換
3つの32bitマッチタイマー出力
1つの16bitマッチタイマー出力
I2Cバス(MCUGearと別系統で使用可能、プルアップ抵抗が必要です)
デバッガ(SWDクロックポート、SWD入出力ポートが取り出せますが、この機能はテストしていません、興味のある方は試してみてください。)

以下にサンプルプログラムの使い方を説明します



・3ch 10bit ADC

main.c で

#define AD_MODE 1

#define PWM_MODE 0
#define I2C_MODE 0

とAD_MODEを選択してください。

3チャンネルの10bit AD変換モジュールとして動作します。


マイコン側では

mbed、KL25Z はMCUGear ライブラリのcommon.hを

//For Sample Mltifunction Mofdule-----------------------------

#define AD_MODE
//#define PWM_MODE
//#define I2C_MODE
//--------------------------------------------------------
としてください。
LPC1114FN28 のLPCXpressoの場合は main.c 内で

#define MultiFunctionModule 1

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

と定義してください。



SPIの操作方法


1、まず、どのAD変換データが欲しいかを指定します。

16bit 1MHzで動作します。16bit なので cs を Low にしたまま 8bit を二回送っても良いです。

チャンネル指定データを送ります。順不同なので注意してください。

0x0001:AD4
0x0002:AD2
0x0003:AD3

2、次に16bitデータの受信を行います。

16bit 0x000を送ってください。ADCが 10bit なので、実際に使えるのは 10bit 分のみです。

KL25Zは16bit Format に対応していないので8bitで操作します。


FRDM-KL25Zの例

    getData = spi.write(0);
    getData = (getData<<8)+spi.write(0);



・3ch PWM 出力

Multifunction Module 側のmain.c で

#define AD_MODE  0

#define PWM_MODE  1
#define I2C_MODE  0

PWM_MODE  を選択してください。

3チャンネルのPWMモジュールとして動作します。


マイコン側では

mbed、KL25ZはMCUGear ライブラリのcommon.hを

//For Sample Mltifunction Mofdule-----------------------------

//#define AD_MODE
#define PWM_MODE
//#define I2C_MODE
//--------------------------------------------------------
としてください。
LPC1114FN28 のLPCXpressoの場合は main.c 内で

#define MultiFunctionModule 1

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

と定義してください。



PWMは32bitタイマーマッチアウト(CT32B1_MAT0~2)を使用しています。


前方4bitがコマンド、後方12bitがデータという 16bit SPI フォーマットで動作します。




1、まず初期化します。

以下の順番にデータを送信してください。
Divider
Frequency
Duty0
Duty1
Duty2


これらのデータはモジュールのLPC1110内では以下のように扱われます。


LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10);

LPC_IOCON->R_PIO1_1 |= 3;
LPC_IOCON->R_PIO1_2 |= 3;
LPC_IOCON->SWDIO_PIO1_3 |= 3;
LPC_TMR32B1->PR = Divider - 1; //プリスケールレジスタ
LPC_TMR32B1->PWMC |= (1<<0);
LPC_TMR32B1->PWMC |= (1<<1);
LPC_TMR32B1->PWMC |= (1<<2);
LPC_TMR32B1->MCR |= (1<<10);
LPC_TMR32B1->MR3 = Frequency-1;
LPC_TMR32B1->MR0 = Frequency*Duty0/100;
LPC_TMR32B1->MR1 = Frequency*Duty1/100;
LPC_TMR32B1->MR2 = Frequency*Duty2/100;
LPC_TMR32B1->TCR = 1;

簡単に説明しますと、タイマーの中にはプリスケールカウンター(PC)というカウンターが動いています。このカウンターがまずプリスケールレジスタの値(PR)と等しくなったときにタイマーカウンター(TC)が1つカウントされます。

TCの値とMR0~MR2の値が一致するときにvoid TIMER32_1_IRQHandler(void)にタイマー割り込みが発生して、そこに記述された動作をします。

さらに詳しい内容は、LPC111Xのユーザーマニュアルを参照してください。


日本語ユーザーマニュアル (15章)


Englich User Manual (Chapter 20)



2、PWM動作中には以下のような変更が可能です。



//data format

//15-12:setting(Header)
// 1 :stop PWM out
// 2 :Frequency setting
// 3 :Duty0 setting
// 4 :Duty1 setting
// 5 :Duty2 setting
// 6 :start PWM out
// other :Nothing
//11-0:Data


16bitのSPI信号で、15-12bit のコマンド部分は、上記の0~5を選択します。

settingと書いてあるところは12bitでデータを入れて調整することができます。
settingと書いていないところは12bit部分は0x000を入れて送信してください。

例えばDuty0 の値を 0x7FF に変えたいときは、16bit の 0x37FF (0011 0111 1111 1111)を送信すれば良いことになります。


実際にどのように動くかは以下の計算式で求められます。


4、RCサーボ用信号の設定

LPC1114FN28を例として、RCサーボ用の信号を想定して約20msecの周期を考えてみます。
そのうちHigh信号の期間が0~2msecの範囲を12bit分解能で調整できるようにしてみます。

初期化で initPWM(&MFM, 24, 40950, 0, 0, 0); と値を入れた場合、

(マイコンのクロック:48MHz)/(Divider:24) = 2MHz
これを(1/2MHz)*(Frequency 40950) ≒ 0.02sec=20msec
としています。

12bitの最大値は4095となります。Frequency 40950 としたので、最大でも周期の10%となります。そのため、サーボ用の信号は周期20msec その10%の範囲で設定できるようになり、0~2msecを12bit分解能で微調整できます。

(※注意:多少パルス幅に誤差があるので、場合によっては微調整が必要です)

    initPWM(&MFM, 24, 40950, 0, 0, 0);

    PWMDuty(&MFM, 1, 0x7FF);    //duty 1msec
    PWMDuty(&MFM, 2, 0x001);    //duty 500nsec
    PWMDuty(&MFM, 3, 0xFFE);    //duty 2msec

RCサーボモーターによって、最小パルスの大きさが違います。
その為サンプルプログラムの例では最小値を0x7FFとしています。最大値も物によっては差が出るかもしれませんので、微調整が必要になります。
モーターなので、電源はMCUGearからではなく、別系統で持ってきた方が安定します。GNDを共通にするのを忘れないでください。
また、マイコンのプログラム中は動きが不安定になるので、RCサーボモーターの電源を切ってから行って下さい。


5、通常のPWM信号の設定


例えば、12bit分解能で、0~100%を設定する場合は、Frequency を4095として、Dividerで同じ周期に調整します。20msecの周期のPWMを変化させる場合は以下のようになります。


    initPWM(&MFM, 240, 4095, 0, 0, 0);

    PWMDuty(&MFM, 1, 0x199);    //duty 10%
    PWMDuty(&MFM, 2, 0x7FF);    //duty 50%
    PWMDuty(&MFM, 3, 0xE65);    //duty 90%


6、応用として、PWM出力とローパスフィルターを利用したDA出力も可能です。




・I2Cテスト(SPI to I2Cデバイスとして動作します)


I2Cテストはユニバーサルモジュール2のゲート操作を行うことを前提に作られています。

別の通信速度のI2Cを動かしたり、アドレスがかぶってしまうようなデバイスを動作するときに使用します。

大まかな流れは

マイコンからMultifunction Module を通してI2Cでゲートを開き、ゲートの開閉状況をI2Cで読みとり、それをまたSPIでマイコン側に戻してシリアルポートから読み取る。
というものです。
これを一回だけ行われるようにしています。シリアルで取りこぼしたときは、パワーモジュールのリセットボタンを押すか、電源をOFF->ONすれば取れるはずです。

では、配線方法です。ユニバーサルモジュール2はベースボードから取り外した状態で使用します。


main.c で


#define AD_MODE  0

#define PWM_MODE  0
#define I2C_MODE  1

I2C_MODE を選択してください。


マイコン側では

mbed、KL25ZはMCUGear ライブラリのcommon.hを

//For Sample Mltifunction Mofdule-----------------------------

//#define AD_MODE
//#define PWM_MODE
#define I2C_MODE
//--------------------------------------------------------
としてください。
LPC1114FN28 のLPCXpressoの場合は main.c 内で

#define MultiFunctionModule 1

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

と定義してください。


SPI通信は16bitで動作し、前半8bitがアドレス、後半8bitがコマンドです。



ここでは試しにユニバーサルモジュール2のゲートスイッチをモジュール単体で操作してみようと思います。

以下のように配線しました。

I2Cはベースボードに取り付けていない場合、MCOM1にしか信号が通りませんのでご注意ください。またユニバーサルモジュール2のアドレスはmcugear.com内の組み立て方を参考にしてください。




プルアップ抵抗は2.2KΩと書いてありますが、今回は3KΩでテストしました。

MCOM1の2番端子をGNDにつなぎ、赤いLEDを適切な抵抗を付けて+3.3Vとユニバーサルモジュール2の2番信号端子に接続してあります。
もしゲートが開くと、LEDの2番信号端子がGNDになるという動きです。

サンプルプログラムを実行してみてください。LEDがONになり、一回だけ送ったデータがLPC1114FN28のuartを通して確認できます。


uartの信号をPCに接続して表示する方法はブログ内の別の記事を見てください。


2013年9月1日日曜日

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

MCU Gear ® を使ったプログラムの説明などを書いています

LPC1114FN28をUART(シリアル通信)で文字列とdouble型のデータをモニタリングしてみましょう。

動作確認用のサンプルプログラムは http://www.mcugear.com/ にあります。

LPC1114FN28のUART to USB(USB シリアル通信)を使ってPCからLPC1114FN28の状態をのぞいてみようと思います。状態が見えると何かと便利です。

MCUGearを通してモジュールのピンからもUARTは使えますが、プログラムを書き込む際に使用しているCOMポートがあるので、それをそのまま利用してみようと思います。

LPC1114FN28でモニタリングするのは、文字列、データ(double型、int型)の関数を用意しました。特にC言語の標準ライブラリはインクルードせずに使える、コンパクトに仕上がっていると思います。



準備するもの

・Tera Term 日本語版
   http://sourceforge.jp/projects/ttssh2/


・今回はMCU Gearは必須ではないですが、あるとそのままつながるので配線が楽です。


・LPC1114FN28が必要です。


・USB-UART のケーブル(LPC1114FN28にプログラムを書き込んでいるケーブルでOK)


Tera Termは定番のソフトで、工学部で少しでも電子電気をやった方ならまず知らない人はいないでしょう。


Tera Termをダウンロードしてインストールしてください。

起動するとTera Termをどこに接続するかを選択できます。LPC1114FN28につないでいるUSBがどのCOMポート番号に割り振られているかを調べてください。



ここではVer 4.78の物を使っています。

windows8で使っていますが、自動的に接続先の情報を集めてくれるようになっているようです。
それ以外のツールで使うときにCOMポートを調べるには以下の方法があります。

COMポート番号の調べ方

コンピュータアイコンの上で右クリック->プロパティ->デバイスマネージャー
を選ぶと、デバイス一覧が出てきます。
そこで、COMポートと出ているので、その番号を控えておきます。

※Tera TermとFlash Magic は同じ通信経路を通っているので、どちらか片方づつ使ってください。競合すると動かなくなります。


LPC1114FN28側のプログラムです。


#include "SimpleUart.h" をインクルードしてください。


void initUART(uint32_t baudrate); でボーレートをセットします。

void UART_Puts(char *str);  でテキストを出力します。


void UART_PutData(double dataD, uint32_t iKeta); 

double dataD はdouble型とint型を入れられます。(warningが出る場合はキャストすると出なくなると思います。)
uint32_t iKetaは表示する小数点の桁数を入れてください。
マイナスも表示されます。小数点は四捨五入されます。
あまり細かい小数点は出せないかもしれません、限度を試していないので目的の桁数でも動作するかを確認してから使ってください。


initUART(9600);
UART_Puts("TEST\r\n");

dData = -123.45678;

UART_PutData(dData, 3);
UART_Puts("\r\n");
  mwait01(1000); //100msec

上記のプログラムを実行すると、ボーレート9600で, 

TEST
-123.457
 と四捨五入で表示されます。


もし指定桁数内に小数点以下が 0 ではない場合、0も表示されます。

例)
1.000000 を 少数点以下3桁で表示しょうとすると 1
1.300000 を 少数点以下3桁で表示しょうとすると 1.300

速すぎると見にくいので適度にmwait01( );を使ってください。


MCU Gear のプログラム:その2 mbed FRDM KL25Z 編

MCU Gear ® を使ったプログラムの説明などを書いています

MCUGear® のサンプルプログラムを参考に簡単な動作説明をします。
多少説明が間違っているかもしれません、その場合予告なく修正する可能性がありますのでご容赦ください。
かなり詳しく説明したつもりです。パッと見、分量が多い様ですが当たり前のことも多く書いています。気長に読んでみてください。
また、ここにも細かな注意点が書いてあります。

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

目標は動画のような雰囲気です。
KL25Zはベースボードの下のマイコンボードに取り付けます。動画はイメージです


回路のイメージは以下のような雰囲気です。青い小さな四角は抵抗です。LEDに+3.3Vか+5V(ユニバーサルモジュールは5Vトレラント入力対応です)をかけて抵抗は220Ω、スイッチに1KΩ使ってます。LEDの種類によっては変化しますので適宜計算してみてください。

この回路を実現するための再配線をしてみましょう。




まず設定の確認をしましょう。
mbedのwebコンパイラはデバイスを選択できるようにコンパイラ画面右上にデバイス選択ボタンが用意されています。それを押してKL25Zを選んでください。

次にMCUGearライブラリのcommon.hを使いたいデバイスと合わせてください。
//select your mbed--------------------------------------------
//#define LPC1768_mbed
#define FS_KL25Z


最も基本的なユニバーサルモジュール2だけを使ってみましょう。
KL25Zのサンプルコードのmain.c を順番に見ていきましょう。

#include "MCUGearBase.h"

#include "MCUGear.h"
#include "common.h"
MCUGearのライブラリがあることを確認して、プログラムをインクルードしています。

MCUGear Uni2M(PTE0, PTE1, N_VDD_VDD_VDD,8);
これはMCUGearのモジュールを定義する部分です
MUCGear クラス(色々と設定情報などの塊と考えておいてください。)をUni2M という名前で定義して生成します。
かっこ内は
PTE0, PTE1 : I2Cの端子(専用のマイコンボードを使う限りはこのままです。)
N_VDD_VDD_VDD : はモジュールの下の設定したアドレスのを入れます。AD2 AD1 AD0 の順番に書き込んでください。VDD = +3V3、 VSS = GND と定義されているので覚えておいてください。また「N_」は コントロール用のI2CデバイスPCA9674、「A_」は  コントロール用のI2CデバイスPCA9674Aを表しています。
※A_VDD_VSS_VSSはベースボードのアドレスとかぶってしまうので設定できません。
8 :これはこのモジュールで使用するピン数を指定します。今回の回路では8ピン必要ですので8と入れてます。




DigitalOut Dout(PTA13);

DigitalOut Dout1(PTA1);
DigitalOut Dout2(PTA2);
DigitalOut Dout3(PTD4);
DigitalOut Dout4(PTA12);
DigitalOut Dout5(PTA4);
DigitalIn Din1(PTB0);
DigitalIn Din2(PTB1);
ここではKL25Z本来の端子の設定を行っています。

void IOUni2M(MCUGear *mcugear);    
プロトタイプ宣言 「こんな関数がここでは用意されてますよ」とあらかじめ宣言して浸透させておくというイメージで考えてください。

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

IOUni2M(&Uni2M);
ここでは、先ほど生成したUni2M のIOの設定をしています。
では、IOUni2M 関数内部を見てみましょう。

void IOUni2M(MCUGear *mcugear){

    uint8_t fio[12];

    // detect SHM
    mcugear->detect_module(fio);
    
    //PTA1, PTA2, PTD4, PTA12, PTA4, PTA5, PTC8
    mcugear->savePinSetting(0, IO_MBED_PTB0, IO_REG_IN_DIR, fio[0]);
    mcugear->savePinSetting(1, IO_MBED_PTB1, IO_REG_IN_DIR, fio[1]);
    mcugear->savePinSetting(2, IO_MBED_PTA13, IO_REG_OUT_DIR, fio[2]);
    mcugear->savePinSetting(3, IO_MBED_PTA1, IO_REG_OUT_DIR, fio[3]);
    mcugear->savePinSetting(4, IO_MBED_PTA2, IO_REG_OUT_DIR, fio[4]);
    mcugear->savePinSetting(5, IO_MBED_PTD4, IO_REG_OUT_DIR, fio[5]);
    mcugear->savePinSetting(6, IO_MBED_PTA12, IO_REG_OUT_DIR, fio[6]);
    mcugear->savePinSetting(7, IO_MBED_PTA4, IO_REG_OUT_DIR, fio[7]);

#ifdef BOOST_MODE
    mcugear->makeCircuit();
#endif

}


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

1、mcugear->detect_module(fio); を使ってモジュールの位置を把握し登録します。配列は8bit のuint8_t 12個の配列を使います。

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

3、
 #ifdef BOOST_MODE
    mcugear->makeCircuit();
#endif

オーバーヘッドを極力減らし自動化したモードです。(慣れてきてから試してみてください)
MCUGearにはバンクというレイヤーのようなものが存在しています。これは再配線する祭に、あらかじめ決まった配線をベースボードに登録しておき、レイヤーの切り替え命令だけで高速に配線を切り替えるためのものです。Bankは0~7まで設定できます。KL25Zのサンプルプログラムでは自動的に動作させることができますが、多くのモジュールを使うとバンクが足りなくなるので通常モードのモジュールそして動作します。
common.h
#define BOOST_MODE //if you want use BANK System, define this.
を定義すると動きます。
また、バンク部分のプログラムを作り替えるときは、複雑な動きをするので上級者向けです。(「マイコン端子の分岐は出来ない」ということを考えながら使ってください。)



int SW1,SW2;
タクトスイッチの入力信号を一旦保存するための変数です。

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

       Dout = 1;
       Dout1 = 1;
       Dout2 = 1;
       Dout3 = 1;
       Dout4 = 1;
       Dout5 = 1;

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


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

       SW1 = Din1.read();
       SW2 = Din2.read();

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

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

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





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



       if(SW1 == 1){
            Dout = 1;
            Dout2 = 1;
            Dout3 = 1;
       }else{
            Dout = 0;
            Dout2 = 0;
            Dout3 = 0;
       }


       if(SW2 == 1){
            Dout1 = 1;
            Dout4 = 1;
            Dout5 = 1;
       }else{
            Dout1 = 0;
            Dout4 = 0;
            Dout5 = 0;
       }

wait(1000);等を途中途中に入れると処理の様子をじっくり見れます。


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


後は同様に
Uni2M.connectModule();

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

Uni2M.disconnectModule();





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

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

MCU Gear ® を使ったプログラムの説明などを書いています

MCUGear® のサンプルプログラムを参考に簡単な動作説明をします。
多少説明が間違っているかもしれません、その場合予告なく修正する可能性がありますのでご容赦ください。
かなり詳しく説明したつもりです。パッと見、分量が多い様ですが当たり前のことも多く書いています。気長に読んでみてください。

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

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





回路のイメージは以下のような雰囲気です。青い小さな四角は抵抗です。LEDに+3.3Vか+5V(ユニバーサルモジュールは5Vトレラント入力対応です)をかけて抵抗は220Ω、スイッチに1KΩ使ってます。LEDの種類によっては変化しますので適宜計算してみてください。

この回路を実現するための再配線をしてみましょう。



まず設定の確認をしましょう。
mbedのwebコンパイラはデバイスを選択できるようにコンパイラ画面右上にデバイス選択ボタンが用意されています。それを押してLPC1768を選んでください。

次にMCUGearライブラリのcommon.hを使いたいデバイスと合わせてください。
//select your mbed--------------------------------------------
#define LPC1768_mbed

//#define FS_KL25Z


最も基本的なユニバーサルモジュール2だけを使ってみましょう。
mbedのサンプルコードのmain.c を順番に見ていきましょう。

#include "MCUGearBase.h"

#include "MCUGear.h"
#include "common.h"
MCUGearのライブラリがあることを確認して、プログラムをインクルードしています。

MCUGear Uni2M(p28, p27, N_VDD_VDD_VDD,8);
これはMCUGearのモジュールを定義する部分です
MUCGear クラス(色々と設定情報などの塊と考えておいてください。)をUni2M という名前で定義して生成します。
かっこ内は
p28, p27 : I2Cの端子(専用のマイコンボードを使う限りはこのままです。)
N_VDD_VDD_VDD : はモジュールの下の設定したアドレスのを入れます。AD2 AD1 AD0 の順番に書き込んでください。VDD = +3V3、 VSS = GND と定義されているので覚えておいてください。また「N_」は コントロール用のI2CデバイスPCA9674、「A_」は  コントロール用のI2CデバイスPCA9674Aを表しています。
※A_VDD_VSS_VSSはベースボードのアドレスとかぶってしまうので設定できません。
8 :これはこのモジュールで使用するピン数を指定します。今回の回路では8ピン必要ですので8と入れてます。





DigitalOut Dout(p15);
DigitalOut Dout1(p16);
DigitalOut Dout2(p21);
DigitalOut Dout3(p22);
DigitalOut Dout4(p23);
DigitalOut Dout5(p24);
DigitalIn Din1(p9);
DigitalIn Din2(p10);
ここではmbed本来の端子の設定を行っています。

void IOUni2M(MCUGear *mcugear);    
プロトタイプ宣言 「こんな関数がここでは用意されてますよ」とあらかじめ宣言して浸透させておくというイメージで考えてください。

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

IOUni2M(&Uni2M);
ここでは、先ほど生成したUni2M のIOの設定をしています。
では、IOUni2M 関数内部を見てみましょう。

oid IOUni2M(MCUGear *mcugear){

    uint8_t fio[12];
    // detect
    mcugear->detect_module(fio);

    mcugear->savePinSetting(0, IO_MBED_P9, IO_REG_IN_DIR, fio[0]);  //input
    mcugear->savePinSetting(1, IO_MBED_P10, IO_REG_IN_DIR, fio[1]); //input
    mcugear->savePinSetting(2, IO_MBED_P15, IO_REG_OUT_DIR, fio[2]);
    mcugear->savePinSetting(3, IO_MBED_P16, IO_REG_OUT_DIR, fio[3]);
    mcugear->savePinSetting(4, IO_MBED_P21, IO_REG_OUT_DIR, fio[4]);
    mcugear->savePinSetting(5, IO_MBED_P22, IO_REG_OUT_DIR, fio[5]);
    mcugear->savePinSetting(6, IO_MBED_P23, IO_REG_OUT_DIR, fio[6]);
    mcugear->savePinSetting(7, IO_MBED_P24, IO_REG_OUT_DIR, fio[7]);

#ifdef BOOST_MODE
    mcugear->makeCircuit();
#endif

}

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

1、mcugear->detect_module(fio); を使ってモジュールの位置を把握し登録します。配列は8bit のuint8_t 12個の配列を使います。

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

3、
 #ifdef BOOST_MODE
    mcugear->makeCircuit();
#endif

オーバーヘッドを極力減らし自動化したモードです。(慣れてきてから試してみてください)
MCUGearにはバンクというレイヤーのようなものが存在しています。これは再配線する祭に、あらかじめ決まった配線をベースボードに登録しておき、レイヤーの切り替え命令だけで高速に配線を切り替えるためのものです。Bankは0~7まで設定できます。mbedのサンプルプログラムでは自動的に動作させることができますが、多くのモジュールを使うとバンクが足りなくなるので通常モードのモジュールそして動作します。
common.h
#define BOOST_MODE //if you want use BANK System, define this.
を定義すると動きます。
また、バンク部分のプログラムを作り替えるときは、複雑な動きをするので上級者向けです。(「マイコン端子の分岐は出来ない」ということを考えながら使ってください。)



int SW1,SW2;
タクトスイッチの入力信号を一旦保存するための変数です。

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

       Dout = 1;
       Dout1 = 1;
       Dout2 = 1;
       Dout3 = 1;
       Dout4 = 1;
       Dout5 = 1;

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


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

       SW1 = Din1.read();
       SW2 = Din2.read();

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

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

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





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



       if(SW1 == 1){
            Dout = 1;
            Dout2 = 1;
            Dout3 = 1;
       }else{
            Dout = 0;
            Dout2 = 0;
            Dout3 = 0;
       }


       if(SW2 == 1){
            Dout1 = 1;
            Dout4 = 1;
            Dout5 = 1;
       }else{
            Dout1 = 0;
            Dout4 = 0;
            Dout5 = 0;
       }

wait(1000);等を途中途中に入れると処理の様子をじっくり見れます。


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


後は同様に
Uni2M.connectModule();

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

Uni2M.disconnectModule();

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

MCU Gear のプログラム:その1 LPC1114FN28, mbed LPC1768, mbed K25Z 共通

MCU Gear ® を使ったプログラムの説明などを書いています

MCU Gear® を使うと自動的にデバイスを搭載したモジュールを発見し、デバイスとマイコンとのデジタル回路を再構成しながら動かすことができます。




単純なシリアル通信ではなく、通常のデジタル回路を動作中に再配線してデバイスを動かすという方法を採用しているため、従来のライブラリも使用可能です。

また切り分けて開発できるので、別の回路を作るときに以前作った回路を再利用することも容易です。

単純なイメージ図は以下のようになります。マイコンが動作中にIOを色々なデバイスに切り替えながら動きます。
ユーザーはプログラムで「マイコンのIOをどのモジュールの何番ピンを接続するか」を指定するだけで自動的に探して動作中に切り替えながら動きます。

途中経路は気にせず、色々ごちゃっと積層して動かすことができます。アドレスの設定パターン数を考えて、理論上は1つのマイコンに約120個程度取り付けることができます。(もちろん実際には動作速度や信号の劣化など、様々な制限がかかります。)


MCU Gear の構成は以下の3つです。

1、マイコンボード・・・LPC1114FN28のDIPマイコン, mbed LPC1768, FRDM-KL25Zなどの+3.3V系マイコンやボードを一枚の基板で扱うことができます。(+5V系マイコンボードは電圧レベル変換ボード等を使用する必要があります。)

~ディーノ系は技術的に検証していない部分が多いので推奨はしませんが、動作確認はできるようにサンプルプログラムは準備中です。


 


2、ベースボード・・・マイコンボードの信号線をベースボード上のコネクタに再配線するデジタルスイッチを搭載しています。マイコンボードなしてもブレッドボードなどに配線すれば別のマイコンを取り付けることもできます。

3、拡張モジュール・・・ベースボードからの信号をデバイスにつなげるかを選択するデジタルスイッチが搭載されています。



以下、どのマイコンを選択するかの参考です。
フリー版のLPCExpressoではC++での開発ができないのでCだけでよい方はこちらを使いましょう。
今後LPC1114FN28もmbedのweb開発環境が使えるそうなので、その時はそちらも試してみようと思います。



  LPC1114FN28 mbed FRDM-KL25Z
C言語 O O O
C++ X(Free版) O O
IDE アプリケーション Web上 Web上
価格 110円前後 5000円前後
1400円前後
(Digi-Key)
(※注意:海外通販で購入する場合は為替で変動します。 2013/06/1現在の情報)
※mbed でもLPC1114FN28対応できるようになったようです。


MCU Gearのプログラムの簡単な流れです。

1、初期化
   a、ベースボード初期化
   b、拡張モジュールの位置を把握
   c、拡張モジュール毎のマイコンとの配線情報を保存

2、動作中(繰り返し)
   a、目的の拡張モジュールと接続は設定されたアドレスを指定
   b、接続後のデバイスとは従来通りの操作。
   c、目的の拡張モジュールと切断

プログラムに必要な項目を見るとわかると思いますが、プログラマーは拡張モジュール上のデバイスが、マイコンのどの端子を割り振るかさえわかっていれば良いので、MCUGear内の途中経路は気にしないで作れます。これにより、拡張モジュールをごちゃっと積層しても動かすことができます

では次回実際にその流れを見てみましょう。