やっぱり最初はLEDピカピカ [ColdFire V2]
SilentC で、アプリケーションを作りました。 やっぱり、最初は LED ピカピカでしょう。
ちょっと、お借りします
付録基板には、 LED が二個実装されていますが、どちらも ETHER ポートの状態を示すために使用されています。 今回のプログラムでは、これら二つの LED をお借りして LED ピカピカを実現します。
回路図を見ると、二つの LED は、 ACTLED と LNKLED の二つの端子に接続されています。 これらの端子は、それぞれ、 PLD[0] と PLD[1] という別名を持っていて、汎用入出力ポートとして使用することが出来ます。 汎用出力として使用する場合には、 PLDPAR[x] ビットをクリアし、 DDRLD[x] ビットをセットします。 LED の点灯状態を制御するには、 PORTLD[x] ビットを使用します。 このビットをクリアすると点灯、セットすると消灯します。
なお、これらの端子は LED 出力として使用することを前提として作られているはずなのですが、 LED を駆動するために定電流制御を行うわけでもなく、大電流に対応したドライバがつながっているわけでもなく、他の汎用出力と同じ仕様になっているようです。
さあ、方針が決まったところでプログラミングの開始です。
PEEK は、どこ? POKE は、どこ?
マイコンのペリフェラルにつながっているレジスタをアクセスするためには、 メモリ空間の特定のアドレスへのアクセスをする手法が必要です。
そこで、「PEEK 関数と POKE 関数」を探したのですが、見当たりません。 よくよく考えたら、 C では、こういった関数を使わなくてもメモリへのアクセスは自由に出来るのでした。 インタプリタと言っても、 BASIC じゃなかったのね。
10 main(){ 20 char *portld = 0x40100015; // PORTLD 30 char *ddrld = 0x4010002D; // DDRLD 40 char *pldpar = 0x40100075; // PLDPAR 50 *portld &= 0xFC; // PORTLD[1:0]=0 60 *ddrld |= 0x03; // DDRLD[1:0]=1 70 *pldpar &= 0xFC; // PLDPAR[1:0]=0 80 }
こういったポインタ変数を準備しておくと、メモリ空間への読み書きが簡単にできます。 プロフラムを実行すると、 PLD[0] と PLD[1] に "0" が出力されて、二つの LED が点灯するはずです。
光れ!
プログラムを実行すると、LED3は点灯しますが、LED2は何回か点滅したあと、消えてしまいます。 どうやら、オペレーティング・システムが何らかの操作をしているようです。 確認するために、プログラムを以下のように変更して、初期状態の SilentC の PLDPAR レジスタの内容を表示させました。
10 main(){ 20 char *portld = 0x40100015; // PORTLD 30 char *ddrld = 0x4010002D; // DDRLD 40 char *pldpar = 0x40100075; // PLDPAR 50 PrHex(*pldpar); 60 PrStr("\r\n"); 70 *portld &= 0xFC; // PORTLD[1:0]=0 80 *ddrld |= 0x03; // DDRLD[1:0]=1 90 *pldpar &= 0xFC; // PLDPAR[1:0]=0 100 }
すると、 telnet 画面には "00000002"と表示されました。 つまり、 LNKLED (LED3) は、 ETHER ポートの状態を自動的に示しているのに対して、 ACTLED (LED2) は、汎用出力として使用されており、オペレーティング・システムで操作しているようです。
ピカピカ・プログラム
それでは、いよいよLEDをピカピカさせます。 ピカピカの周期は、明らかに点滅として認識できる2Hzとします。 そのため、点灯と消灯のそれぞれの時間を250m秒に設定します。 時間待ちには、 SilentC の Sleep(int time) 関数を使い、 telnet 画面から q を打つと停止するようにします。
10 main(){ 20 char *portld = 0x40100015; // PORTLD 30 char *ddrld = 0x4010002D; // DDRLD 40 char *pldpar = 0x40100075; // PLDPAR 50 *portld &= 0xFE; // PORTLD[0]=0 60 *portld |= 0x02; // PORTLD[1]=1 70 *ddrld |= 0x03; // DDRLD[1:0]=1 80 *pldpar &= 0xFC; // PLDPAR[1:0]=0 90 #stop 0 100 for(;;) { 110 if(Getc(0)=='q')break; 120 Sleep(25); // wait for 250msec 130 *portld ^= 0x03; // toggle LED 140 } 150 }
「#stop 0」という記述は、何だか良くわからないのですが、 Getc(char wait) 関数で待ち時間を 0 にしたときに必要だと本誌に書いてありました。
実行すると、点滅が始まります。 プログラムは、ポート出力を反転しているだけです。 そのため、 telnet 画面から q 以外のキーを打つと、 ACTLED の状態が変化して、タイミングによって「同時点滅」になったり「かわりべんたん点滅」になったりします。
参考文献
MCF52233 付録基板は、これについてきます。
Interface (インターフェース) 2008年 09月号 [雑誌]
- 作者:
- 出版社/メーカー: CQ出版
- 発売日: 2008/07/25
- メディア: 雑誌
わぁ、ぺ、ページ間違ったかとおもっちゃましたよー(笑)
by たけまろ (2008-08-04 22:56)
すいません、たけまろさん原案のプログラムを勝手に使わせていただきました。
# 髪のお手入れ方法がわからず、はね返ったまんまです。
# f/t さんに教えてもらおう。
by noritan (2008-08-04 23:15)
なぜ、さあらたんがここに???。
by hamayan (2008-08-05 03:57)
私もどこかで人形手に入れようかな。
つい先日までウルトラマンがあったのに。
by DAI (2008-08-05 21:12)
しくしく、うちには、フリスク犬人形しかないー><
って、みなさん人形に反応しすぎ?
by Sim (2008-08-05 22:42)
これは? リカちゃん・・・ともちょっと違う?
by k_t (2008-08-06 19:16)
見事に誰も本文に突っ込まないのは、ナゼだぁ!?!?!
by noritan (2008-08-06 19:44)
それは追試していないから。ゴメンなさい。ゴメンなさい。
# ワタシは CGI で LED チカチカしてみようかしらん。
by masato (2008-08-06 20:43)