8051
AVR
EZLab
PIC
80C196KC
DSP
ARM
VHDL
마이크로마우스
로봇축구
Battle 로봇
로봇대회
휴먼로봇
Embeded Linux
HW/SW 강좌
RTOS
 
 

2. LED 깜박이기

 

   저번 강좌에서는 개발환경을 구축했다. 이제 구슬은 준비되었고, 이제부터는 구슬을 하나씩 꿰어 보기로 하자. 오늘 다룰 주제는 8개의 LED를 순차적으로 반복해서 켜는 실험이다. 먼저 Volker Oth가 배포한 avrgcc 패키지에 보면 gcctest가 포함되어 있다. 윈도우용 avr-gcc를 성공적으로 설치한 사람들은 다 가지고 있을 것이다. c:\avr-gcc에 avr-gcc를 설치하였다면 하위 디렉토리에 gcctest를 풀도록 한다. 그러면 c:\avr-gcc\gcctest\gcctest1 디렉토리 밑에 오늘의 주제 소스 파일이 있을 것이다. 먼저 gcctest1 디렉토리를 살펴보면 다음과 같은 파일들이 존재한다.

 

gcctest1.c

 이번에 다룰 소스 파일이다.

makefile

 소스 파일을 컴파일하는데 필요한 규칙파일, 자세한 내용은 avr-gcc 설치법을 참고

 

그리고 실험에 이용될 회로도는 다음과 같다.

   먼저 위의 그림과 같이 PORTB에 LED를 8개 부착한다. 그림처럼 굳이 9V를 연결할 필요는 없다. 5V 파워 서플라이가 있으면 바로 연결해서 써도 좋다. 그리고 그림 왼편에서 Voltage Dector는 없다고 생각해도 좋으며, PD2, PD3에 스위치는 부착하지 않아도 좋다.

   그림에서 LED가 PORTB에 부착되어 있으며, LED의 캐소드가 포트핀에 물려있다. 따라서 포트 B의 출력이 '0'이면 LED가 켜진다. PORTB에 '0'를 출력하기 위해서는 다음과 같은 과정이 필요하다. PORTB는 입력/출력핀으로 사용할 수 있기 때문에 PORTB를 출력으로 설정하여야 한다. PORTB의 입출력을 결정하는 것이 DDRB 레지스터 이다. 8515의 매뉴얼을 보면 DDRB에 대하여 다음과 같이 기술하고 있다. DDRB는 8비트 레지스터로써 각 비트는 PORTB의 핀과 관계가 있다. 즉 DDRB의 5번째 비트에 1을 쓰면 PB5(PORTB의 5번째 핀)을 출력으로 설정한다. 우리는 PB0~PB7을 모두 출력으로 사용하여야 한다. 따라서 DDRB에 0xFF를 써주면 된다. PORTB에 원하는 값을 출력하고 싶을 때는 어떻게 해야 할까? 답은 PORTB 레지스터에 원하는 값을 쓰는 것이다. 예를 들어 PORTB에 0x02를 쓰면 PB1에 '1'이 출력되고 나머지 핀들에는 '0'이 출력된다. 따라서 PB1에 연결괸 LED를 제외한 모든 LED가 켜질 것이다.

   그럼 이제 아래의 소스 파일을 보자.

 

/*
    Title:    AVR-GCC test program #1 for the STK200 eva board
    Author:   Volker Oth
    Date:     4/1999
    Purpose:  Flashes the LEDs on Port B with a hard coded delay loop
    needed
    Software: AVR-GCC
    needed
    Hardware: ATS90S8515/8535/2313/mega on STK200/STK300 board
    Note:     To contact me, mail to
                  volkeroth@gmx.de
              You might find more AVR related stuff at my homepage:
                  http://members.xoom.com/volkeroth
*/

#include <io.h>                /* 입출력 함수가 정의되어 있다. */

typedef unsigned char  u08;

int main( void )               /* main() 함수는 모든 함수의 시작 지점이다. */
{
   u08 led, i, j, k;           
/* led : led의 상태를 저장, i, j, j : 아래의 for 루프를 수행하는 필요한 변수 */

   outp(0xff, DDRB);           /* PORTB의 방향을 모두 출력으로 선언 */

   led = 1;                    /* led라는 변수를 1로 초기화 */

   for (;;) {                  /* 무한 루프 시작 */
       outp(~led, PORTB);      
/* led라는 변수를 반전시킨후 PORTB에 그 값을 쓴다. */
       led <<= 1;              
/* led라는 변수내의 값을 왼쪽으로 1비트 쉬프트한다. */
       if (!led)               
/* led라는 변수가 8번 쉬프트되면 다시 1을 입력한다. */
           led = 1;


       for (i=0; i<255; i++)   
/* 시간을 지연시키기 위한 루프 */
           for(j=0; j<255;j++)
               k++;            
/* 의미없이 시간 지연을 위한 덧셈 */

    }

}

 

   위의 소스 파일에서 보면 생소한 것들이 몇가지 나온다. 먼저 io.h 파일은 입출력에 관계된 함수들과 레지스터의 어드레스가 선언된 파일이다. 우리의 예제에서는 outp()라는 함수가 나오는데 이 함수가 io.h에 선언되어 있다. 그리고 outp() 함수를 설명하면 다음과 같다.

