임베디드 마이크로프로세서 프로그래밍 실전 제작 : 네 로 테 크 강의 : 김 종 형
Embedded AVR Programming
ATMEGA128의 실전Ⅰ
1. 2. 3.
20062006-0404-07
-2-
Dotmatrix 구동원리 Heart 실습 Bitman 실습
Embedded AVR Programming
1-1 Dotmatrix 구동 원리 ⊙ LED를 매트릭스(행렬)의 형태로 나열한 것 - 5×7, 8×8, 16×16 등의 매트릭스로 이루어진 것 ⊙ 칼라 수에 따라 싱글(single, 단색)또는 멀티(multi, 다색) ⊙ LED를 사용한 디스플레이 장치는 고휘도에 수명이 길다는 장점 ⊙ 도트 매트릭스를 구동시키는 방법 - 스태틱구동(static drive) : 시프트 레지스터의 비트를 LED 갯 수 만큼 준비하고 여기에 데이터를 보내어 점등하는 방식으로 한 번에 모든 LED를 ON/OFF함 - 다이나믹구동(dynamic drive) : 스캔라인과 데이터라인으로 구성되어 스캔라인에 의해 각 행 또는 열을 1행씩 스캔하면서 데이터라인에 의해 동기된 데이터를 출력하는 방식 ⊙ 다이나믹 드라이브방식은 스태틱 드라이브에 비해 휘도가 낮고, 스캔주파수가 낮은 경우에 깜박거림이 일어난다는 점에서는 다소 떨어진다고 할 수 있으나 구동회로가 간단하기 때문에 저가격으로 대화면의 구성에 적합
20062006-0404-07
-3-
Embedded AVR Programming
1-2 Dotmatrix 구조
20062006-0404-07
-4-
Embedded AVR Programming
1-3 Dotmatrix 8*8 회로도 PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0
PB0
PB1
PB2
PB3
PB4
PB5
PB6
PB7
20062006-0404-07
COL8 COL7 COL6 COL5 COL4 COL3 COL2 COL1
ROW1
ROW2
ROW3
ROW4
ROW5
ROW6
ROW7
ROW8
LED1
LED2
LED3
LED4
LED5
LED6
LED7
LED8
Red
Red
Red
Red
Red
Red
Red
Red
LED9
LED10
LED11
LED12
LED13
LED14
LED15
LED16
Red
Red
Red
Red
Red
Red
Red
Red
LED17
LED18
LED19
LED20
LED21
LED22
LED23
LED24
Red
Red
Red
Red
Red
Red
Red
Red
LED25
LED26
LED27
LED28
LED29
LED30
LED31
LED32
Red
Red
Red
Red
Red
Red
Red
Red
LED33
LED34
LED35
LED36
LED37
LED38
LED39
LED40
Red
Red
Red
Red
Red
Red
Red
Red
LED41
LED42
LED43
LED44
LED45
LED46
LED47
LED48
Red
Red
Red
Red
Red
Red
Red
Red
LED49
LED50
LED51
LED52
LED53
LED54
LED55
LED56
Red
Red
Red
Red
Red
Red
Red
Red
LED57
LED58
LED59
LED60
LED61
LED62
LED63
LED64
Red
Red
Red
Red
Red
Red
Red
Red
-5-
Embedded AVR Programming
1-4 Heart 실습 1 ☞ 하트 모양을 아래로 쉬프트한 후 다시 원상태로 복귀하는 장면 등을 반복하는 프로그램 #include <mega128.h> #include <delay.h> typedef unsigned char u08; typedef unsigned int u16;
flash unsigned char M[1][25]={ {1,2,3,4,5,6,8,9,7,6,5,4,3,2,1,12,10,11,10,12,13,1,9,1,0} }; flash unsigned char P[14][8]={ {0x66,0xFF,0xFF,0xFF,0x7E,0x3C,0x18,0x00}, {0x66,0xFF,0xFF,0xFF,0x7E,0x3C,0x18,0x00}, {0x00,0x66,0xFF,0xFF,0xFF,0x7E,0x3C,0x18}, {0x00,0x00,0x66,0xFF,0xFF,0xFF,0x7E,0x3C}, {0x00,0x00,0x00,0x66,0xFF,0xFF,0xFF,0x7E},
unsigned char line=0; unsigned char patt=0; unsigned char mod=0, num_mod=0; unsigned char time=0;
{0x00,0x00,0x00,0x00,0x66,0xFF,0xFF,0xFF}, {0x00,0x00,0x00,0x00,0x00,0x66,0xFF,0xFF}, {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0xFF}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
unsigned char dir=0; //상하좌우방향결정으로 디스플레이 방향 선택 unsigned char temp_led, temp_line;
/* 배열 P는 각 동작들이 도트 매트릭스에 표시되는 데이터이고(하나하 나의 정지모습) 배열 M은 그 동작들을 순서대로 나열하여 하나의 움직임이 되도록 한 다. */
{0x66,0x99,0x81,0x81,0x42,0x24,0x18,0x00}, {0x00,0x66,0x99,0x81,0x81,0x42,0x24,0x18}, {0x66,0xFF,0xDB,0xC3,0x66,0x3C,0x18,0x00}, {0x66,0xFF,0xFF,0xE7,0x7E,0x3C,0x18,0x00} };
20062006-0404-07
-6-
Embedded AVR Programming
1-4 Heart 실습 2 ☞ 하트 모양을 아래로 쉬프트한 후 다시 원상태로 복귀하는 장면 등을 반복하는 프로그램 interrupt [TIM0_OVF] void timer0_int(void) { TCNT0 = 0xe3; // reload for 448us ticks(측정값 : 460us) switch (dir){ //dir에 따라 표시되는 방향을 결정한다. case 0: temp_led=1<<(7-line); temp_line=P[patt][line]; break; case 2: temp_led=P[patt][line]; temp_line=1<
20062006-0404-07
void main(void) { DDRB = 0xff; DDRC = 0xff; DDRD = 0xff; TCCR0 = 0x06; // clk/256 TCNT0 = 0xe3; TIMSK = 0x01; // enable TOIE0 #asm("sei") while(1) { if(M[mod][num_mod] == 0) { num_mod=0; } else{ patt= M[mod][num_mod]; num_mod++; } delay_ms(200); }; }
-7-
//움직임 상태 변경
Embedded AVR Programming
1-5 BITMAN 실습 1 ☞ BITMAN으로 사람의 움직임을 랜덤하게 표시하는 프로그램 #include <mega128.h> #include <delay.h> typedef unsigned char u08; typedef unsigned int u16;
/* 배열 P는 각 동작들이 도트 매트릭스에 표시되는 데이터이고(하나하나의 정지모습) 배열 M은 그 동작들을 순서대로 나열하여 하나의 움직임이 되도록 한다. */
#define DELAY 100
flash unsigned char M[6][25]={ {1,2,3,4,5,6,5,4,3,2,1,7,8,9,10,11,10,9,8,7,1,0,0,0,0}, {12,13,14,13,12,13,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {15,16,17,16,15,18,19,18,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {20,21,22,21,20,23,24,23,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {25,26,27,28,29,30,31,32,29,30,31,32,0,0,0,0,0,0,0,0,0,0,0,0,0},
unsigned char line=0; unsigned char patt=0; unsigned char mod=0, num_mod=0; unsigned char time=0; unsigned char delay=DELAY; unsigned unsigned unsigned unsigned
char dir=3; char temp_led, temp_line; char temp_dir; int dir_cnt=0;
unsigned char dir_chk_sw=0; unsigned char mov_chk_sw=1; //센서 감지 없으면 움직임 정지. unsigned char mov_chk_cnt=0; unsigned char name_sw=0;
20062006-0404-07
{33,34,35,36,37,38,39,40,37,38,39,40,41,42,41,42,0,0,0,0,0,0,0 ,0,0} }; flash unsigned char P[43][8]={ {0x18,0x18,0x3c,0x5a,0x5a,0x24,0x24,0x66}, {0x18,0x18,0x3C,0x5A,0x5A,0x24,0x24,0x66}, {0x18,0x18,0x3C,0xDA,0x1A,0x24,0x24,0x66}, {0x0C,0xCC,0x3C,0x1A,0x1A,0x24,0x26,0x62}, {0x8C,0x4C,0x3C,0x1A,0x1A,0x24,0x27,0x60},
-8-
Embedded AVR Programming
1-5 BITMAN 실습 2 ☞ BITMAN으로 사람의 움직임을 랜덤하게 표시하는 프로그램 {0x4C,0x4C,0x3C,0x1A,0x1A,0x24,0x27,0x60}, {0x2C,0x4C,0x3C,0x1A,0x1A,0x24,0x27,0x60}, {0x18,0x18,0x3C,0x5B,0x58,0x24,0x24,0x66}, {0x30,0x33,0x3C,0x58,0x58,0x24,0x24,0x66}, {0x31,0x32,0x3C,0x58,0x58,0x24,0xE4,0x06},
{0x18,0x18,0x3C,0x5A,0x5A,0x24,0x24,0x66}, {0x18,0x18,0x3E,0x59,0x58,0x24,0x26,0x60}, {0x0C,0x0C,0x18,0x3C,0x38,0x14,0x36,0x20}, {0x0C,0x0C,0x38,0x5E,0x58,0x14,0x74,0x46}, {0x0C,0x0C,0x38,0x3E,0x18,0x78,0x50,0x18},
{0x32,0x32,0x3C,0x58,0x58,0x24,0xE4,0x06}, {0x34,0x32,0x3C,0x58,0x58,0x24,0xE4,0x06}, {0x18,0x18,0x3C,0x5A,0x5A,0x24,0x24,0x66}, {0x00,0x18,0x7E,0x99,0x18,0x3C,0x24,0x66}, {0x00,0x00,0xDB,0x3C,0x18,0x3C,0x3C,0x66},
{0x00,0x0C,0x3C,0x58,0x5C,0x16,0x30,0x20}, {0x0C,0x0C,0x78,0x9E,0x1C,0x14,0x76,0x40}, {0x0C,0x0C,0x3F,0x58,0x18,0x34,0x24,0x06}, {0x18,0x18,0x3C,0x5A,0x5A,0x24,0x24,0x66}, {0x18,0x18,0x7C,0x9A,0x1A,0x24,0x64,0x06},
{0x18,0x18,0x3C,0x5A,0x5A,0x24,0x24,0x66}, {0x18,0x18,0x3C,0xDA,0x1A,0x24,0x64,0x06}, {0x30,0x30,0x9C,0x7A,0x19,0x24,0x64,0x06}, {0x18,0x18,0x3C,0x5B,0x58,0x24,0x26,0x60}, {0x0C,0x0C,0x39,0x5E,0x98,0x24,0x26,0x60},
{0x30,0x30,0x18,0x3C,0x1C,0x28,0x6C,0x04}, {0x30,0x30,0x1C,0x7A,0x1A,0x28,0x2E,0x62}, {0x30,0x30,0x7C,0x1A,0x18,0x16,0x12,0x30}, {0x30,0x30,0x1C,0x7C,0x18,0x1E,0x0A,0x18}, {0x00,0x30,0x3C,0x1A,0x3A,0x68,0x0C,0x04},
{0x18,0x18,0x3C,0x5A,0x5A,0x24,0x24,0x66}, {0x0C,0x0C,0x7C,0x9A,0x1A,0x24,0x26,0x60}, {0x00,0x06,0xFE,0x1C,0x1A,0x2A,0x28,0x6C}, {0x30,0x30,0x3E,0x59,0x58,0x24,0x64,0x06}, {0x00,0x60,0x7F,0x38,0x58,0x54,0x14,0x36},
{0x30,0x30,0x1E,0x79,0x38,0x28,0x6E,0x02}, {0x30,0x30,0xFC,0x1A,0x18,0x2C,0x24,0x60}, {0x30,0x30,0x3E,0x58,0x1C,0x24,0x26,0x60}
20062006-0404-07
};
-9-
Embedded AVR Programming
1-5 BITMAN 실습 3 ☞ BITMAN으로 사람의 움직임을 랜덤하게 표시하는 프로그램 interrupt [TIM0_OVF] void timer0_int(void) { TCNT0 = 0xe3; // reload for 448us ticks(측정값 : 460us) switch (dir){ //dir에 따라 표시되는 방향을 결정한다. case 0: temp_led=1<<(7-line); temp_line=P[patt][line]; break; case 2: temp_led=P[patt][line]; temp_line=1<
interrupt [TIM2_OVF] void timer2_ovf_isr(void) //움직임을 바꾸기 위한 타이머 사용(랜덤함수와 유사) { TCNT2 = 0xdf; // reload for 2.048ms ticks(측정값 : 2.12ms) time++; if(mov_chk_sw==1 && time >= delay ) //(측정값 : 214ms) { time=0; if(M[mod][num_mod] == 0) { mod= TCNT0%6; num_mod=0; mov_chk_cnt++; if(mov_chk_cnt == 10) { mov_chk_sw=0; mov_chk_cnt=0; } } else { patt= M[mod][num_mod]; num_mod++; if(delay<= DELAY) delay++; }
PORTB = ~temp_line; PORTC = temp_led; //빨강색 출력 if(line==7) line=0; else line++; }
} }
20062006-0404-07
//움직임 종류 변경
-1010-
//움직임 상태 변경
Embedded AVR Programming
1-5 BITMAN 실습 4 ☞ BITMAN으로 사람의 움직임을 랜덤하게 표시하는 프로그램 void main(void) { DDRA = 0x00; PORTA = 0xff; DDRB = 0xff; DDRC = 0xff; DDRD = 0xff;
TCCR0 = 0x06; // clk/256 TCCR2 = 0x05; // clk/1024 TCNT0 = 0xe3; TCNT2 = 0x00; TIMSK = 0x41; // enable TOIE2, TOIE0 #asm("sei") while(1) { }; }
20062006-0404-07
-1111-