SW 개발자를 위한 하드웨어의 이해. 두번째

마이크로 콘트롤러의 이해



2019년
http://goo.gl/ztX1n


셋째날 시간표


Quiz

http://dh8.kr/wiki/doku.php/workshop:quiz


직접 메모리 제어하기: 포인터

C에서 메모리 주소를 변수에 저장하여 사용. -> 포인터


Lesson 4: Blinky program

이제 프로그램을 만들어 보자!

포인터를 이용!

*((unsigned int *)0x400FE608U) = 0x20; // clock gateing
*((unsigned int *)0x40025400U) = 0x0E; // pin direction output
*((unsigned int *)0x4002551CU) = 0x0E; // PF_1, PF_2, PF_3 enable!
*((unsigned int *)0x400253FCU) = 0x02; // RED ON!

해보기:

코드 pointer.c


Lesson 5: 전처리자

전처리자의 종류

//#define, #include #if #ifdef …

해보기:

#define RCGCGPIO  (*(unsigned int*) 0x400FE608U)
#define GPIOF_BASE
#define GPIOF_DIR
#define GPIOF_DEN
#define GPIOF_DATA

코드 preprocessor.c


Lesson 5: 전처리자 2

lm4f120h5qr.h 사용.

해보기

RCGGPIO -> SYSCTL_RCGCGPIO_R
GPIOF_DIR -> GPIO_PORTF_DIR_R
GPIOF_DEN -> GPIO_PORTF_DEN_R
GPIOF_DATA -> GPIO_PORTF_DATA_R

#include "lm4f120h5qr.h"

int main() {
    SYSCTL_RCGCGPIO_R = 0x20;  // clocking gpio
    GPIO_PORTF_DIR_R = 0x0E; // Portf pin 1,2,3
    GPIO_PORTF_DEN_R = 0x0E;
    while (1) {
        GPIO_PORTF_DATA_R = 0x02;
        int volatile counter = 0;
        while (counter < 1000000) { 
            ++counter;
        }
        GPIO_PORTF_DATA_R = 0x00;
        counter = 0;
        while (counter < 1000000) { 
            ++counter;
        }
    }
    return 0;
}

코드 lm4fheader.c


Lesson 6: 비트연산

비트연산 왜 필요하나? pin setting, clear, toggle, shift

6개 비트 연산


Lesson 6: 비트연산 2

unsigned int a = 0x5A5A5A5A;
unsigned int b = 0x66666666;
unsigned int c; 
c = a | b;
c = a & b;
c = a ^ b;
c = ~b;
c = b >> 1;
c = b << 3;

해보기


Lesson 6: 비트연산 3

부호(signed) 타입 C에서, C에 음수가 일때 있을때, c >> 1 을 실행하면, 최상위 비트에 1이 따라감. 왜?

ASR(산술 shift right)을 사용.

정말 그런지 증명해 봅시다.

해보기 - c를 signed int 타입로 선언하고, c에 음수를 넣고 shift right 해보자.


Lesson 6: 비트연산 사용하여 코드 정리!

2 == (1U << 1)
4 == (1U << 2)
8 == (1U << 3)

0x20 = (1U << 5)

다음을 이용하여, LED_RED, LED_BLUE, LED_GREEN 전처리자를 만들어 보자. 코드


#include "lm4f120h5qr.h"

#define LED_RED   (1U << 1)
#define LED_BLUE  (1U << 2)
#define LED_GREEN (1U << 3)
int main() {
  SYSCTL_RCGCGPIO_R |= (1U << 5); 
  GPIO_PORTF_DIR_R |= (LED_RED | LED_BLUE | LED_GREEN);
  GPIO_PORTF_DEN_R |= (LED_RED | LED_BLUE | LED_GREEN);
  GPIO_PORTF_DATA_R |= LED_BLUE;
  while (1) {
    GPIO_PORTF_DATA_R |= LED_RED;
    int volatile counter = 0;
    while (counter < 1000000) {  
      ++counter;
    }
    GPIO_PORTF_DATA_R &= ~LED_RED;
    counter = 0;
    while (counter < 1000000) {  
      ++counter;
    }
  }
  return 0;
}

Byte Order

해보기

Memory endianness: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/I1835.html


Structure Memory Mapping

#include <stdint.h>
// uint16_t
// uint32_t
// uint8_t
#include <stdint.h>    
#include "lm4f120h5qr.h"

#define LED_RED   (1U << 1)
#define LED_BLUE  (1U << 2)
#define LED_GREEN (1U << 3)

typedef struct {
    uint16_t x;
    uint8_t y;
} Point;
Point p1, p2;

