ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Atmega128 기초 - 8비트 타이머/카운터 일반모드
    Avr/Atmega128 강좌 2016. 6. 17. 01:05



    용어 정의

    BOTTOM - 카운터가 0이 되었을 때를 의미.


    MAX – 카운터가 0xFF(=255)에 도달했을 때를 의미


    TOP 

    TOP값은 0xFF(MAX) 또는 OCR0 레지스터에 저장된 값으로 지정할 수 있다.

    카운터가 TOP값과 똑같거나 더 커진 경우를 의미한다.



    일반 모드

    TCCR0 레지스터의 WGM00 비트와 WGM01 비트가 0으로 설정된 경우이다.



    TCNT0 레지스터는 카운터에서 값을 직접 읽거나 쓸 수 있게 해주는 레지스터이다.


    일반 모드에서 카운팅은 항상 증가하는 방향으로 이루어 진다.


    8비트로 표현할 수 있는 최대값인 0xFF(=255)를 초과하면 다시 bottom(=0)부터 카운팅을 시작한다.  TCNT0가 0이 되는 순간 TIFR 레지스터의 TOV0 비트가 1로 설정된다.


    타이머/카운터 오버플로우 인터럽트와 같이 사용되면, TIFR 레지스터의 TOV0 플래그 비트는 자동으로 0으로 클리어된다.


    TIMSK 레지스터의 TOIE0 비트가 1로 설정되고 Status 레지스터의 I비트가 1로 설정되었을 때 타이머/카운터0 오버플로우 인터럽트가 활성화된다.




    프리스케일러 선택은 TCCR0레지스터의 CS02, CS01, CS00 비트에 의해서 결정된다.



    아래처럼 회로를 구성하고 프로그램 코드를 테스트한다. 



    사용중인 크리스탈의 값 F_CPU = 16Mhz이고 8비트 타이머(최대값 255)를 사용한다면 만들 수 있는 최소 딜레이값은 0.016ms이다. 계산과정은 다음과 같다.


    주기 = 1/주파수 = 1/16000000 Hz = 0.0000000625 s = 0.0000625 ms


    타이머 카운터 = 필요한 딜레이 시간 / 클록 시간 주기 – 1

    255 = X / 0.0000625 ms – 1

    X = 256 * 0.0000625 ms = 0.016 ms



    1 ms를 만들고 싶다면... 위에서 계산한 순서대로 계산해보면 된다.


    F_CPU 그대로 사용한다면

    16MHz => 0.0000625 ms

    1ms/0.0000625ms –1 = 15999=> 8비트 표현 범위를 넘어섬..


    프리스케일러로 8을 사용한다면

    16MHz / 8 = 16000000/8 = 2000000Hz => 0.0000005 s = 0.0005ms

    1ms/0.0005ms –1 = 1999 => 8비트 표현 범위를 넘어섬..


    프리스케일러 64를 사용한다면

    16Mhz / 64 = 16000000/64 = 250000Hz => 0.000004 s = 0.004ms

    1ms/0.004ms –1 = 249 => 8비트 카운터로 사용가능


    프리스케일러 256을 사용한다면

    16Mhz / 256 = 16000000/256 = 62500Hz => 0.000016 s = 0.016ms

    1ms/0.016ms-1=61.5 => 소수점이 있음


    프리스케일러 1024를 사용한다면...

    16Mhz / 1024 = 16000000/1024 = 15625Hz => 0.000064 s = 0.064ms

    1ms/0.064ms-1=14.625 => 소수점이 있음..



    위에서 계산한 결과를 이용하여 1ms마다 오버플로우 인터럽트가 발생하도록 설정해놓았다.

    프르스케일러로 64를 사용하게 되며 TCNT0의 시작값은 256-249인 7이 된다.

    249는 위에서 계산한 결과 값이다.




    따라서 total_overflow_count값이 1000이 될때마다 1초가 되므로 

    LED는 1초가 될 때마다  켜지게 된다..


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    /*
     * 8bit_timer_example.c
     *
     * Created: 2016-06-17
     * Author : webnautes
     */ 
    #define F_CPU 16000000UL
     
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
     
    volatile uint16_t total_overflow_count;
     
     
    ISR(TIMER0_OVF_vect)
    {
        total_overflow_count++;
        TCNT0 = 7;
    }
     
    int main(void)
    {
        DDRB |= (1<<DDB3); //LED용
     
        //프리스케일러로 64를 선택
        TCCR0 |= (1<<CS02);
     
        //카운터 초기화 256-249
        TCNT0 = 7;
     
        //타이머/카운터 오버플로우 인터럽트 활성화
        TIMSK |= (1<<TOIE0);
     
        //전역 인터럽트 활성화
        sei();
     
        total_overflow_count = 0;
     
     
        /* Replace with your application code */
        while (1
        {
            if ( total_overflow_count == 1000 ) //1초마다 LED 켜짐
            {
                total_overflow_count = 0;
                PORTB |= (1<<PB3);
                _delay_ms(10);
            }
            else PORTB &= (~(1<<PB3));
     
                
        }
    }
     
     
    cs


    포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
    댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.

    여러분의 응원으로 좋은 컨텐츠가 만들어집니다. 지금 본 내용이 도움이 되었다면 유튜브 구독 부탁드립니다. 감사합니다 : )

    유튜브 구독하기


    댓글 0

Designed by Tistory.