目次
前
次
方向指示器
方向指示器をエミュレートするには、LEDと抵抗を
ブレッドボード上に載せて、IchigoLatte基板から
電源と制御信号を与えます。
方向指示器の仕様を次のように決めます。
- IN_1にプッシュボタンを接続
- IN_2にプッシュボタンを接続
- IN_1を使って、左のLEDを点滅
- IN_2を使って、右のLEDを点滅
- 左LEDは、OUT_1に接続
- 右LEDは、OUT_2に接続
- 点滅は5回とする
動作イメージは、以下。
入力は、関数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以上になると、この方法を採用すると
対象ビットのマスク操作が不要で、考えやすくなると
思います。
目次
前
次