int main() {
  p1.x = sizeof(Point);
  p1.y = p1.x - 3U;

  SYSCTL_RCGCGPIO_R |= (1U << 5); 
  GPIO_PORTF_DIR_R |= (LED_RED | LED_BLUE | LED_GREEN);
  GPIO_PORTF_DEN_R |= (LED_RED | LED_BLUE | LED_GREEN);
  GPIO_PORTF_DATA_R |= LED_BLUE;
  while (1) {
    // 생략
  }
  return 0;
}

해보기

더 해보기


CMSIS (software interface standard)

tm4c_cmsis.h를 추가하고, core_cm4.h의 디렉토리 위치를 Preprocessor옵션 위치에 추가하자.

#define GPIOF ((GPIO_Type*) GPIO_PORTF_BASE)

.

#include <stdint.h>    
#include "tm4c_cmsis.h"

#define LED_RED   (1U << 1)
#define LED_BLUE  (1U << 2)
#define LED_GREEN (1U << 3)

int main() {

  SYSCTL->RCGC2 |= (1U << 5); 
  GPIOF->DIR |= (LED_RED | LED_BLUE | LED_GREEN);
  GPIOF->DEN |= (LED_RED | LED_BLUE | LED_GREEN);
  // GPIOF->DATA_Bits[LED_BLUE] |= LED_BLUE;
  GPIOF->DATA |= LED_BLUE;    
  while (1) {
    GPIOF->DATA |= LED_RED;
    int volatile counter = 0;      
    while (counter < 1000000) {  
      ++counter;
    }
    GPIOF->DATA &= ~LED_RED;
    counter = 0;
    while (counter < 1000000) {  
      ++counter;
    }

  }
  return 0;
}

해보기


TivaWare

TI에서 제공하는 Cortex-M 라이브러리

Tivaware Peripheral Driver Library USER’S GUIDE

해보기


새 프로젝트 만들기: project0

TivaWare 를 사용해보자. 다운로드 받은 SW-TM4C–2.1.1.71.exe를 실행하자.


#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"

#define RED_LED   GPIO_PIN_1
#define BLUE_LED  GPIO_PIN_2
#define GREEN_LED GPIO_PIN_3

int
main(void)
{
    //
    // Setup the system clock to run at 50 Mhz from PLL with crystal reference
    //
    SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|
                    SYSCTL_OSC_MAIN);

    //
    // Enable and configure the GPIO port for the LED operation.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED);

    while(1)
    {
        GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED, RED_LED);

        SysCtlDelay(2000000);

        GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED, BLUE_LED);

        SysCtlDelay(2000000);
    }
}

해보기


버튼 읽기

https://gist.github.com/donghee/e9182ab4a3af65b613de

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "inc/hw_gpio.h"

#define RED_LED GPIO_PIN_1
#define BLUE_LED GPIO_PIN_2
#define GREEN_LED GPIO_PIN_3

#define BUTTON_2 GPIO_PIN_0
#define BUTTON_1 GPIO_PIN_4

int main(void)
{
  int LED = 2;
  // configure system clock to run at 50 MHz
  // use external crystal (16 MHz) and PLL
  SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

  // Enable PORT F GPIO
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
  GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED);

  // Button Setup.
  // UNLOCK BUTTON_2
  HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
  HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
  HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;

  GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, BUTTON_1|BUTTON_2);
  GPIOPadConfigSet(GPIO_PORTF_BASE, BUTTON_1|BUTTON_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

  while(1)
  {
    LED = 0;
    if(!GPIOPinRead(GPIO_PORTF_BASE, BUTTON_1))
      LED |= RED_LED;

    if(!GPIOPinRead(GPIO_PORTF_BASE, BUTTON_2))
      LED |= BLUE_LED;

    GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED, LED);
    // Delay for a bit
    //SysCtlDelay(5000000);
  }
}

GPIO의 핀세팅

입력핀

GPIO내부회로

출력핀


GPIO 입출력 구조

from datasheet (stm32f)


인터럽트 콘트롤러 (Nested Vectored Interrupt Controller (NVIC))


버튼 읽기: 핀 인터럽트

핀의 입력을 감시하다가 핀의 입력이 변할때 인터럽트 핸들러를 실행

https://gist.github.com/donghee/8d0ad90e264ddcb59f9e

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
//#include "driverlib/pin_map.h"
//#include "driverlib/uart.h"
//#include "utils/uartstdio.h"

#define RED_LED GPIO_PIN_1
#define BLUE_LED GPIO_PIN_2
#define GREEN_LED GPIO_PIN_3

#define BUTTON_2 GPIO_PIN_0
#define BUTTON_1 GPIO_PIN_4

