승코딩당당당
[TC275] Multi-interrupt로 LED 제어 (Blue/Red) 본문
이번 실습에서는 Infineon AURIX TC275와 Easy Module Shield v1을 이용해 하나의 ERU 모듈에서 두 개의 외부 인터럽트를 동시에 처리하는 Multi-interrupt 구성을 구현한다. P02.0과 P02.1에 연결된 두 개의 버튼을 각각 ERS2, ERS3로 매핑하고, 이를 통해 Blue LED(P10.2)와 Red LED(P10.1)의 상태를 독립적으로 토글하도록 설계했다.
ERS2 → ERU0 → ISR0는 Blue LED 토글, ERS3 → ERU1 → ISR1은 Red LED 토글을 담당하며, 두 인터럽트 소스가 서로 간섭하지 않도록 SCU_EICR, SCU_IGCR, SRC_SCU_SCU_ERU0/1 레지스터를 각각 분리해서 설정하는 것이 핵심이다.
특히 ERS3 경로에서는 OGU(Output Gating Unit)를 초기화한 후 값을 1로 세팅해 OGU1을 사용하도록 만들어야 ERS2에서 사용하는 OGU0와 겹치지 않고, 두 인터럽트가 독립적으로 동작한다는 점을 코드와 함께 확인할 수 있다.
이렇게 하지 않으면 두 개의 스위치 모두 Blue LED만 동작한다...
이를 통해 AURIX의 ERU 구조, 다중 인터럽트 라우팅, OGU 선택 방식까지 한 번에 정리하면서 실전적인 외부 인터럽트 설계 감각을 익히는 것을 목표로 한다.
아래 datasheet p.614~ 를 확인하면서 코드를 작성한다.
https://www.farnell.com/datasheets/3109944.pdf
+ 아래 인터럽트로 LED 제어하는 방법을 먼저 익힌 후 공부하면 이해가 더 쉽다.
https://xeungcoding.tistory.com/90
[TC275] ERU 인터럽트로 LED 제어 (On/Off, Toggle)
이번 포스팅에서는 Infineon AURIX TC275와 Easy Module Shield v1 환경에서 버튼 입력을 이용해 파란색 LED를 제어하는 세 가지 방법을 정리한다.먼저 가장 기본적으로, 버튼을 누르면 Blue LED가 켜지도록 GPIO
xeungcoding.tistory.com
코드
/**********************************************************************************************************************
* \file Cpu0_Main.c
* \copyright Copyright (C) Infineon Technologies AG 2019
*
* Use of this file is subject to the terms of use agreed between (i) you or the company in which ordinary course of
* business you are acting and (ii) Infineon Technologies AG or its licensees. If and as long as no such terms of use
* are agreed, use of this file is subject to following:
*
* Boost Software License - Version 1.0 - August 17th, 2003
*
* Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and
* accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute,
* and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the
* Software is furnished to do so, all subject to the following:
*
* The copyright notices in the Software and this entire statement, including the above license grant, this restriction
* and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all
* derivative works of the Software, unless such copies or derivative works are solely in the form of
* machine-executable object code generated by a source language processor.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*********************************************************************************************************************/
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#define PCn_2_IDX 19
#define P2_IDX 2
#define PCn_1_IDX 11 // P02.1
#define P1_IDX 1
#define PCn_0_IDX 3 // P02.0
#define P0_IDX 0
#define EXIS0_IDX 4
#define FEN0_IDX 8
#define REN0_IDX 9
#define EIEN0_IDX 11
#define INP0_IDX 12
#define IGP0_IDX 14
#define EXIS1_IDX 20
#define FEN1_IDX 24
#define EIEN1_IDX 27
#define INP1_IDX 28
#define IGP1_IDX 30
#define SRE_IDX 10
#define TOS_IDX 11
void initERU(void);
IFX_INTERRUPT(ISR0, 0, 0x10);
void ISR0 (void)
{
// P10_OUT.U = 0x1 << P2_IDX;
P10_OMR.U = (1 << (P2_IDX + 16)) | (1 << P2_IDX);
}
IFX_INTERRUPT(ISR1, 0, 0x20);
void ISR1 (void)
{
P10_OMR.U = (1 << (P1_IDX + 16)) | (1 << P1_IDX);
}
IfxCpu_syncEvent cpuSyncEvent = 0;
void initLED(void);
void initGPIO(void);
void core0_main(void)
{
IfxCpu_enableInterrupts();
/* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!
* Enable the watchdogs and service them periodically if it is required
*/
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());
/* Wait for CPU sync event */
IfxCpu_emitEvent(&cpuSyncEvent);
IfxCpu_waitEvent(&cpuSyncEvent, 1);
initGPIO();
initERU();
while(1)
{
}
}
void initLED(void){
P10_IOCR0.U &= ~(0x1F << PCn_2_IDX);
P10_IOCR0.U |= 0x10 << PCn_2_IDX;
}
void initGPIO(void) {
// PC2.0 button
P02_IOCR0.U &= ~(0x1F << PCn_0_IDX);
P02_IOCR0.U |= (0x02 << PCn_0_IDX);
// PC2.1 button
P02_IOCR0.U &= ~(0x1F << PCn_1_IDX);
P02_IOCR0.U |= 0x02 << PCn_1_IDX;
// PC10.2 blue led
P10_IOCR0.U &= ~(0x1F << PCn_2_IDX);
P10_IOCR0.U |= 0x10 << PCn_2_IDX;
// PC10.1 red led
P10_IOCR0.U &= ~(0x1F << PCn_1_IDX);
P10_IOCR0.U |= 0x10 << PCn_1_IDX;
}
void initERU() {
//**********ERS2 -> ERU0 -> ISR0 (Blue LED)**********
SCU_EICR1.U &= ~(0x7 << EXIS0_IDX);
SCU_EICR1.U |= 0x1 << EXIS0_IDX;
// SCU_EICR1.U &= ~(1 << FEN0_IDX); // Falling edge 끄고
// SCU_EICR1.U |= (1 << REN0_IDX); // Rising edge 켜기
SCU_EICR1.U |= 1 << FEN0_IDX;
SCU_EICR1.U |= 1 << EIEN0_IDX;
SCU_EICR1.U &= ~(0x7 << INP0_IDX);
SCU_IGCR0.U &= ~(0x4 << INP0_IDX);
SCU_IGCR0.U |= 0x1 << IGP0_IDX;
// SRC (Service Request Control) Setting
SRC_SCU_SCU_ERU0.U &= ~0xFF;
SRC_SCU_SCU_ERU0.U |= 0x10;
SRC_SCU_SCU_ERU0.U |= 1 << SRE_IDX;
SRC_SCU_SCU_ERU0.U &= ~(0x3 << TOS_IDX);
//**********ERS3 -> ERU1 -> ISR1 (Red LED)**********
SCU_EICR1.U &= ~(0x7 << EXIS1_IDX);
SCU_EICR1.U |= (0x2 << EXIS1_IDX);
SCU_EICR1.U |= 1 << FEN1_IDX;
SCU_EICR1.U |= 1 << EIEN1_IDX;
SCU_EICR1.U &= ~(0x7 << INP1_IDX); // INP1 = 0 → OGU1
SCU_EICR1.U |= 0x1 << INP1_IDX;
SCU_IGCR0.U &= ~(0x3 << IGP1_IDX);
SCU_IGCR0.U |= 0x1 << IGP1_IDX;
SRC_SCU_SCU_ERU1.U &= ~0xFF;
SRC_SCU_SCU_ERU1.U |= 0x20; // PRI = 0x20
SRC_SCU_SCU_ERU1.U |= 1 << SRE_IDX;
SRC_SCU_SCU_ERU1.U &= ~(0x3 << TOS_IDX);
}
1. 인터럽트 서비스 루틴 (ISR0, ISR1)
IFX_INTERRUPT(ISR0, 0, 0x10);
void ISR0(void) {
P10_OMR.U = (1 << (P2_IDX + 16)) | (1 << P2_IDX);
}
IFX_INTERRUPT(ISR1, 0, 0x20);
void ISR1(void) {
P10_OMR.U = (1 << (P1_IDX + 16)) | (1 << P1_IDX);
}
- IFX_INTERRUPT 매크로로 ISR0는 우선순위 0x10, ISR1은 0x20으로 등록.
- P10_OMR은 출력 토글용 레지스터:
- 하위 비트(PSx): set
- 상위 비트(PCLx): clear
- 같은 핀에 대해 PSx와 PCLx를 동시에 1로 쓰면 해당 비트가 토글된다.
- ISR0: P10.2 비트를 토글 → 파란 LED On/Off
- ISR1: P10.1 비트를 토글 → 빨간 LED On/Off
2. ERU 설정 (initERU)
// ERS2 → ERU0 → ISR0 (Blue LED)
SCU_EICR1 ... EXIS0, FEN0, EIEN0, INP0 설정
SCU_IGCR0 ... IGP0 설정
SRC_SCU_SCU_ERU0 ... 우선순위 0x10, enable, CPU0
// ERS3 → ERU1 → ISR1 (Red LED)
SCU_EICR1 ... EXIS1, FEN1, EIEN1, INP1 설정
SCU_IGCR0 ... IGP1 설정
SRC_SCU_SCU_ERU1 ... 우선순위 0x20, enable, CPU0
- EICR1(EXISx)
- 스위치가 연결된 핀(P02.0, P02.1)을 각각 ERS2, ERS3 입력으로 선택한다.
- FENx / EIENx
- 버튼을 누를 때 발생하는 엣지(falling edge) 에서 이벤트 발생 + 인터럽트 활성화.
- INPx / IGPx
- ERU 입력(ERS2, ERS3)을 출력 게이트(OGU)로 연결해서 서비스 요청을 발생시키는 경로를 만든다.
- SRC_SCU_SCU_ERUx
- 생성된 서비스 요청을 CPU0 인터럽트 소스로 등록하고,
- 각 채널을 ISR0(0x10), ISR1(0x20)과 매핑한다.
결과




'개발 > 임베디드' 카테고리의 다른 글
| [TC275] STM 인터럽트 기반 신호등 구현하기 (1) | 2026.02.23 |
|---|---|
| [TC275] 인터럽트로 LED Blinking과 멈추기 (0) | 2026.02.20 |
| [TC275] ERU 인터럽트로 LED 제어 (On/Off, Toggle) (0) | 2026.02.20 |
| [TC275] GPIO 입력으로 LED 제어 + OMR 레지스터 (2) | 2026.02.19 |
| [리눅스] 라즈베리파이 커널 모듈로 LED 제어하기 (0) | 2026.02.13 |