[AVR] EEPROM 이란

2013. 10. 23. 02:00 from MCU/AVR

ATmega128 의 메모리 중 flash 메모리와  EEPROM   내장하고 있다. flash 메모리는 128KB,  EEPROM  은 4KB 용량이다. 적은량 같지만 실제로 이정도면 웬만한 것은 전부 제어할 수 있다.



컴퓨터에 비유하면 flash 메모리는 하드디스크에 비유할 수 있고 EEPROM 은 USB 에 비유할 수 있다. EEPROM 은 SRAM 과 속성이 비슷하지만 비휘발성으로 매우 유용하다. 그러나 읽고 쓰는데 걸리는 시간이 느리므로 SRAM 과 동일하게 사용할 수 없다. 따라서 EEPROM 은 실시간으로 사용되는 변수를 저장하는 메모리로 사용할 수는 없으며, 한번 저장도니 내용은 비교적 오랫동은 저장되며 전원을 껏다 켜도 데이터가 날라가지 않으므로 중요한 정보를 저장시키는 것으로 유용하다.




Posted by 나무길 :

예전부터 지식인에서 저에게 초음파센서 모듈인 SRF05를 가지고 어떻게 거리측정하는 것을 구동할 수 있냐고

물어보는 사람들이 많아서 이번에 그냥 강좌식으로 정리해볼까 합니다.

SRF05_CIRCUIT.jpg

 일단 회로도는 위와 같습니다. ATmega128을 사용하고 위와 같은 방식으로 연결해 주면 되겠습니다.

 물론 반드시 위와 같이 연결하지 않으셔도 됩니다. 그 이유는 아래의 설명을 보시면 자연히 알게 될꺼에요.

 

 일단 SRF05란 놈에 대해 먼저 알아볼까요?

 srf05.jpg

 일단 모양은 위와 같이 생긴 놈입니다. 음.. 마치 특정 모듈 광고(?) 인것 같아서 좀 찜찜하기 하지만..

 사실 저것만 사용해봐서 뭐 딱히 강좌를 쓸라고 해야 쓸 수가 없습니다..ㅡㅡ;

 스팩은 아래와 같습니다.

 (http://eleparts.co.kr/front/productdetail.php?productcode=005035002004000009&sort=) 참고했음.

 

 -입력전압 : +5VDC

 -소비전류 : 4mA Typical

 -주파수 : 40Khz(초음파센서이니 40Khz의 주파수(초음파)를 사용한다는 의미겠지요.)

 -최대 측정거리 : 4M

 -최소 측정거리 : 1cm

 -모드 : mode 1 => SRF04 모드 (Input핀과 Output 핀이 분리됨)

            mode 2 => Single Pin Mode (Input핀과 Output 핀을 공유함) -> SRF05의 특징임

 -입력신호 : 10usec의 TTL High Pulse

 -에코펄스신호(출력되는 신호) : Positive TTL level Signal(측정거리에 따라 Pulse Width가 달라짐)

 -크기 : 43 * 20 * 17mm

 -초당 측정횟수 : 약 20회/sec (한번측정에 최대 50msec 소요)

 

 일단 위와 같은데 중요하게 생각할 것이 cm 단위로의 측정이 가능하다는 것이죠.

 물론 계산하기에 따라서 mm 단위도 가능할 수도 있겠으나 스팩에서 사용하는 단위는 Cm와 inch 단위 입니다.

 

 자~ 이제 서서히 강좌를 제대로 시작해 보도록 할께요.

 먼저 위의 회로도는 설명하지 않겠습니다. 128의 기본회로에서 SRF05 추가한 것 빼고는 아무것도 없으니까요.

 또한 5V 전원을 그대로 사용한다면 7805도 필요 없을 것입니다.

 

 그럼 SRF05를 어떻게 사용하느냐의 문제만 남겠군요.

 아래 그림부터 보시지욧~

 srf05_pulse.jpg

 

 1) Trigger Input 핀에 10usec의 High Pulse를 출력해줍니다.(첫번째 펄스 그림)

 2) 10usec 의 펄스를 입력해 주게 되면 2번째 펄스 그림과 같이 8 싸이클의 초음파(40khz)가 발생됩니다.

     즉, 10usec의 High 펄스가 초음파를 쏴라~! 라고 명령을 주게 된 것이지요.

 3) 이렇게 초음파가 출력되고 물체에 부딪쳐서 반사되어 다시 센서로 되돌아 오게 되면 Echo Output 핀쪽에서

     해당 거리에 따라 High Pulse가 출력되게 됩니다. 즉, 측정된 거리에 따라 High Pulse의 Width가 달라집니다.

     위의 그림에 따르면 100usec ~ 25msec까지 출력되고 30msec가 넘어가면 물체를 감지하지 못한것으로

     간주한다고 나와있군요(Time OUT이라는 의미임)

     따라서 우리는 이렇게 출력되는 High Pulse의 Width의 시간폭을 알아내면 측정거리를 알 수 있겠군요.

 4) 펄스 폭에 대해 거리 계산을 하는 방식은 데이터 시트에 아래와 같이 나와있습니다.

   The SRF04 provides an echo pulse proportional to distance. If the width of the pulse is measured

   in uS, then dividing by 58 will give you the distance in cm, or dividing by 148 will give the distance

   in inches.  uS/58=cm or uS/148=inches.

    : 위의 글에 따르면 58usec = 1cm 이고 148usec = 1inch 로 계산하라고 나와있군요.

      즉, Cm 단위를 사용하기 위해 출력되는 펄스의 시간적 폭을 58usec씩 구분하면 된다 이겁니다. 

 

   

음.. 그럼 이제 어떻게 구동하는 지 알았으니 직접 소스코딩일 통해서 제어해 보도록 하지요.

 

#include <mega128.h>
#include <delay.h>

#define SONIC_INPUT PORTD.4
volatile unsigned int pulse_count = 0;

volatile unsigned char togle = 0;

void pulse(void) // 10usec의 High 펄스를 출력
{
        SONIC_INPUT = 1;
        delay_us(10);
        SONIC_INPUT= 0;        
}
interrupt [TIM0_OVF] void cho_pulse(void)
{      
        pulse_count++; // 58usec 마다 1씩 증가                       
}
interrupt [EXT_INT4] void pulse_read(void)
{
        if(togle == 0) // 카운터 시작하고 외부 인터럽트(INT4)를 다음에는 Falling Edge에거 걸리도록 함.
        {
                pulse_count = 0; // 측정된 이전 거리값 초기화
                //******************** TIMER COUNTER RESISTER ********************
                TIMSK = 0x01; // Timer Counter 0 Enable 
                //OCE2, TOIE2, TICIE1, OCIE1A, OCIE1B, TOEI1, OCEI0, TOIE0
                TCCR0 = 0x02; // 8ck
                TCNT0 = 140;    //58us/per count
                EICRB = 0x02; // EXT_int4 falling edge interrupt
                togle = 1;
        }
        else // 카운터를 정지시키고 외부 인터럽트(INT4)를 다음에는 Riging Edge에서 걸리도록 함.
        {
                TIMSK = 0x00; // All Timer Disable
                togle = 0;
                EICRB = 0x03; //INt4 high_edge interrupt
        }                          
             
}

void main(void)
{
        
        DDRD = 0x10; // PD.4 : input pulse(출력으로 설정)  송신
        DDRE = 0x00; // PE.4:  output pulse(EXT INT4) 수신
        delay_ms(5);

        
        //******************** ENT_INT0,1 Register *********************
        
        EIMSK = 0x10; //INT4 EXT_Interrupt Enable
        EICRB = 0x03; //INt4 high_edge interrupt
        //************************************************************
        
        
        ACSR=0x80;
        SREG = 0x80; // 전체 인터럽트 Enable
        #asm("sei")
        while(1)
        {
                pulse(); // 10usec High Pulse Output
        }      
}

 

위의 코드를 분석해 보도록 하지요.

 

1) pulse 함수는 아까 말한대로 SRF05에 10usec의 High 펄스를 입력해주어 초음파가 발생되로고 해주는 함수로

    main 함수의 While(1)에서 계속 무한반복하여 출력하고 있습니다.

 

2) pulse 함수를 통해 초음파가 출력되고 반사된 초음파가 수신되면 Echo Output 핀에서 High Pulse가 뜨겠군요.

    그러면 그때 부터 들어오는 펄스의 시간폭을 측정해야 하지요.

     일단 출력이 나오기 시작하는 것이 Low => High 로 바뀌는 것이고 이 때부터 타이머 카운터 0를 Enable 시켜

     야 하니까 이 출력되는 핀을 외부 인터럽트 핀(회로에서는 INT4에 연결)에 연결해 두고 처음에 Rigind Edge

     를 체크하게 하여 인터럽트가 걸리게 만들어 놓습니다.

     srf05_01.jpg

    즉, 위와 같이 펄스폭의 측정을 시작하는 점을 알아내기 위해 Riging Edge 체크를 통해 인터럽트가 걸리게 해놓

    고 카운트를 시작하게 만든다는 것이죠.

 

 3) 인터럽트를 통해 카운트 시작을 알고 나면 Timer Counter 0를 Enable 시키고 타이머 카운터의 인터럽트는

     TCNT값과 설정 레지스터값을 조정하여 58usec마다 인터럽트가 걸려서 pulse_count 값을 1씩 증가시키게

     합니다.

 4)  이제 출력되는 펄스가 다시 High => Low로 변경되면 카운트를 정지해야 하기 때문에 펄스가 떨어지는

      시점을 알기 위해 외부 인터럽트 체크를 Falling Edge 체크로 변경하여 펄스가 떨어지는 구간을 잡아내고

      그 때는 Timer Counter 0를 Disabel 하여 더 이상 Pulse_count 값이 증가되지 않도록 합니다.

 5) 이렇게 되면 Pulse_count 값이 58usec마다 1씩 증가했으므로 이 값이 측정된 거리 값이 됩니다.(cm단위)

 

이제 위의 코드에서 Pulse_count 값을 UART를 통해 PC로 보내던지..

아니면 해당 값을 LCD에 출력하던지, LED로 표시하던지는 사용자의 몫이겠군요.

 

여기서 사실 제가 테스트한 결과 약간의 거리 오차가 1~2cm 정도는 차이가 납니다.

실제 구동을 해보고 센서 앞에 30cm 짜리 줄자를 높은 후에 직접 테스트를 해서

오차범위의 값을 pulse_count 값에서 빼주거나 더해주면 됩니다.

 

또한 초음파센서라는 것 자체가 음파의 반사를 이용하는 것이므로 주변의 환경이 시끄럽거나 하게 되면

신호에 노이즈가 타서 거리측정의 오차가 더욱 심해질 우려가 있다는 것을 주의해 주시길 바랍니다.

추가적으로 반사되는 물체에 따라서도 측정거리가 달라질 수 있으니 되도록 반사되는 물체는 반듯한

면이 되는 물체와의 거리를 측정하는 것이 좋습니다.

최대 측정거리도 실제로 해보니 2M를 넘어가게 되면 측정이 좀 이상하게 되더군요.

되도록 1M 이내의 거리를 측정하는 용도로 사용하면 좋을 것 같습니다.

 

이상 SRF05 사용강좌를 마칠께요~

도움이 되셨길 바랍니다.


출처 : http://j102.net/4020

'MCU > AVR' 카테고리의 다른 글

Datasheet 레지스터 보는 방법  (0) 2013.12.03
[AVR] 인터럽트  (0) 2013.12.03
[AVR] 시작하기 전에 알아야 할 것들  (0) 2013.12.02
ATmega128 과 블루투스 연결하기  (4) 2013.10.23
[AVR] EEPROM 이란  (0) 2013.10.23
Posted by 나무길 :