// handler if button 1, 2 is pressed
// when pressed it changes which LED colors
void GPIOFIntHandler(void)
{
    unsigned int isr = GPIOIntStatus(GPIO_PORTF_BASE, true);
    GPIOIntClear(GPIO_PORTF_BASE, BUTTON_1|BUTTON_2);

    GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|GREEN_LED|BLUE_LED, 0); // turn off LEDs

    if (isr & BUTTON_1)  {
        GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|BLUE_LED, RED_LED); 
        //UARTprintf("Button 1\n");
    }

    if (isr & BUTTON_2) {
        GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|BLUE_LED, BLUE_LED); 
         //UARTprintf("Button 2\n");
    }

    if (!GPIOPinRead(GPIO_PORTF_BASE, (BUTTON_1)) &&
        !GPIOPinRead(GPIO_PORTF_BASE, (BUTTON_2))) {
        GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|GREEN_LED|BLUE_LED, 0); // turn off LEDs
        GPIOPinWrite(GPIO_PORTF_BASE, GREEN_LED, GREEN_LED);
    }
}

int main(void) {

    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); 

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

   //  launchpad 스위치 쓸려면 lock을 풀어줘야함!
    // Unlock PF0 so we can change it to a GPIO input
    // Once we have enabled (unlocked) the commit register then re-lock it
    // to prevent further changes.  PF0 is muxed with NMI thus a special case.
    //
    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
    HWREG(GPIO_PORTF_BASE+ GPIO_O_LOCK) = 0;

    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, RED_LED|GREEN_LED|BLUE_LED); 
    GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|GREEN_LED|BLUE_LED, 0); // turn off LEDs

    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, BUTTON_1|BUTTON_2); 
    GPIOPadConfigSet(GPIO_PORTF_BASE, BUTTON_1|BUTTON_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

    GPIOIntTypeSet(GPIO_PORTF_BASE, BUTTON_1|BUTTON_2, GPIO_FALLING_EDGE); // falling edge

    IntEnable(INT_GPIOF);
    GPIOIntEnable(GPIO_PORTF_BASE, BUTTON_1|BUTTON_2);
    IntMasterEnable();


     //
    // Initialize the UART.
    //
    //SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    //SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);    
    //GPIOPinConfigure(GPIO_PA0_U0RX);
    //GPIOPinConfigure(GPIO_PA1_U0TX);
    //GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    //UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    //UARTStdioConfig(0, 115200,  16000000);


    while(1)
    {
    }
}

// startup_ewarm.c
// extern void GPIOFIntHandler(void);
//     GPIOFIntHandler,                      // GPIO Port F

해보기:


Button Debounce 와 오실로 스코프

해보기


Button Debounce 하드웨어

1uF 추가. 추가후 오실로 스코프로 관찰하기.

참고


UART

UART(Universal Asynchronous Receiver/Transmitter) 이름으로 알 수 있듯이 리시버와 트랜시버가 따로 존재하고 시간 클럭 정보가 없는 비동기식 통신 형태를 말한다.

그럼 클럭 정보 없이 데이터를 어떻게 구분할것인가 궁금할 것 이다.

시작(start bit)과 끝(stop bit) 신호가 있고 그 사이를 일정 시간으로 잘라서 데이터의 비트를 구분한다.

UART는 통신의 속도가 설정가능하고 데이터의 형식(갯수) 설정이 가능하다. UART의 종류로 TTL UART(0–5v), RS–232(+–12), RS–422, RS–485 등이 있다.

참고


UART rx/tx

UART module Control Sequence

API

.

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/uart.h"
#include "driverlib/gpio.h"

//! - UART0 peripheral
//! - GPIO Port A peripheral (for UART0 pins)
//! - UART0RX - PA0
//! - UART0TX - PA1

int main(void)
{
    char cThisChar;

    SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_16MHZ);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    // Configure the GPIO pin muxing for the UART function.
    // This is only necessary if your part supports GPIO pin function muxing.
    // Study the data sheet to see which functions are allocated per pin.
    // TODO: change this to select the port/pin you are using
    //
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);

    //
    // Since GPIO A0 and A1 are used for the UART function, they must be
    // configured for use as a peripheral function (instead of GPIO).
    // TODO: change this to match the port/pin you are using
    //
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Configure the UART for 115,200, 8-N-1 operation.
    // This function uses SysCtlClockGet() = 16000000 to get the system clock
    // frequency.  This could be also be a variable or hard coded value
    // instead of a function call.
    //
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,
                        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                         UART_CONFIG_PAR_NONE));

    //
    // Put a character to show start of example.  This will display on the
    // terminal.
    //
    UARTCharPut(UART0_BASE, '!');

    //
    // Enter a loop to read characters from the UART, and write them back
    // (echo).  When a line end is received, the loop terminates.
    //
    do
    {
        //
        // Read a character using the blocking read function.  This function
        // will not return until a character is available.
        //
        cThisChar = UARTCharGet(UART0_BASE);

        //
        // Write the same character using the blocking write function.  This
        // function will not return until there was space in the FIFO and
        // the character is written.
        //
        UARTCharPut(UART0_BASE, cThisChar);

    //
    // Stay in the loop until either a CR or LF is received.
    //
    } while((cThisChar != '\n') && (cThisChar != '\r'));

    UARTCharPut(UART0_BASE, '@');

    return(0);
}

