久々に LPC114514 1114 をいじろうという気が起きたんですが、これを期に aitendo 等でよく見かける IchigoJam を超簡易的に作ってみようと思った記事です。
簡易的なので、ハンダの類は一切使用しません。すべてブレッドボード上で作り上げます。
参考にしたサイト
- パソコンと接続 - イチゴジャム レシピ
- HOME of IJUtilities
- CPU ピン配置 - イチゴジャム レシピ
- IchigoJam BASIC リファレンス ver 1.2.2
- (資料)プログラミング教材 | プログラミング | PCN金沢
- はじめてのマシン語 - IchigoJamではじめるArmマシン語その1 #IchigoJam #KidsIT #Arm / 福野泰介の一日一創 / Create every day by Taisuke Fukuno
マイコン
当然 LPC1114 です。型が同じなら SSOP 版でも DIP 版でもなんでも良いです。今回はオリジナルと同じの DIP 版(FN28)があったのでこちらを使います。秋月の販売サイトはこちら。
使用ハードウェア
中心になってくるのは LPC1114 マイコンです。こちらですべての処理が行われます。電源電圧は 3.3V なのでご注意を。更に USB-シリアル変換モジュールも必要ですね。僕は自作基板とマイコンを接続しました。接続した LPC1114 のピン配置は以下の通り。
pin # | ピン名 | 備考 |
---|---|---|
15 | TXD | シリアル変換モジュールの RXD と接続 |
16 | RXD | シリアル変換モジュールの TXD と接続 |
21 | VDD | 3.3V と接続 |
22 | GND | |
23 | PIO0_0 | リセット端子。Lowでリセット状態 |
24 | PIO0_1 | リセット時、ここのロジックによってブートモードが変わる |
...これだけです。後はファームウェアを書き込むだけで環境構築完了!ブザーとかは使う時逐一付けてしまえば良いんです。ファームウェアは落として ichigojam-ntsc-jpkbd.bin を書き込みます。FlashMagic を使う人は頑張って。lpc21isp
の方は以下のコマンドでいいでしょう。
$ lpc21isp -bin ichigojam-ntsc-jpkbd.bin /dev/tty.usbmodem1412 115200 120000
書き込み時は PIO0_1 を Low にして、PIO0_0 を Low から High に立ち上げると良いです。その後 PIO0_1 を High にして、再度 PIO0_0 を立ち上げてください。
通信用ソフト
いつものように screen
を使えばいい...と思ったんですが、改行コードの関係で非常に都合が悪いです。こんな感じに↓
ということで、HOME of IJUtilitiesから IJUtilities を利用します。僕は Mac64bit 版を選択しました。この中の README 的なものに従っておけばいいです。すると下のように良い感じの開発環境が整ったことになります。
ピン配置
CPU ピン配置 - イチゴジャム レシピに良い感じにありますのでご参照を。
実行モード(?)
よく分かっていないんですが、行番号を付けずに1行入力すると即座に実行されるインタプリタモード(?)的な挙動になるようです。一方で行番号を行頭に付した場合、プログラムの打ち込みモード的なものになって、最後に run
を打つことで実行されるとのことです。後者はプログラムを繰り返して実行できるという点で(run
を再度打つだけで直前のプログラムを実行可能)ちがいます。
プログラムの保存・呼び出し
打ち込んだプログラムは保存することが出来ます。インタプリタのものではなく、行番号を付けて打ち込んだ一連のプログラムが対象です。プログラムは LPC1114 マイコンの Flash 領域に保存することが出来、スロットは 0 から 3 までの4つのみとなっています。
save 0 ' 0番に保存
呼び出しは load
で行うことが出来、メモリにロードされたプログラムを確認するには list
を打ちます。
load 0 ` 0番のプログラムを呼び出し
実行する場合は run
とすれば良いです。
プログラム例
とりあえずLチカ
LED を点灯させるだけなら簡単です。とりあえずLEDを接続し(#14)、ポート名 値
と書けばよし。どうやら値は 0 以外を True と見るようです。LED ポートを付けるには LED 1
ですね。
以下は LED をチカチカさせる例。wait 値
で値は100分の1秒を指定するようです。
10 led 1
20 wait 50
30 led 0
40 wait 50
50 goto 10
run
無限ループなので Esc を押してブレークしてください。なおこのように行番号を使って書いた場合は、その番号を重複させて別のプログラムを書くことは出来ないようです(エラーは出ないが)。なので逐一 new
を実行して現在のプログラムを破棄するようにしましょう。
LED ボヤァ
ホタルのように3回光ります。ポートは PWM 制御の関係で OUT4(#12)となります。
10 let c, 0
20 for i=0 to 2000 step 20 : pwm 4, i : next
30 for i=0 to 2000 step 20 : pwm 4, 2000 - i : next
40 let c, c + 1
50 if c <> 3 goto 20
run
サイコロ
要は乱数を出せばいいだけです。ということで run
を除けば一行で終了。
10 print rnd(5) + 1
run
run
を何度も叩けば繰り返しサイコロを振れますね。
圧電ブザーを鳴らす
SOUND端子(#25)に圧電ブザーを接続すると(ブザーの端子の他方はGNDに固定)、IchigoJam で音の演奏ができます。というか特に設定しなくても、エラー時にピッっと音がなるんですね。楽しい。
play "T120<CDEFEDC" ' ちょっと音痴なカエルの歌冒頭
play "T250<CDE2DCRRCDEDCD1" ' チャルメラ
フィボナッチ数列の計算
Fib(n)(n: 整数)、Fib(0) = 0, Fib(1) = 1 としてフィボナッチ数列(Fib(n+2) = Fib(n) + Fib(n+1) を満たす数列: Fib(n) for n >= 0)を求めるプログラムです。こちらではサブルーチン呼び出しを行っています。といっても、行番号を指定してカタマリの最後に return
を書くだけです。なおメインルーチンで end
を書かない場合、10 -> 20 -> ... と実行されていって、ついにはサブルーチン内に入り込みます。そして最終的に return
が実行されて戻り先がないためエラーになってしまいます。サブルーチンを使う時はメインルーチンを end
で〆ましょう。
また、以下では配列操作を行っています。配列は無名の [0]
から [100]
までの100個あり、それぞれインデックス番号にて参照・書き込み可能です。
' こちらが計算をするルーチン
100 [0] = 0 : [1] = 1
110 for i=0 to x-2
120 [i+2] = [i] + [i+1]
130 :next
140 return
' メインルーチン
' とりあえずFib(10)まで求めて順に出力
10 x = 10
20 gosub 100
30 for i=0 to x
40 print [i]
50 :next
60 end
run
ARM アセンブリ
なんと、ARM の命令をハンドアセンブルして打ち込むことが出来ます! poke
命令を使えば、指定したメモリアドレスにデータを連続的に書くことが出来るのです。
はじめてのマシン語 - IchigoJamではじめるArmマシン語その1 #IchigoJam #KidsIT #Arm / 福野泰介の一日一創 / Create every day by Taisuke Fukunoを参考にされたし。
以下は 指定した数値まで足していくプログラムです(Σ i を求めるもの)。
まず疑似コードを考えました。そしたらこの参照先のページと全くおなじになってしまったんですが、一応以下に掲載します。
r1 = 0
r1 = r1 + r0
r0 = r0 - 1
IF Not ZeroFlag GOTO -2
r0 = r1
RET
これをハンドアセンブルして機械語を #700
番地に書き込んだものが以下。実際にハンドアセンブルすると上位8ビットと下位8ビットが逆転しているのに気が付くとおもいますが、これは ARM がリトルエンディアンであるためです。
あとついでに、上のサイトで機械語表のジャンプ先アドレスに << 1
が付いている理由ですが、これはまあ命令コードが 16bit なもんで、1命令に 2Byte 分のサイズが必要ですよね。ですので命令1個単位で見ると2倍になっているということです。そして更に更に、 GOTO
の相対的なジャンプ先命令位置に -2 をする理由なのですが、ARM はプログラムカウンタが実行中の命令の2つ先を指しているので、これに対応するものだと思われます。
poke #700, #00,#21,#09,#18,#01,#38,#FC,#D1,#08,#43,#70,#47
あとは usr
で実行・返り値の取得ができます。第一引数は開始メモリアドレス、第二引数は r0 に渡す値です。print usr(#700, 100)
とすると 1/2 * 100 * (100 + 1) = 5050 と同じ値が出るはずです。
なおこの機能はユーザが打ち込んだ機械語を素直に実行してくれるものですから、ブレーク等は一切聞かず、暴走したらしっぱなしです。返ってこなかったら諦めて電源を落としましょう。
その他制御・演算
A to Z
AからZまで、各行に表示する
for i=asc("A") to asc("Z") : ?chr$(i) : next
2の補数計算
ベタですみません。。。。ビット演算の練習に。
print ~10 + 1 + 5
〆
いやぁ、こんなレガシーな BASIC というものを手軽に、そしてものづくりに応用できるようなシステムを作るなんてすごいです〜
YouTube とか観てると「基板作ってみた」とか「プログラム書いてみた」とかありますよね。そんな軽いノリで黒い画面に立ち向かえる人が増えることを期待します。
ちなみに以下はこの IchigoJam を作った jig.jp さんのページです。
このページのサンプルは気が向き次第追記していきます〜〜〜
見つけた良い感じの教材
追記したい
- I2C
コメント
マシン語まで使ったご紹介ありがとうございます!IchigoJamをつくっている者です。
WAITのパラメーターは垂直同期の数を使っているので、1/100secではなく1/60sec(PALの場合1/50sec)となってます。小学生に紹介する時には秒間60コマの超高速紙芝居だよっと説明してます。(ゲーム好き学生にはFPS値で通じますね)
本日リリースした、IchigoJam BASIC ver 1.4 では、例外を使用して暴走が起きにくい状態としたので、少し気軽にマシン語で遊べるようになりました!
https://fukuno.jig.jp/2487
APIテーブルを用意したのでオールマシン語プログラムでできる幅も広がってます。
https://fukuno.jig.jp/2498
福野さん
コメントありがとうございます!実はTwitterで相互フォロー頂いています(笑)
WAITに関しまして、ご指摘ありがとうございます。そういう意味があったんですね〜〜
僕は高レイヤなフレームワークは好きではないのですが、BASIC上で機械語を打てるということに好感を持ちまして記事にさせて頂きました。
いろいろ試している時は暴走が面倒くさいなと思っていたのですが(でもおそらくHardFault_Handlerに飛んでいますよね)、その点を準備してくださったことはとても有り難いなあと感じます。
IchigoJamはワンコマンドでLチカを楽しめる比較的高レイヤなプログラミング環境である一方、このように低レイヤな環境としても大きく楽しめることは非常に魅力を感じております。
今後とも楽しませていただきます。コメントありがとうございました。