プロが教えるわが家の防犯対策術!

LEDマトリクスについて質問です。

今LEDマトリクスを制御しようとしているのですが、プログラムの方法がいまちよく分かりません。
LEDマトリクスはアノードコモン、アノード側の制御はPNPトランジスタ、
カソード側の制御はNPNトランジスタで行っています。
なので、自分は1行目(アノード)1列目(カソード)のLEDを表示させるために1行目
(PNPトランジスタ)に0を、1列目(NPNトランジスタ)に1を出力しているのですが点灯してくれません。
アノード側のPNPトランジスタに接続しているのはポートAで、カソード側NPNトランジスタに接続しているのはポートBです。
以下にソースコードを示すので、間違いの指摘のことよろしくお願いします。

void wait(long wait) /* 時間を指定できる時間稼ぎ関数 */
{
while(wait--);
}
int main(void) /* 実際に表示をする関数 */
{
PADDR = 0xff; /* ポートA全ビット入力 */
PAPCR = 0xff;
PBDDR = 0xff; /* ポートB全ビット出力 */
int i;
for(;;) {
for(i = 0;i <= 8;i++) { /* 1列目の表示 */
PADR = 0x01 ;
PBDR = 0x01 << i;
wait(50000);
PBDR = 0;
}
PADR = 0;
wait(1000);
for(i = 8;i >= 0;i--) { /* 2列目の表示 */
PADR = 0x01 << 1;
PBDR = 0x01 << i;
wait(50000);
PBDR = 0;
}
PADR = 0;
wait(1000);
for(i = 0;i <= 8;i++) { /* 3列目の表示 */
PADR = 0x01 << 2;
PBDR = 0x01 << i;
wait(50000);
PBDR = 0;
}
PADR = 0;
wait(1000);
for(i = 8;i >= 0;i--) { /* 4列目の表示 */
PADR = 0x01 << 3;
PBDR = 0x01 << i;
wait(50000);
PBDR = 0;
}
PADR = 0;
wait(1000);
for(i = 0;i <= 8;i++) { /* 5列目の表示 */
PADR = 0x01 << 4;
PBDR = 0x01 << i;
wait(50000);
PBDR = 0;
}
PADR = 0;
wait(1000);
for(i = 8;i >= 0;i--) { /* 6列目の表示 */
PADR = 0x01 << 5;
PBDR = 0x01 << i;
wait(50000);
PBDR = 0;
}
PADR = 0;
wait(1000);
for(i = 0;i <= 8;i++) { /* 7列目の表示 */
PADR = 0x01 << 6;
PBDR = 0x01 << i;
wait(50000);
PBDR = 0;
}
PADR = 0;
wait(1000);
for(i = 8;i >= 0;i--) { /* 8列目の表示 */
PADR = 0x01 << 7;
PBDR = 0x01 << i;
wait(50000);
PBDR = 0;
}
PADR = 0;
wait(1000);
}
}

A 回答 (1件)

マトリックスLEDには「アノードコモン」などという概念はありません。


アノードもカソードもどちらも共通配線が入っているのが「マトリックス」ですから。

(前回の質問からすると、「2色LEDなマトリックスで、2色のアノードがコモンになっている」のだと思いますが、
今回のプログラムでは、その接続がどうなっているか書かれていません。
8x8の2色LEDマトリックスなら、8bit×3ポート必要になりますが、今回のプログラムでは2ポートしか制御していないようですし)

それと、PADR と PBDR のどちらがアノードでどちらがカソードなのかもわかりません。
(コード的にも「1行目(PNPトランジスタ)に0を、」に該当するコードがありません。2つのポートのどちらも、1ビットだけ1に出力してますし。)

といった質問の不明点があるので、まともに答えようがないというか、
さらに、使用しているマイコンが何かわからないので、以下の文章は多分に推測が入っています。

> PADDR = 0xff; /* ポートA全ビット入力 */

入力とコメントに書かれていますが、それでいいのでしょうか?

あと、まずはダイナミック点灯ではなくスタティック点灯で、
LEDがハードウェア的に正しく接続されているかどうかを確認する方がいいかと。

もし、PADRがアノード側PNPトランジスタ、PBDRがカソード側NPNトランジスタに繋がっているのなら、

---
PADR = 0x00;
PBDR = 0xFF;
for (;;) ;
---

で、全てのLEDが点灯するはずです。(PADRがカソード、PBDRがアノードなら、PADR/PBDRを入れ替えてください。以下同じ)

これでLEDが点灯しないのなら、ダイナミック点灯以前の問題です。
ハードウェア回りか、ソフト側のポートの初期化回りか、どちらかの問題だと思いますが、
エミュレータでポートの入出力を確認するとか、テスタでポートの出力電圧を確認するとかして
まずLEDをスタティック点灯できるようにしてください。

これでLEDが点灯したなら、次にダイナミック点灯ですが、
まずは簡単な例で、市松模様を表示させてみると、
おそらく
---
for(;;) {
PADR=~(0x01 << 0); PBDR=0xaa; wait(50000);// 1列目に「○●○●○●○●」表示
PADR=~(0x01 << 1); PBDR=0x55; wait(50000);// 2列目に「●○●○●○●○」表示
PADR=~(0x01 << 2); PBDR=0xaa; wait(50000);// 3列目に「○●○●○●○●」表示
PADR=~(0x01 << 3); PBDR=0x55; wait(50000);// 4列目に「●○●○●○●○」表示
PADR=~(0x01 << 4); PBDR=0xaa; wait(50000);// 5列目に「○●○●○●○●」表示
PADR=~(0x01 << 5); PBDR=0x55; wait(50000);// 6列目に「●○●○●○●○」表示
PADR=~(0x01 << 6); PBDR=0xaa; wait(50000);// 7列目に「○●○●○●○●」表示
PADR=~(0x01 << 7); PBDR=0x55; wait(50000);// 8列目に「●○●○●○●○」表示
}
---
こんな感じになるはずです。基本的に「8回の操作」の繰り返しになります。
2重ループにして64回のポート出力があるというのは間違えています。

(PADRがカソード、PBDRがアノードなら、PADR/PBDRを入れ替えてください)
    • good
    • 0
この回答へのお礼

もうボロボロですね…
今度はもうちょっとじっくりと作っていきたいと思います。
あの後判明したのですが、PNPトランジスタが悪かったようです。

細かいご指摘ありがとうございます、これを参考に今後も頑張ります!
(またお世話になるかもしれません…)

お礼日時:2010/06/08 06:03

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!