해보기


UARTprintf 추가하기

UARTprintf 함수의 위치

C:\ti\Tivaware_C_Series_2.1.1.71\utils\uartstdio.c

Serial port setup: 11520 Baud rate

#include "driverlib/pin_map.h"
#include "driverlib/uart.h"    
#include "utils/uartstdio.h"

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);        
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200,  16000000);

UARTprintf("Hello World\n");

타이머

특정시간이 되면 인터럽트가 걸려서 인터럽트 핸들러를 실행!


타이머

Https://gist.github.com/donghee/e5ee186f833d55a5d247

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"

int main(void)
{
  unsigned long ulPeriod;
  SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
  GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

  // Init TIMER0
  SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
  TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
  ulPeriod = (SysCtlClockGet() / 10) / 2;
  TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod -1);

  // Interrupt Enable
  IntEnable(INT_TIMER0A);
  TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
  IntMasterEnable();
  TimerEnable(TIMER0_BASE, TIMER_A);

  while(1)
  {
  }
}

void Timer0IntHandler(void)
{
  // Clear the timer interrupt
  TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
  // Read the current state of the GPIO pin and
  // write back the opposite state
  if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))
  {
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, ~GPIO_PIN_2);
  }
  else
  {
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);
  }
}

startup.c에 이벤트 핸들러 등록!

수정할 내용

IntDefaultHandler,                      // Timer 0 subtimer A

를 Timer0IntHandler, 로 수정

extern void __iar_program_start(void);

아래에 extern void Timer0IntHandler(void); 추가

참고: Tiva LaunchPad Workbook

PWM 발생

아날로그 신호를 디지털로 인코딩(?) 하는 방식. 아날로그 신호를 신호의 duty cycle에 모듈레이션 한다.

스위치 파워서플라이, 모터제어, 서보제어, LED제어등에 사용한다.

Timer로 PWM 만들기

기본 타이머 세팅.

SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
//TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM);

ulPeriod = 1000; 
TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod - 1);
//TimerMatchSet(TIMER0_BASE, TIMER_A, dutyCycle); // PWM: dutyCycle is low level width (off dutyCycle)

TimerEnable(TIMER0_BASE, TIMER_A);

PB6 포트에 PWM 세팅하기

필요한 헤더:

#include "driverlib/timer.h"
#include "driverlib/pin_map.h"

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB) ;
GPIOPinConfigure(GPIO_PB6_T0CCP0); // mux T0CCP0 to PB6
GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_6); //to set PB6 pin

타이머 세팅

SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM);
TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod -1);
TimerMatchSet(TIMER0_BASE, TIMER_A, dutyCycle); // PWM: dutyCycle is low level width (off dutyCycle)
TimerEnable(TIMER0_BASE, TIMER_A);

PWM

코드


PWM 실습

해보기

힌트

ulPeriod = 10000;  
dutyCycle = 5000; // 50% duty cycle in buzzer 


PWM API

PWMGenConfigure(PWM_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
PWMGenPeriodSet(PWM_BASE, PWM_GEN_0, 400);
PWMPulseWidthSet(PWM_BASE, PWM_OUT_0, 100);
PWMGenEnable(PWM_BASE, PWM_GEN_0);
PWMOutputState(PWM_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT), true);

System tick

간단한 타이머. 카운팅을 하는 용도.

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"

#include "driverlib/systick.h"

volatile unsigned long sysTickUptime=0;

void SysTick_Handler(void)
{
    sysTickUptime++;
}

unsigned long millis()
{
    return sysTickUptime;   
}

int main(void) {
  SysTickPeriodSet(SysCtlClockGet()/1000); //set to 1kHZ
  SysTickIntRegister(SysTick_Handler);
  SysTickIntEnable();
  SysTickEnable();

  while(1) {}
}

System tick을 사용하여 메인 시간을 관리 해보자

해보기

코드


미션!