outp(value, register_address);

                       value : 레지스터에 쓰고 싶은 값을 의미한다.
                       register_address : 값을 바꾸고 싶은 레지스터의 어드레스를 의미한다.

따라서, outp(0xff, DDRB); 라고 하면 DDRB 레지스터에 0xff를 쓴다. 그리고 led라는 변수는 LED를 켜기 위한 값을 저장하고 있는 변수이다. 처음부터 따라가 보면 처음에 led=1로 초기화된다. 그리고 for()루프에 들어가서 led값을 반전시킨후, 즉 (1의 반전=>0xFE)가 된다. 이를 PORTB에 쓴다. 그러면 PB0에 물린 LED가 켜진다. 그리고 led변수를 왼쪽으로 쉬프트 1하면 led=1에서 led=2가 된다. 즉, 다음번에 켜지는 LED는 PB1이 되고, 또 다시 led가 왼쪽으로 쉬프트 1하면 PB2가 켜진다. 이런 식으로 계속 for()루프를 반복하면 결국 led=0x80이 되고 이 상태에서 왼쪽으로 쉬프트 1면 led 변수값은 0가 된다. 그러면 if(!led)라는 조건문에서 걸려서 led=1로 다시 초기화된다. 마지막에 있는 for() 루프 두 개는 시간 딜레이를 얻기 위한 부분이다. 이렇게 하는 이유는 AVR의 명령어 수행 속도가 매우 빠르기 때문에 딜레이를 주지 않으면 LED가 8개 모두 켜진 것처럼 보이게 된다.

  다음 gcctest1 디렉토리에서 make라고 치고 엔터를 누르면 컴파일이 될 것이다. 컴파일 후에 생성되는 파일은 다음과 같다.

gcctest1.o

 gcctest1.c을 컴파일하여 얻어진 오브젝트 파일.

gcctest1.lst

 gcctest1.c가 어셈블리 언어로 변환된 파일(리스트 파일이라고 부른다).

gcctest1.obj

 AVR-Studio에서 사용하기 위한 오브젝트 파일

gcctest1.map

 롬파일의 구성이 어떻게 되는지를 보이는 맵파일

gcctest1.rom

 컴파일된 기계어 코드, 즉 롬파일

gcctest1.eep

 8515내부의 EEPROM 데이터 코드

위에서 *.eep 파일은 아직 필요가 없으며, 프로그램을 실행하기 위해서는 *.rom 파일을 ISP를 이용하여 플래쉬에 프로그램하면 된다.

   gcctest1.rom 파일을 프로그램하기 위해서는 먼저 홈페이지에 있는 AVR_ISP를 설치하여야 한다. AVR_ISP를 먼저 실행하고, 메뉴에서 Project->New Project...을 선택하면 다음과 같은 참이 뜬다. 그러면 디바이스 선택 창이 뜨고 독자의 환경에 맞는 디바이스를 선택한다.

  

그런 다음 Title에 다음과 같이 gcctest1이라고 쓴다.

그런 다음 세가지 윈도우(Data EEPROM Memory 윈도우, Program Memory 윈도우, Project Manager 윈도우)에서 Program Memory 윈도우를 클릭한다. 그런 다음 메뉴에서 File->Load를 선태한 다음 gcctest1.rom을 선택한다.

그러면 다음과 같이 파일이 성공적으로 읽힌다.

그리고 난 후 메뉴에서 Options->Change Printer Port를 선택하면 다음과 같이 프로그래머를 감지한다. 필자의 경우는 STK300을 사용하기 때문에 아래와 같이 출력된다.

다음은 F5를 누르거나 메뉴에서 Program->Auto-program을 선택하면 프로그래밍이 된다. 속도가 느릴 경우는 다음과 같이 하면 빨리 프로그래밍 할 수 있다. 즉 EEPROM은 Writer와 Verify를 할 필요가 없으며, Verify Device도 생략해도 된다.(대부분 Verify에 시간이 많이 소요된다.)

여기까지하면 LED가 순차적으로 깜박이는 것을 볼 수 있을 것이다. 마지막으로 프로젝트를 저장한다. Project->Save Project...를 선택한 후 원하는 파일명으로 프로젝트를 저장하면 된다. 프로젝트는 *.avr이라는 확장자로 저장된다.

 5를 이용하는 편이 낳을 듯 싶다. 가격도 6,000~7,000원 정도하고 8051하고 외형이 비슷하다(하지만 더 강력하다). 그리고 ISP 프로그래머는 "롬 라이터 만들기"

 

상호 : (주) 로보블럭 사업자등록번호:214-86-56219 통신판매업신고19-2544 대표: 신대섭 전화:(02)2679-8556 Fax :(02)2679-8557
본사 : 경기도 부천시 원미구 약대동 부천 테크노파크 401동 502호     서울사무소 : 서울시 영등포구 문래동 4가 8-1 4층
Copyright(C) 2004, (주) 로보블럭 시스템즈 All Rights Reserved E-Mail : WebMaster