- マトリクスLEDのアノードを74HC138Nの出力に接続(行)
- マトリクスLEDのカソードを74HC595の出力に接続(列)
- 74HC595を連結(1個目のQ7Sを2個目のDSに接続)
- 74HC138N、74HC595ともに入力はジャンパーピンでHL切り替え
- 74HC595のクロックはスライドスイッチで行う
- いわば手動ダイナミック制御
- 簡単な回路なのに手持ちのジャンパーピン全部使用
- とくにマトリクスLEDの下部に配線するのに腐心した
- 次はAtmega8で制御予定
動作風景
/* | |
atmega8 16pu | |
ISP | |
PC6 RESET | |
PB5 SCK | |
PB4 MISO | |
PB3 MOSI | |
ADC PC0 ADC0 | |
*/ | |
#define F_CPU 1000000UL // Clock Speed | |
#include <avr/io.h> | |
#include <avr/interrupt.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));\ | |
} | |
volatile unsigned char v; | |
int | |
main(void) | |
{ | |
unsigned char j; | |
// port c output setting | |
DSET(B,0); | |
DSET(B,1); | |
DSET(B,6); | |
DSET(B,7); | |
DSET(D,4); | |
DSET(D,5); | |
DSET(D,6); | |
DSET(D,7); | |
ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<ADLAR); | |
// ck/8 | |
ADCSRA = (1<<ADEN) | (0<<ADSC) | (1<<ADFR) | (1<<ADIE) | | |
(1<<ADPS2)| (1<<ADPS1)| (1<<ADPS0); | |
ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADFR) | (1<<ADIE) | | |
(0<<ADPS2)| (1<<ADPS1)| (1<<ADPS0); | |
sei(); | |
v = 0; | |
while (1) { | |
j = 0; | |
PSET(B,0,(v&(1<<j))>>j);j++; | |
PSET(B,1,(v&(1<<j))>>j);j++; | |
PSET(B,6,(v&(1<<j))>>j);j++; | |
PSET(B,7,(v&(1<<j))>>j);j++; | |
PSET(D,4,(v&(1<<j))>>j);j++; | |
PSET(D,5,(v&(1<<j))>>j);j++; | |
PSET(D,6,(v&(1<<j))>>j);j++; | |
PSET(D,7,(v&(1<<j))>>j);j++; | |
_delay_ms(10); | |
} | |
return 0; | |
} | |
ISR(ADC_vect) | |
{ | |
v = ADCH; | |
} |
![]() |
1日グラフ |
![]() |
1週間グラフ |
![]() |
http://www.jma.go.jpより |
/* | |
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 | |
*/ | |
#define F_CPU 1000000UL // Clock Speed | |
#define BAUD 9600 | |
#define MYUBRR (((F_CPU / (BAUD * 16UL))) - 1) | |
#include <avr/io.h> | |
#include <avr/interrupt.h> | |
#include <util/delay.h> | |
#include <stdio.h> | |
#include <stdlib.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));\ | |
} | |
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 500 | |
#define PERIOD 60000000 /* 60sec */ | |
#define INTERVAL 500000 /* 500ms */ | |
void | |
life(void) | |
{ | |
int i,j,k,a,b,live; | |
unsigned long t1,t2; | |
unsigned char m[2][8]; | |
allcut(); | |
t1 = t2 = k = a = 0; | |
for(i=0;i<8;i++) { | |
m[0][i] = 0x0; | |
m[1][i] = 0x0; | |
for(j=0;j<8;j++) { | |
if (rand()%2==0) { | |
m[0][i]|=(1<<j); | |
m[1][i]|=(1<<j); | |
} | |
} | |
} | |
while (t1 < PERIOD) { | |
if (t2 > INTERVAL) { | |
t2 = 0; | |
k++; | |
a = k % 2; | |
b = (k+1) % 2; | |
for(i=0;i<8;i++) { | |
for(j=0;j<8;j++) { | |
live = 0; | |
/*up left*/ | |
if ((m[b][(i+7)%8]&1<<(j+7)%8)) { | |
live++; | |
} | |
/*up*/ | |
if ((m[b][(i+7)%8]&1<<j)) { | |
live++; | |
} | |
/*up right*/ | |
if ((m[b][(i+7)%8]&1<<(j+1)%8)) { | |
live++; | |
} | |
/*left*/ | |
if ((m[b][i]&1<<(j+7)%8)) { | |
live++; | |
} | |
/*right*/ | |
if ((m[b][i]&1<<(j+1)%8)) { | |
live++; | |
} | |
/*down left*/ | |
if ((m[b][(i+1)%8]&1<<(j+7)%8)) { | |
live++; | |
} | |
/*down*/ | |
if ((m[b][(i+1)%8]&1<<j)) { | |
live++; | |
} | |
/*down right*/ | |
if ((m[b][(i+1)%8]&1<<(j+1)%8)) { | |
live++; | |
} | |
if (m[b][i]&1<<j) { | |
/*die*/ | |
if (live<=1 || live>=4) { | |
m[a][i]&=~(1<<j); | |
} else { | |
m[a][i]|=(1<<j); | |
} | |
} else { | |
/*born*/ | |
if (live==3) { | |
m[a][i]|=(1<<j); | |
} else { | |
m[a][i]&=~(1<<j); | |
} | |
} | |
} | |
} | |
} | |
for(i=0;i<8;i++) { | |
allcut(); | |
for(j=0;j<8;j++) { | |
col(j,(m[a][i]&1<<j)>>j); | |
if (i==j) { | |
row(j,0); | |
} | |
} | |
_delay_us(DELAY); | |
t1 += DELAY; | |
t2 += DELAY; | |
} | |
} | |
} | |
int | |
main(void) | |
{ | |
init_port(); | |
while (1) { | |
life(); | |
} | |
return 0; | |
} |
![]() |
左がUSB-UART変換モジュール、中央にマトリクスLED、右にAtmega8、上部にISPコネクタ |
![]() |
基板ウラ面 |