Skip to content
irmusy edited this page Oct 2, 2013 · 1 revision

개요

SysTick 타이머는 일반 timer와 쓰임세가 조금 다릅니다. 일반 타이머는 외부 클럭을 카운트하거나 시간 주기를 측정하는 capture, 내부 클럭을 이용해 특정 주기를 만드는 등의 용도로 쓰입니다. 이 머릿 글자를 따라 타이머를 CCP(Capture, Compare, PWM) 유닛이라 부르기도 합니다.

반면 SysTick 타이머는 오직 정주기를 만드는 용도로만 쓰입니다. 또한 일반 타이머와 달리 Cortex-M3 코어에 내장된 타이머입니다. 즉 칩 제조사가 다르더라도 모든 Cortex-M3 칩은 SysTick 타이머를 가지고 있습니다.

SysTick 타이머는 시스템 틱 타이머의 약자입니다. 리얼타임 OS를 사용할 때 1ms 주기의 틱 타이머를 만드는 용도로 SysTick 타이머가 많이 쓰입니다. 꼭 RTOS에서만 아니라 일반 펌웨어 작성에서도 정해진 주기로 반복되는 작업을 구현할 때 일반 타이머 보다 더 유용하게 쓰입니다.

본 예제에서는 1ms 주기의 SysTick 타이머를 설정하고, SysTick 타이머 인터럽트 핸들러에서 전역 변수의 값을 1씩 증가시켜줍니다. 이 전역변수는 부팅 이후 경과된 ms 단위의 시간을 의미하게 될 것입니다. main()함수에서는 이 시간이 1초 경과할 때 마다 LED를 깜박이게 하였습니다.

관련 Peripheral

  • SysCtl
  • SysTick
  • GPIO
  • interrupt

소스 살펴보기

45 line:

static volatile unsigned long tick_count;

전역변수로 tick_count를 선언합니다. SysTick 인터럽트가 발생할 때 마다 이 변수의 값을 1씩 증가시킵니다. 따라서 1ms 마다 1씩 증가하게 됩니다.

변수 선언에 volatile이 있습니다. 이 전역변수는 SysTick 인터럽트 핸들러 내부에서만 값이 변경(write)되고 main()함수 내부에서는 값을 참조(read)하기만 합니다. 이런 경우 컴파일러 설정에 따라 main() 함수 내부에서는 tick_count 값이 변경된 것을 인지하지 못할 수 있기 때문에 인의적으로 volatile 형태로 선언하였습니다.

64 line:

    //
    // Set up the period for the SysTick timer.
    //
    SysTickPeriodSet(SysCtlClockGet() / 1000);   // 1kHz SysTick timer

SysTick 타이머 주기를 설정합니다. 1000Hz 주기입니다. 이런 형태로 코드를 작성하면 MCU의 클럭이 얼마가 되든 상관없이 원하는 결과를 얻을 수 있습니다. 참고로 SysTick 예제는 MCU 코어 클럭으로 8MHz를 사용하고 있습니다. 만일 52 라인의 코드를 수정하여 50Mhz로 변경하더라도 67 라인의 코드는 변경할 필요 없습니다. 여전히 1ms 주기의 SysTick 타이머가 동작하게 됩니다.

70 line:

    //
    // Enable the SysTick Interrupt.
    //
    SysTickIntEnable();
    SysTickIntRegister(SysTickIntHandler);

    //
    // Enable SysTick.
    //
    SysTickEnable();

SysTick 인터럽트를 활성화하고 사용자의 인터럽트 핸들러 함수를 등록해 줍니다. 마지막으로 **SysTickEnable()**을 호출하여 SysTick 타이머를 동작시킵니다.

87 line:

        SysCtlSleep();              // sleep here till interrupt

        if (tick_count % 1000 == 0) // toggle LED for every seconds.
            LED_TOGGLE();

SysTick 타이머 인터럽트가 발생할 때 까지 sleep 모드에 있다가 인터럽트가 발생하면 if문으로 내려갑니다. if 문에서는 tick_count 전역 변수가 1000의 배수가 되었는지 확인해 보고 그렇다면 LED를 토글시키고 있습니다. tick_count는 SysTick 인터럽트 핸들러에서 1ms 마다 1씩 증가되는 전역변수입니다. 따라서 1000번의 1ms, 즉 1초가 지나면 한번 LED가 토글됩니다.

95 line:

void SysTickIntHandler(void)
{
    tick_count++;               // increment counter value for every 1ms.
}

SysTick 인터럽트가 발생했을 때 호출되는 인터럽트 핸들러 입니다. 본 예제에서는 tick_count 변수 값을 1씩 증가시켜 주는 코드만 있습니다. SysTick 인터럽트는 별도의 flag가 set되지 않습니다. 또한 flag를 clear 해 주지도 않습니다.

실행 방법 안내

  1. 펌웨어를 빌드하여 다운로드한 후 리셋 스위치를 1회 누릅니다.
  2. 보드에 내장된 LED가 1초 마다 켜지고 꺼지는 것을 반복하는 것을 확인합니다.