두 번째 LED실험도 앞의 실험과 비슷하다. 이번에는 다음과 같은 순서로 1→2→3→4→1→2→3→4→1→… 계속 시차를 두고 반복하는 실험이다.
[표 1] 두 번째 LED 실험
순서
|
LED상태
|
이진수
|
16진수
|
1
|
●●●○○●●●
|
0b00011000
|
0x18
|
2
|
●●○●●○●●
|
0b00100100
|
0x24
|
3
|
●○●●●●○●
|
0b01000010
|
0x42
|
4
|
○●●●●●●○
|
0b10000001
|
0x81
|
프로그램 예는 다음과 같다.
#define F_CPU 16000000#include <avr/io.h>#include <util/delay.h>#include "Am8USBasp.h"int main(void) {uchar ucA, ucaRelay[4] = {0x18, 0x24, 0x42, 0x81};InitAM8();while(1) {for (ucA=0; ucA<4; ucA++) {LED(ucaRelay[ucA]);_delay_ms(200);}}} |
이 예를 보면 typedef 명령어로 unsigned char형은 byte형으로 재정의하였으며 앞으로도 이것은 계속 사용할 것이다. 그리고 LED로 순차적으로 내보낼 데이터는 배열로 처리하였음을 눈여겨 보기 바란다.
LED실험 3
다음 [표 2]에 설명한 바와 같이 1→2→ … →13→14→1→2→ … 의 순서로 14가지 패턴을 반복하면 마치 LED한개가 좌우로 왕복하는 듯이 보이는 예제이다. 이 세 번째 LED실험은 앞의 것들과 달리 조금 복잡해 보인다.
[표 2] 세 번째 LED 실험
순서
|
LED상태
|
이진수
|
16진수
|
1
|
●●●●●●●○
|
0b00000001
|
0x01
|
2
|
●●●●●●○●
|
0b00000010
|
0x02
|
3
|
●●●●●○●●
|
0b00000100
|
0x04
|
4
|
●●●●○●●●
|
0b00001000
|
0x08
|
5
|
●●●○●●●●
|
0b00010000
|
0x10
|
6
|
●●○●●●●●
|
0b00100000
|
0x20
|
7
|
●○●●●●●●
|
0b01000000
|
0x40
|
8
|
○●●●●●●●
|
0b10000000
|
0x80
|
9
|
●○●●●●●●
|
0b01000000
|
0x40
|
10
|
●●○●●●●●
|
0b00100000
|
0x20
|
11
|
●●●○●●●●
|
0b00010000
|
0x10
|
12
|
●●●●○●●●
|
0b00001000
|
0x08
|
13
|
●●●●●○●●
|
0b00000100
|
0x04
|
14
|
●●●●●●○●
|
0b00000010
|
0x02
|
이번 프로그램을 이전 실험과 같이 14개의 데이터를 포트에 순차적으로 내보내는 식으로 프로그램을 작성할 수도 있으나 그렇게 하면 너무 비효율적인 프로그램이 된다. 그래서 비트이동 연산자와 반복문을 이용하면 좀 더 간단하게 프로그램이 가능하다. 프로그램 예는 다음과 같다.
#define F_CPU 16000000#include <avr/io.h>#include <util/delay.h>#include "Am8USBasp.h"typedef enum DIR {UP, DOWN} EDIR;int main(void) {uchar ucLed = 1;EDIR eDir = UP;InitAM8();while(1) {if (eDir == UP) {ucLed <<= 1;if (ucLed == 0x80)eDir = DOWN;} else { // if (eDir == DOWN)ucLed >>= 1;if (ucLed == 0x01)eDir = UP;}LED(ucLed);_delay_ms(200);}} |
LED실험 4 : LED탑 쌓기
마지막으로 아래와 같은 패턴을 보여주는 프로그램을 작성해보자. 벽돌로 하나씩 탑을 쌓는 것처럼 보여서 ‘LED 탑 쌓기’실험이라고 이름을 붙여 보았다.
[표 3] 네 번째 LED 실험
순서
|
LED상태
|
이진수
|
16진수
|
1
|
○●●●●●●●
|
0b01111111
|
0x7F
|
2
|
●○●●●●●●
|
0b10111111
|
0xBF
|
3
|
●●○●●●●●
|
0b11011111
|
0xDF
|
4
|
●●●○●●●●
|
0b11101111
|
0xEF
|
5
|
●●●●○●●●
|
0b11110111
|
0xF7
|
6
|
●●●●●○●●
|
0b11111101
|
0xFB
|
7
|
●●●●●●○●
|
0b11111110
|
0xFD
|
8
|
●●●●●●●○
|
0b11111110
|
0xFE
|
9
|
○●●●●●●○
|
0b01111111
| |
10
|
●○●●●●●○
|
0b10111111
| |
11
|
●●○●●●●○
|
0b11011111
| |
12
|
●●●○●●●○
|
0b11101111
| |
13
|
●●●●○●●○
|
0b11110111
| |
14
|
●●●●●○●○
|
0b11111101
| |
15
|
●●●●●●○○
|
0b11111110
| |
16
|
○●●●●●○○
|
0b01111111
| |
17
|
●○●●●●○○
|
0b10111111
| |
18
|
●●○●●●○○
|
0b11011111
| |
19
|
●●●○●●○○
|
0b11101111
| |
20
|
●●●●○●○○
|
0b11110111
| |
21
|
●●●●●○○○
|
0b11111101
| |
22
|
○●●●●○○○
|
0b11111110
| |
⋮
|
⋮
|
⋮
|
이 실험은 이제 포트에 데이터를 순차적으로 내보내는 식으로는 프로그램이 거의 불가능하다. 이번에도 역시 비트이동연산자와 반복문을 조합하여 프로그램을 작성할 수 있다.
#define F_CPU 16000000#include <avr/io.h>#include <util/delay.h>#include "Am8USBasp.h"int main(void) {uchar ucaLEDTower[8] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };uchar ucled, uck, ucl;InitAM8();while (1) {for (uck=0;uck<8;uck++) {ucled = 0x80;for (ucl=0;ucl<8-uck;ucl++) {LED( ucled | ucaLEDTower[uck] );_delay_ms(200);ucled >>= 1;}}}} |
위 프로그램은 길이는 짧지만 한 줄씩 읽어가면서 분석해 볼 여지가 있다. 다중 반복문을 사용하고 있는데 내부 반복문에서는 LED가 위에서 아래로 한 칸씩 떨어지는 것을 비트쉬프트 연산자로 처리하고 있으며 이 때 PORTB로 내보내는 데이터를 배열 byaLEDTower[]과 OR연산을 하여 마치 벽돌이 쌓여 있는 듯한 효과를 내는 것이다. 배열 byaLEDTower[]은 벽돌이 쌓인 모양의 데이터를 가지고 있다. 바깥 반복문에서는 떨어지는 루틴을 8번 반복하게끔 하는데 떨어지는 곳의 높이를 점차로 높인다.
이번 포스트에서는 LED를 이용하여 간단한 예제들을 살펴보았다. 독자가 C언어의 문법을 잘 숙지하고 있다면 어떻게 동작이 되는지 쉽게 분석해 볼 수 있을 것이다.
댓글 없음:
댓글 쓰기