본문 바로가기
임베디드 개발/TMS320F2838x (C28x)

TMS320F28388D ] External Interrupt 외부 인터럽트

by eteo 2022. 9. 8.

 

 

 

데이터 시트 116페이지에 나와있듯이 외부 인터럽트는 5개 까지 지원된다.

 

 

 

 

syscfg 설정

 

LED GPIO Output 설정

 

 

버튼 GPIO Input 설정

 

 

참고로 Qualification Mode는 디폴트가 Synchronization to SYSCLKOUT Only 이다. 그냥 단순히 SYSCLK에 동기화해서 들어오는 신호를 입력받겠다는 것이다.

 

 

여기서

Input Qualification 이란

(Technical Reference Guide 1639페이지 부터)

 

 

디지털 신호는 일반적으로 아날로그 신호보다 노이즈에 대한 내성이 더 강하므로 왜곡이 거의 없다고 볼 수 있는데 위의 그림처럼 (A)와 같은 노이즈가 발생하면 매우 곤란하다. 

 

이런 경우에 Input Qualification 이 쓰일 수 있다. 입력 신호의 길이를 감지하여 기준에 미치지 못하면 무시하는 것을 코드가 아니라 회로를 구현한 것이다.

 

좀 더 구체적으로는 샘플링 횟수를 3회 또는 6회로 설정할 수 있는데 위 그림은 6회로 설정한 예시이다. 처음 6번 샘플링한 값이 0으로 동일하기 때문에 결과가 MCU로 전달될 테지만, 그 다음 신호는 6번 샘플링한 결과가 동일하지 않기 때문에 노이즈 (A)는 무시되고 Input Signal은 이전값으로 유지될 것이다.

 

다만 샘플링 시간만큼 입력 신호가 지연되는 것은 어쩔 수 없기 때문에 이를 고려해 사용을 결정하면 된다.

 

아래참조.

 

 

 

그리고 매뉴얼에도 나와있지만 또 하나 주의해야할 것은 코어가 여러개인 상황일 때이다. CPU1이 다른 코어에게 GPIO핀을 할당해줘야하는데 해당 핀을 통신 용도로 쓴다면 이 Qualification Mode를 Asynchronous 로 설정해 주어야 할 것이다.

 

 

 

 

 

버튼을 눌러 LED를 토글시키기

#include "driverlib.h"
#include "device.h"
#include "board.h"

//
// Interrupt Handler
//
__interrupt void gpioInterruptHandler(void);

//
// Main
//
void main(void)
{

    //
    // Initializes system control, device clock, and peripherals
    //
    Device_init();

    //
    // Initializes PIE and clear PIE registers. Disables CPU interrupts.
    // and clear all CPU interrupt flags.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    GPIO_setInterruptType(GPIO_INT_XINT1, GPIO_INT_TYPE_FALLING_EDGE);
    GPIO_setInterruptPin(myBUTTON, GPIO_INT_XINT1);
    GPIO_enableInterrupt(GPIO_INT_XINT1);

    Interrupt_register(INT_XINT1, &gpioInterruptHandler);
    Interrupt_enable(INT_XINT1);

    //
    // Board Initialization
    //
    Board_init();

    //
    // Enables CPU interrupts
    //
    Interrupt_enableMaster();

    //
    // Loop.
    //
    for(;;)
    {
        GPIO_togglePin(greenLED);
        DEVICE_DELAY_US(1000000);
    }
}

__interrupt void gpioInterruptHandler(void)
{
    GPIO_togglePin(myLED);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}

 

참고로 Interrupt_register() 함수를 호출할 때는 두번째 매개변수로 핸들러 함수명 앞에 & 를 붙이든 안붙이든 함수의 주소가 전달되는 것은 똑같다. 근데 예제를 보면 앞에 &를 붙이는 게 표준인 것같다.

Interrupt_register(INT_XINT1, &gpioInterruptHandler);
Interrupt_register(INT_XINT1, gpioInterruptHandler);