JINTBEAT Design Life

ARM cortex-M3 ISR(Interrupt Service Routine) 구현 Code 예제 본문

🖥️ - ARM

ARM cortex-M3 ISR(Interrupt Service Routine) 구현 Code 예제

jintbeat_design 2025. 7. 22. 23:54
반응형

구현 코드는 다음을 포함하고 있다.
 
- tick 기반 delay 함수
- 타이머 2개를 이용한 ping-pong 인터럽트 구조
- 전체 main.c 구조(초기화부터 ISR까지)
 

#include <stdint.h>
#include "DTM.h"       // DTIMER0, DTIMER1 레지스터 정의
#include "core_cm3.h"  // CMSIS: NVIC 함수 포함

//----------------------
// 전역 변수
//----------------------
volatile uint32_t tick = 0;
volatile uint8_t toggle = 0;

//----------------------
// SysTick 방식 delay
//----------------------
void delay_tick(uint32_t ms) {
    uint32_t start = tick;
    while ((tick - start) < ms);
}

//----------------------
// 타이머 초기화 함수
//----------------------
void DTM_Timer_Init(volatile DTM_TypeDef* timer, uint32_t load_value) {
    timer->LOAD = load_value;

    timer->CONTROL =
        (1 << 7) |  // Enable
        (1 << 6) |  // Periodic
        (1 << 5) |  // Interrupt Enable
        (0 << 2) |  // Prescaler /1
        (1 << 1);   // 32-bit
}

//----------------------
// NVIC 설정
//----------------------
void NVIC_Init(void) {
    NVIC_SetPriority(TIMER0_IRQn, 2);
    NVIC_EnableIRQ(TIMER0_IRQn);

    NVIC_SetPriority(TIMER1_IRQn, 2);
    NVIC_EnableIRQ(TIMER1_IRQn);
}

//----------------------
// ISR - 타이머0
//----------------------
void TIMER0_IRQHandler(void) {
    if (DTIMER0->MIS & 0x1) {
        DTIMER0->ICR = 0x1;

        tick++;  // 시간 흐름용

        toggle = 0;  // Ping 역할 수행
    }
}

//----------------------
// ISR - 타이머1
//----------------------
void TIMER1_IRQHandler(void) {
    if (DTIMER1->MIS & 0x1) {
        DTIMER1->ICR = 0x1;

        toggle = 1;  // Pong 역할 수행
    }
}

//----------------------
// 메인 함수
//----------------------
int main(void) {
    // 1. 타이머 초기화
    DTM_Timer_Init(DTIMER0, 50000);  // 1ms 간격 (50MHz 기준)
    DTM_Timer_Init(DTIMER1, 5000000); // 100ms 간격

    // 2. NVIC 설정
    NVIC_Init();

    // 3. 메인 루프
    while (1) {
        if (toggle == 0) {
            // Ping 타이머가 인터럽트 발생
            // 여기에 LED1 토글 또는 상태 갱신 가능
        }
        else if (toggle == 1) {
            // Pong 타이머가 인터럽트 발생
            // 여기에 LED2 토글 또는 데이터 처리 가능
        }

        // Delay 없이도 동작 가능하지만, 테스트용 delay 삽입 가능
        delay_tick(1);  // 1ms blocking delay
    }
}

 

DTM.h

 

#ifndef DTM_H
#define DTM_H

#include <stdint.h>

typedef struct {
    volatile uint32_t LOAD;
    volatile uint32_t VALUE;
    volatile uint32_t CONTROL;
    volatile uint32_t ICR;
    volatile uint32_t RIS;
    volatile uint32_t MIS;
    volatile uint32_t BGLOAD;
} DTM_TypeDef;

// 하드웨어 IP base 주소에 맞게 수정
#define DTIMER0_BASE   (0x40000000UL)
#define DTIMER1_BASE   (0x40001000UL)

#define DTIMER0        ((DTM_TypeDef *) DTIMER0_BASE)
#define DTIMER1        ((DTM_TypeDef *) DTIMER1_BASE)

// IRQ 번호는 실제 시스템에 맞게 지정
#define TIMER0_IRQn    (18)
#define TIMER1_IRQn    (19)

#endif

 

동작 요약

 

  • Timer0 : 주기는 1ms이고, tick++ 증가용(delay, 시간 측정) + ping 상태
  • Timer1 : 주기는 100ms이고, toggle=1 + pong 역할 수행
반응형