目次

方向指示器

 方向指示器をエミュレートするには、LEDと抵抗を
 ブレッドボード上に載せて、IchigoLatte基板から
 電源と制御信号を与えます。



 方向指示器の仕様を次のように決めます。

 動作イメージは、以下。



 入力は、関数inを使います。
 2つのプッシュボタンは、以下のように接続。



 INで値を入力して、変数に保存します。

var l ;
var r ;

l = gpin(1);
r = gpin(2);

 点滅は、左右に分けて関数を定義して処理します。
 out命令を使えると思ったのですが、ピンアサイン
 で、出力(OUT_1..OUT_6)をアクセスできる仕様
 になっていません。




 IchigoLatteでは、ARMのLPC1114を利用しているので
 内部レジスタのGPIOに関係する値を使えばIchigoJam
 で使われているOUT命令と等価な処理は可能。

 内部レジスタにアクセスするには mem を利用。
 memには、複数のパラメータ設定の仕方があるのですが
 次のフォーマットを利用。

  mem(v)       : if v is number, a byte will return on the address v
 mem(a,v,...) : write v to memory of address a

 GPIOでOUT_1からOUT_6に関係するアドレスは、以下。

GPIO1_DATA 0x50010000
GPIO1_DIR  0x50018000

 IchigoLatteのJavaScriptでは、値は32ビットで扱うので
 方向を設定してから、ビットごとの1と0を設定すると
 OUT_1からOUT_6への出力論理値を確定できます。

 入出力方向の指定には、DIRレジスタの値を取り出して
 下位6ビットを出力に設定すればOK。

function gpout_set()
{
  var ddra = 0x50018000;
  // set lower 6 bits as OUTPUT
  mem(ddra,mem(ddra) | 0x3f);
}

 特定のビットに1あるいは0を設定するときには
 論理演算を利用。これを関数でまとめてます。

function gpout(x,v)
{
  var xadr = 0x50010000;
  var xdat ;
  // generate logical value
  xdat = 0xfff ;
  if ( v == 0 ) { xdat = xdat & v ; }
  // calculate address
  bl = (1 << (x-1)) << 2;
  if ( x == 5 ) {  bl = (1 << 11); }
  if ( x == 6 ) {  bl = (1 << 10); }
  xadr = xadr + bl ;
  // set logical value
  mem(xadr,xdat);
}

 IchigoLatteは、マイコンチップLPC1114を使って
 いるので、ビットに割り当てられたアドレスに0
 かそれ以外をライトすると、該当ピンが0か1に
 なることを利用。

 ここまでで、IchigoJamのBASICにあるOUT命令と
 等価な処理を実現できる関数を用意したので
 ラッパー関数を追加して、より使いやすいよう
 にしていきます。

function clr_led()
{
  gpout(1,0);
  gpout(2,0);
}

function left_flash()
{
  for (i = 0 ; i < 5 ; i = i+1 ) {
    gpout(1,1);
    sleep(500);
    clr_led();
    sleep(500);
  }
}

function right_flash()
{
  for (i = 0 ; i < 5 ; i = i+1 ) {
    gpout(2,1);
    sleep(500);
    clr_led();
    sleep(500);
  }
}

 JavaScriptのコードにまとめます。

function gpout_set()
{
  var ddra = 0x50018000;
  // set lower 6 bits as OUTPUT
  mem(ddra,mem(ddra) | 0x3f);
}

function gpout(x,v)
{
  var xadr = 0x50010000;
  var xdat ;
  // generate logical value
  xdat = 0xfff ;
  if ( v == 0 ) { xdat = xdat & v ; }
  // calculate address
  bl = (1 << (x-1)) << 2;
  if ( x == 5 ) {  bl = (1 << 11); }
  if ( x == 6 ) {  bl = (1 << 10); }
  xadr = xadr + bl ;
  // set logical value
  mem(xadr,xdat);
}

function clr_led()
{
  gpout(1,0);
  gpout(2,0);
}

function left_flash()
{
  for (i = 0 ; i < 5 ; i = i+1 ) {
    gpout(1,1);
    sleep(500);
    clr_led();
    sleep(500);
  }
}

function right_flash()
{
  for (i = 0 ; i < 5 ; i = i+1 ) {
    gpout(2,1);
    sleep(500);
    clr_led();
    sleep(500);
  }
}

var l ;
var r ;

gpout_set();
clr_led();
while (1) {
  l = gpin(1);
  r = gpin(2);
  if ( l == 1 ) { left_flash(); }
  if ( r == 1 ) { right_flash(); }
}

 関数は少ない方がデバックしやすいので、左右の点滅を
 ひとつの関数にまとめます。

function led_flash(x)
{
  for (i = 0 ; i < 5 ; i = i+1 ) {
    gpout(x-1,1);
    sleep(500);
    clr_led() ;
    sleep(500);
  }
}

 関数を呼び出す方は、次のように変更。

while (1) {
  l = gpin(1);
  r = gpin(2);
  if ( l == 1 ) { led_flash(1); }
  if ( r == 1 ) { led_flash(2); }
}

 全体は、以下。

function gpout_set()
{
  var ddra = 0x50018000;
  // set lower 6 bits as OUTPUT
  mem(ddra,mem(ddra) | 0x3f);
}

function gpout(x,v)
{
  var xadr = 0x50010000;
  var xdat ;
  // generate logical value
  xdat = 0xfff ;
  if ( v == 0 ) { xdat = xdat & v ; }
  // calculate address
  bl = (1 << (x-1)) << 2;
  if ( x == 5 ) {  bl = (1 << 11); }
  if ( x == 6 ) {  bl = (1 << 10); }
  xadr = xadr + bl ;
  // set logical value
  mem(xadr,xdat);
}

function clr_led()
{
  gpout(1,0);
  gpout(2,0);
}

function left_flash()
{
  for (i = 0 ; i < 5 ; i = i+1 ) {
    gpout(1,1);
    sleep(500);
    clr_led();
    sleep(500);
  }
}

var l ;
var r ;

gpout_set();
clr_led();
while (1) {
  l = gpin(1);
  r = gpin(2);
  if ( l == 1 ) { left_flash(1); }
  if ( r == 1 ) { left_flash(2); }
}

 マイコンチップLPC1114のGPIOは、アドレスを利用して
 1ビットあるいは複数ビットの論理値を設定できます。

 GPIO1のビット0、1の複数ビットを一度に設定したい時
 データレジスタ0x50010000にオフセットを加えて対応する
 各ビットのアドレスを計算で求めます。

 ビット0、1を選択するので2進数11を用意し、2ビット
 シフトして0x50010000に加えます。

  var xadr = 0x0x50010000 ;

  xadr = xadr + (3 << 2);

 2つのビットのアドレスを一度に決めたので、出力したい
 論理値をそれぞれ決めて書込むと、他ビットをマスクする
 手間を省けます。

  var xadr = 0x50010000 ;

  xadr = xadr + (3 << 2);
  mem(xadr,0); // 00
  mem(xadr,1); // 01
  mem(xadr,2); // 10
  mem(xadr,3); // 11

 LPC1114の特徴を利用すると、全LEDを消灯するには
 次の関数で対応できます。

function clr_led()
{
  var xadr = 0x50010000 ;

  xadr = xadr + (3 << 2);
  mem(xadr,0);
}

 複数ビットが4以上になると、この方法を採用すると
 対象ビットのマスク操作が不要で、考えやすくなると
 思います。

目次

inserted by FC2 system