AVRマイコンのポートで7セグLEDを表示する(ATtiny2313)

7seg-twenty-four-title
『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 

ブレッドボードを使って配線したら以下のようになりました。
7seg-twenty-four-001

以下にソースを貼ってあります。
変わったところといえば、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	}

このように表示されます。
7seg-twenty-four-002
くるくる回って、だんだんと早くなり、(写真だと全部光っているように見えます)
最後にこうなります。
7seg-twenty-four-003

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA