본문으로 바로가기

ATmega128 Delay함수 사용 방법

category MCU/AVR 2019. 5. 11. 11:24
반응형

오늘 포스팅할 내용은 ATmega128에서 Delay 함수 사용 방법입니다. Delay는 설정한 시간 동안 프로그램을 중지시키는 기능입니다. LED 제어, LCD 제어, DC 모터 제어 등 안 사용하는 곳이 없기 때문에 꼭 알아야 하는 함수입니다.


Delay함수의 헤더는 하기 경로에 위치해 있습니다.

C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\util


먼저 Delay 함수를 사용하기 위해서는 헤더(util/delay.h)를 추가해야 합니다. 우선 예제를 통해서 알아보겠습니다. 


Delay 사용법 잘못된 예제


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <avr/io.h>
#include <util/delay.h>
 
 int main(void)
 {
    DDRA = 0xFF// 모든 포트 출력으로 설정.
    PORTA = 0x00;
    
     /* Replace with your application code */
     while (1)
     {
        PORTA |= 0x01;
        _delay_ms(1000);
        PORTA &= 0x01;
        _delay_ms(1000);
        
     }
     return 0;
 }



- 이 소스 코드에는 문제가 있습니다. 그대로 복사 후 컴파일을 해보면
#warning "F_CPU not defined for <util/delay.h>" [-Wcpp]라는 경고문이 발생합니다.

C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\util경로에서 delay.h를 살펴보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef F_CPU
/* prevent compiler error by supplying a default */
# warning "F_CPU not defined for <util/delay.h>"
/** \ingroup util_delay
    \def F_CPU
    \brief CPU frequency in Hz
    The macro F_CPU specifies the CPU frequency to be considered by
    the delay macros.  This macro is normally supplied by the
    environment (e.g. from within a project header, or the project's
    Makefile).  The value 1 MHz here is only provided as a "vanilla"
    fallback if no such user-provided definition could be found.
    In terms of the delay functions, the CPU frequency can be given as
    a floating-point constant (e.g. 3.6864E6 for 3.6864 MHz).
    However, the macros in <util/setbaud.h> require it to be an
    integer value.
 */
# define F_CPU 1000000UL
#endif


- F_CPU라는 값이 정의되지 않으면 warning이 발생하고 이 값은 1M로 define 되게 됩니다. 따라서 정확한 delay를 사용하기 위해서는 외부 크리스탈과 동일한 값을 F_CPU에 define을 해야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define F_CPU 16000000UL // 외부 크리스탈 16MHz
#include <avr/io.h>
#include <util/delay.h>
 
 int main(void)
 {
    DDRA = 0xFF// 모든 포트 출력으로 설정.
    PORTA = 0x00;
    
     /* Replace with your application code */
     while (1)
     {
        PORTA |= 0x01;
        _delay_ms(1000);
        PORTA &= 0x01;
        _delay_ms(1000);
        
     }
     return 0;
 }


- 저는 외부 크리스탈에 16MHz를 사용하기 때문에 F_CPU에 16000000UL이라는 값을 define 해주었습니다. 여기서 UL이라는 것은 unsigned long을 의미합니다. 


- 컴파일을 해보면 정상적으로 성공이 되고, 모든 포트를 출력으로 설정 후 1초마다 PORTA의 0번핀을 High, Low를 반복하고 있습니다.


- _delay_ms는 ms단위로 동작하기 때문에 1000을 넣으면 1초, 100을 입력하면 0.1초가 됩니다.


util/delay.h에는 void _delay_ms(double __ms)함수 말고도 u단위를 사용하는 void _delay_us(double __us)함수도 있으니 용도에 맞게 사용하면 될 것 같습니다. 


반응형

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

ATmega128 블루투스 제어(HC-06)  (1) 2019.11.24
ATmega128 타이머를 이용한 DC모터 제어  (0) 2019.08.13
ATmega128 입출력 제어  (2) 2019.04.22
[atmel studio7]ATmega128 프로젝트 생성  (6) 2019.04.05