
『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 }
このように表示されます。
くるくる回って、だんだんと早くなり、(写真だと全部光っているように見えます)
最後にこうなります。

コメント