『24 -TWENTY FOUR-』
ジャックバウアーに夢中になりました。私的に一番面白かったのはシーズン1です。仕事をやっていると、一時間なんてあっという間に過ぎてしまいますが、ジャックバウアーの時間の使い方って上手いですよね。24時間でたいていのことは解決しますからね。
電子工作を始めたら、いつか7セグLEDで『24 -TWENTY FOUR-』のオープニングを作ってみようと思っていましたが、意外と簡単でした。まあそっくりそのままではなく、なんちゃって、です。音もないし。
A-3880EGの時と同じく、AVRのポートをふんだんに使っています。もったいないですねえ。
各ピン配はこのとおりです。
ATtiny2313 +-----------+ -|1 20|- VCC II-5 <--- PD0 -|2 19|- PB7 ---> II-6 II-4 <--- PD1 -|3 18|- PB6 ---> II-7 II-2 <--- PA1 -|4 17|- PB5 ---> II-9 II-1 <--- PA0 -|5 16|- PB4 ---> II-10 I-5 <--- PD2 -|6 15|- PB3 ---> I-6 I-4 <--- PD3 -|7 14|- PB2 ---> I-7 I-2 <--- PD4 -|8 13|- PB1 ---> I-9 I-1 <--- PD5 -|9 12|- PB0 ---> I-10 GND -|10 11|- +-----------+ 7SEG(Cathode common) 7SEG(Cathode common) (I) (II) 10 9 8 7 6 10 9 8 7 6 | | | | | | | | | | +-------------+ +-------------+ |G F cmn A B| |G F cmn A B| | | | | | +---A---+ | | +---A---+ | | | | | | | | | | F B | | F B | | | | | | | | | | +---G---+ | | +---G---+ | | | | | | | | | | E C | | E C | | | | | | | | | | +---D---+ | | +---D---+ | | DP | | DP | | | | | |E D cmn C DP| |E D cmn C DP| +-------------+ +-------------+ | | | | | | | | | | 1 2 3 4 5 1 2 3 4 5
ブレッドボードを使って配線したら以下のようになりました。
以下にソースを貼ってあります。
変わったところといえば、4行目からの文字列でしょうか。7セグLEDのピン配置と合わせるために、エスケープシーケンスを使っています。
数字の1の表示なら、ピン番号4と6なので、”\x4\x6″としています。
で、これを使うのが、61行目の
p = digit[num / 10];
なんですが、
while(pin=*p++)
で回して、文字列の最後、つまりNULLを見つけたら抜けるようになっています。
ただ、エスケープシーケンスは見難いので、
“46”
としておいて、
while(pin=*p++ – ‘0’)
としても良いかもしれません。
全文です。
~$ cat -n hello.c 1 #include <avr/io.h> 2 #include <util/delay.h> 3 4 char *digit[] ={ 5 /* 0 */ "\x7\x6\x4\x2\x1\x9", 6 /* 1 */ "\x4\x6", 7 /* 2 */ "\x7\x6\xA\x1\x2", 8 /* 3 */ "\x7\x6\xA\x4\x2", 9 /* 4 */ "\x9\xA\x6\x4", 10 /* 5 */ "\x9\xA\x7\x4\x2", 11 /* 6 */ "\x7\x9\xA\x4\x2\x1", 12 /* 7 */ "\x7\x9\x6\x4", 13 /* 8 */ "\x7\x6\x4\x2\x1\x9\xA", 14 /* 9 */ "\xA\x7\x9\x6\x4", 15 }; 16 17 void anode(int sel, int pin) 18 { 19 switch(sel){ 20 case 1: // 7SEG (I) 21 switch(pin){ 22 case 1: PORTD |= 0b00100000;break; 23 case 2: PORTD |= 0b00010000;break; 24 case 4: PORTD |= 0b00001000;break; 25 case 5: PORTD |= 0b00000100;break; 26 case 6: PORTB |= 0b00001000;break; 27 case 7: PORTB |= 0b00000100;break; 28 case 9: PORTB |= 0b00000010;break; 29 default: PORTB |= 0b00000001;break; 30 } 31 break; 32 case 2: // 7SEG (II) 33 switch(pin){ 34 case 1: PORTA |= 0b00000001;break; 35 case 2: PORTA |= 0b00000010;break; 36 case 4: PORTD |= 0b00000010;break; 37 case 5: PORTD |= 0b00000001;break; 38 case 6: PORTB |= 0b10000000;break; 39 case 7: PORTB |= 0b01000000;break; 40 case 9: PORTB |= 0b00100000;break; 41 default: PORTB |= 0b00010000;break; 42 } 43 break; 44 } 45 } 46 47 void clear() 48 { 49 PORTB &= ~0b11111111; 50 PORTD &= ~0b00111111; 51 PORTA &= ~0b00000011; 52 } 53 54 void disp(int num) 55 { 56 int pin; 57 char* p; 58 59 clear(); 60 61 p = digit[num / 10]; 62 while(pin=*p++) 63 anode(1,pin); 64 65 p = digit[num % 10]; 66 while(pin=*p++) 67 anode(2,pin); 68 } 69 70 int main() 71 { 72 DDRB = 0b11111111; //ATtiny2313 pin.12-19 PB0-7 OUT 73 DDRD = 0b00111111; //ATtiny2313 pin.2,3,6-9 PD0-5 OUT 74 DDRA = 0b00111111; //ATtiny2313 pin.4,5 PA0-1 OUT 75 76 //twenty-four logic 77 { 78 int i,j,wait,sel,pin; 79 80 for(i=0;i<30;i+=5){ 81 for(j=0;j<5;j++){ 82 for(sel=1;sel<=2;sel++){ 83 for(pin=1;pin<=9;pin++){ 84 clear(); 85 anode(sel,pin); 86 for(wait=1;wait<=(29-i);wait++){ 87 _delay_ms(1); 88 } 89 } 90 } 91 } 92 } 93 } 94 95 disp(24); 96 97 while(1) 98 ; 99 100 return 0; 101 }
このように表示されます。
くるくる回って、だんだんと早くなり、(写真だと全部光っているように見えます)
最後にこうなります。
コメント