2013年11月10日日曜日

Atmega8-16PUでマトリクスLEDのダイナミック制御

前回確認したマトリクスLEDをAtmega8-16PUでダイナミック制御してみた。

単純なパターンを一定間隔で反転するだけ。



回路はAtmega8-16PUの16ポートにマトリクスLEDを直結しただけ。

一応アノードに100Ωの抵抗かましてある。

当初はシフトレジスタとデコーダ使おうかと思ってたけどAtmega8の出力ポート数足りてたので直結してみた。

割り込みとか入力とかする場合はシフトレジスタが必要になるかも。

プログラムについては、ポートに対応したビット操作だけなんで簡単だろうと思ってたけど以外と手間取った。

特定のビットだけ書き換えたりとか。いや基本なんだろうけど。普段ビット操作なんかしないから。
あとは行表示の前に一度LEDオフにしとくとか、ディレイの入れ方とか。

それとプログラムのバイナリが650バイトで転送に180秒かかる。
ちょっと直しては転送を繰り返すと結構待ち時間がガガガ。

今時のフラッシュメモリデバイスと比べると桁違いに遅い。のはデバイスなのか、ドライバというか転送プロトコルのせいなのか。まあいいや。

作成したプログラム
----
/*
atmega8 16pu
matrix led(1088bgy) controller
ISP
PC6 RESET
PB5 SCK
PB4 MISO
PB3 MOSI
USART
PD0 RXD
PD1 TXD
LED
ROW PC0,PC1,PC2,PC3,PC4,PC5,PB0,PB1
COL PB6,PB7,PD2,PD3,PD4,PD5,PD6,PD7
*/
#include <avr/io.h>
#include <util/delay.h>
/* DDRC |= (1 << PC0); */
#define DSET(p,n) (DDR##p|=(1<<P##p##n))
/* PORTC |= (1 << PC0); */
#define PSET(p,n,d) \
if ((d)) { \
(PORT##p|=(1<<P##p##n));\
} else { \
(PORT##p&=~(1<<P##p##n));\
}
unsigned char matrix[8] = {
0b11111111,
0b10000001,
0b10111101,
0b10100101,
0b10100101,
0b10111101,
0b10000001,
0b11111111
};
void
init_port()
{
// port c output setting
DSET(C,0);
DSET(C,1);
DSET(C,2);
DSET(C,3);
DSET(C,4);
DSET(C,5);
// port b output setting
DSET(B,0);
DSET(B,1);
DSET(B,6);
DSET(B,7);
// port d output setting
DSET(D,2);
DSET(D,3);
DSET(D,4);
DSET(D,5);
DSET(D,6);
DSET(D,7);
}
void
row(int i,int d)
{
switch(i) {
case 0:PSET(C,0,d);break;
case 1:PSET(C,1,d);break;
case 2:PSET(C,2,d);break;
case 3:PSET(C,3,d);break;
case 4:PSET(C,4,d);break;
case 5:PSET(C,5,d);break;
case 6:PSET(B,0,d);break;
case 7:PSET(B,1,d);break;
}
}
void
col(int i,int d)
{
switch(i) {
case 0:PSET(B,6,d);break;
case 1:PSET(B,7,d);break;
case 2:PSET(D,2,d);break;
case 3:PSET(D,3,d);break;
case 4:PSET(D,4,d);break;
case 5:PSET(D,5,d);break;
case 6:PSET(D,6,d);break;
case 7:PSET(D,7,d);break;
}
}
void
allcut()
{
// col
PSET(B,6,0);
PSET(B,7,0);
PSET(D,2,0);
PSET(D,3,0);
PSET(D,4,0);
PSET(D,5,0);
PSET(D,6,0);
PSET(D,7,0);
// row
PSET(C,0,1);
PSET(C,1,1);
PSET(C,2,1);
PSET(C,3,1);
PSET(C,4,1);
PSET(C,5,1);
PSET(B,0,1);
PSET(B,1,1);
}
#define DELAY 1
#define INTERVAL 300
int
main(void)
{
int i,j,k,elaps;
init_port();
k = 0;
elaps = 0;
while (1) {
if (elaps > INTERVAL) {
k += 1;
elaps = 0;
}
for(i=0;i<8;i++) {
allcut();
for(j=0;j<8;j++) {
col(j,((matrix[i]&1<<j)>>j)^(k&1));
if (i==j) {
row(j,0);
}
}
_delay_ms(DELAY);
elaps += DELAY;
}
}
return 0;
}
view raw matrix.c hosted with ❤ by GitHub
----


0 件のコメント:

amazonアソシエイト