TI의 TMS320F28377D는 C2000 Delfino 시리즈의 32비트 마이크로컨트롤러로, 외부 메모리 인터페이스(EMIF, External Memory Interface)를 통해 SRAM, NOR Flash, SDRAM, 그리고 외부 ADC/DAC 같은 병렬 인터페이스 장치와 고속으로 통신할 수 있습니다. EMIF 모듈은 고속 데이터 전송, 외부 장치 연결, 메모리 매핑 등을 지원하며, 모터 제어, 데이터 로깅, 대용량 데이터 처리, 아날로그-디지털 변환 애플리케이션에 적합합니다. 이 문서에서는 TMS320F28377D EMIF 모듈의 상세 설정 방법, Bitfield 구조를 활용한 레지스터 설정, 그리고 실용적인 예제 코드를 제공하여 초보자와 숙련된 개발자 모두 쉽게 활용할 수 있도록 돕겠습니다. 모든 예제는 Code Composer Studio(CCS)와 C2000Ware 환경에서 실행 가능합니다.
1. TMS320F28377D EMIF 모듈 개요
TMS320F28377D는 두 개의 EMIF 모듈(EMIF1, EMIF2)을 제공하며, 각각 독립적으로 외부 메모리 또는 병렬 인터페이스 장치와 인터페이스를 구성할 수 있습니다. 아래는 주요 사양입니다:
- 지원 장치 유형:
- 비동기 메모리(SRAM, NOR Flash)
- 동기 메모리(SDRAM)
- 병렬 인터페이스 장치(ADC, DAC, FPGA 등)
- 주요 기능:
- 16비트/32비트 데이터 버스
- 최대 256MB 주소 공간(EMIF1), 2MB 주소 공간(EMIF2)
- 프로그래밍 가능한 타이밍 파라미터
- 인터럽트 지원
- DMA(Direct Memory Access) 지원
- 클럭 소스: 시스템 클럭(SYSCLK, 최대 200MHz)
- 핀 구성:
- EMIF1:
- 데이터: EM1D[31:0]
- 주소: EM1A[21:0]
- 뱅크 주소: EM1BA[1:0] (SDRAM에서 뱅크 선택용)
- 제어 신호: EM1CS[4:2], EM1WE, EM1OE, EM1SDCE, EM1CAS, EM1RAS
- EMIF2:
- 데이터: EM2D[15:0]
- 주소: EM2A[11:0]
- 뱅크 주소: EM2BA[1:0] (SDRAM에서 뱅크 선택용)
- 제어 신호: EM2CS[0], EM2WE, EM2OE
- EMIF1:
- EMIF_BA[1:0] 역할:
- EMIF_BA[1:0]은 SDRAM의 내부 뱅크를 선택하기 위해 사용됩니다.
- SDRAM은 일반적으로 2개 또는 4개의 내부 뱅크를 가지며, EMIF_BA[1:0]는 액세스할 뱅크를 지정하여 병렬 처리 및 성능 최적화를 지원합니다.
- 예: 4뱅크 SDRAM의 경우, EM1BA[1:0] 또는 EM2BA[1:0]는 00, 01, 10, 11 값을 통해 각 뱅크를 선택합니다.
- 비동기 메모리(SRAM, NOR Flash) 또는 병렬 ADC/DAC 인터페이스에서는 일반적으로 사용되지 않으며, SDRAM 전용 신호로 간주됩니다.
- GPIO 매핑 예: EM1BA0 (GPIO36), EM1BA1 (GPIO37), EM2BA0 (GPIO29), EM2BA1 (GPIO30).
- 주요 레지스터:
- RCSR: 리비전 및 모듈 제어
- ASYNC_CSx_CTRL: 비동기 칩 선택 제어
- SDRAM_CR: SDRAM 제어
- SDRAM_TR: SDRAM 타이밍
- INT_EN: 인터럽트 활성화
2. EMIF Bitfield 설정 상세
TMS320F28377D의 EMIF 레지스터는 Bitfield 구조로 정의되어 있으며, F2837xD_emif.h 헤더 파일을 통해 접근합니다. Bitfield는 레지스터의 개별 비트를 명확히 설정하여 코드 가독성과 유지보수성을 높입니다. 주요 레지스터와 Bitfield는 다음과 같습니다:
2.1 RCSR (리비전 및 제어 레지스터)
- bit.MODULE_ID: 모듈 식별자 (읽기 전용)
- bit.MAJOR_REVISION: 메이저 리비전 번호
- bit.MINOR_REVISION: 마이너 리비전 번호
2.2 ASYNC_CSx_CTRL (비동기 칩 선택 제어 레지스터, x=2,3,4)
- bit.CS_EN: 칩 선택 활성화 (1: 활성화)
- bit.ASIZE: 주소 크기 (0: 32비트, 1: 16비트, 2: 8비트)
- bit.W_SETUP/W_STROBE/W_HOLD: 쓰기 동작 타이밍
- bit.R_SETUP/R_STROBE/R_HOLD: 읽기 동작 타이밍
- bit.TURN_AROUND: 턴어라운드 시간
2.3 SDRAM_CR (SDRAM 제어 레지스터)
- bit.SD_EN: SDRAM 활성화 (1: 활성화)
- bit.BANK_SIZE: 뱅크 크기 (0: 4뱅크, 1: 2뱅크, EMIF_BA[1:0]와 연계)
- bit.PAGE_SIZE: 페이지 크기 (0: 256워드, 1: 512워드, 2: 1024워드)
- bit.CL: CAS 지연 시간 (2: CL=2, 3: CL=3)
- bit.IBANK: 내부 뱅크 구조
2.4 SDRAM_TR (SDRAM 타이밍 레지스터)
- bit.T_RFC: 자동 리프레시 주기
- bit.T_RP: 로우 프리차지 시간
- bit.T_RCD: 로우 활성화에서 컬럼 액세스 시간
- bit.T_WR: 쓰기 복구 시간
- bit.T_RAS: 로우 활성화 시간
- bit.T_RC: 로우 사이클 시간
2.5 INT_EN (인터럽트 활성화 레지스터)
- bit.WR_INT_EN: 쓰기 인터럽트 활성화
- bit.LT_INT_EN: 라인 트랩 인터럽트 활성화
- bit.AT_INT_EN: 비동기 타임아웃 인터럽트 활성화
Bitfield 사용 이점:
- 명확한 비트 단위 설정으로 실수 감소
- 코드 가독성 및 유지보수성 향상
- F2837xD_emif.h에서 제공하는 구조체로 직관적 접근
3. EMIF 설정 절차
EMIF 모듈을 효과적으로 설정하려면 다음 단계를 따라야 합니다:
- 시스템 초기화:
- InitSysCtrl()를 호출하여 시스템 클럭과 PLL을 초기화합니다.
- 인터럽트를 비활성화하고 PIE(Peripheral Interrupt Expansion)를 초기화합니다 (DINT, InitPieCtrl, InitPieVectTable).
- EMIF 클럭 활성화:
- CpuSysRegs.PCLKCR8.bit.EMIF1 또는 CpuSysRegs.PCLKCR8.bit.EMIF2를 설정하여 EMIF 모듈 클럭 활성화.
- 보호된 레지스터 접근을 위해 EALLOW와 EDIS 사용.
- GPIO 설정:
- EMIF 핀을 적절한 기능(EMIF1/EMIF2)으로 설정 (예: GpioCtrlRegs.GPAMUXx.bit.GPIOx).
- 데이터, 주소, 제어 신호, 그리고 SDRAM 사용 시 EMIF_BA[1:0] 핀을 모두 매핑.
- 병렬 ADC/DAC의 경우, 칩 선택(CS)과 읽기/쓰기 신호(EMxWE, EMxOE)를 활용하여 데이터 전송 제어.
- 비동기 메모리 또는 장치 설정 (SRAM/NOR Flash/ADC/DAC):
- ASYNC_CSx_CTRL로 칩 선택 활성화 및 타이밍 설정.
- 읽기/쓰기 타이밍 파라미터(W_SETUP, W_STROBE, R_SETUP, R_STROBE 등) 설정.
- SDRAM 설정 (필요 시):
- SDRAM_CR로 SDRAM 활성화, 뱅크 크기(EMIF_BA[1:0]와 연계), 페이지 크기, CAS 지연 설정.
- SDRAM_TR로 타이밍 파라미터 설정.
- 초기화 시퀀스 수행 (예: 리프레시 주기 설정).
- 인터럽트 설정 (필요 시):
- INT_EN으로 원하는 인터럽트 활성화.
- PIE 벡터 테이블에 인터럽트 서비스 루틴(ISR) 등록.
- 모듈 실행:
- 메모리 또는 장치 테스트를 통해 설정 확인.
- 외부 메모리 읽기/쓰기 또는 ADC/DAC 데이터 전송 수행.
4. EMIF 설정 고려사항
- 클럭 설정: SYSCLK(200MHz)에서 EMIF 동작 클럭 확인.
- 타이밍 계산: 외부 메모리 또는 장치(ADC/DAC 포함)의 데이터시트를 참조하여 읽기/쓰기 타이밍 설정.
- 핀 멀티플렉싱: EMIF 핀(특히 EMIF_BA[1:0])과 다른 기능(GPIO, ePWM 등) 간 충돌 방지.
- SDRAM 초기화: 리프레시 주기와 타이밍 파라미터를 정확히 설정, EMIF_BA[1:0] 핀 매핑 확인.
- ADC/DAC 인터페이스: 병렬 ADC/DAC의 데이터시트에 따라 칩 선택 및 타이밍 설정, 데이터 버스 폭 확인.
- 인터럽트: 비동기 타임아웃, 라인 트랩 등 오류 처리용 인터럽트 활용.
- 메모리 매핑: EMIF1(0x08000000
0x0FFFFFFF), EMIF2(0x001000000x0013FFFF) 주소 공간 확인.
5. 실용적인 EMIF 예제 코드 (Bitfield 구조)
아래는 TMS320F28377D EMIF 모듈을 Bitfield 구조로 설정한 7개의 실용적인 예제 코드입니다.
5.1 예제 1: 비동기 SRAM 읽기/쓰기
// File: emif_async_sram.c
// Description: TMS320F28377D EMIF 비동기 SRAM 읽기/쓰기 예제 (Bitfield 구조)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D
#include "F28x_Project.h"
#define SRAM_BASE 0x08000000 // EMIF1 CS2 메모리 주소
void main(void) {
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 초기화
IER = 0x0000; // CPU 인터럽트 비활성화
IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
InitPieVectTable(); // PIE 벡터 테이블 초기화
// GPIO 설정 (EMIF1 CS2, 데이터, 주소, 제어 신호)
EALLOW;
// 칩 선택
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 2; // EM1CS2
// 데이터 (EM1D0~EM1D15, 16비트 버스)
GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 2; // EM1D0
GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 2; // EM1D1
GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 2; // EM1D2
GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 2; // EM1D3
GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 2; // EM1D4
GpioCtrlRegs.GPBMUX1.bit.GPIO45 = 2; // EM1D5
GpioCtrlRegs.GPBMUX1.bit.GPIO46 = 2; // EM1D6
GpioCtrlRegs.GPBMUX1.bit.GPIO47 = 2; // EM1D7
GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 2; // EM1D8
GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 2; // EM1D9
GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 2; // EM1D10
GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 2; // EM1D11
GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 2; // EM1D12
GpioCtrlRegs.GPCMUX1.bit.GPIO69 = 2; // EM1D13
GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 2; // EM1D14
GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 2; // EM1D15
// 주소 (EM1A0~EM1A11, 예시로 12비트 주소 사용)
GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 2; // EM1A0
GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 2; // EM1A1
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 2; // EM1A2
GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 2; // EM1A3
GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 2; // EM1A4
GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 2; // EM1A5
GpioCtrlRegs.GPCMUX2.bit.GPIO72 = 2; // EM1A6
GpioCtrlRegs.GPCMUX2.bit.GPIO73 = 2; // EM1A7
GpioCtrlRegs.GPCMUX2.bit.GPIO74 = 2; // EM1A8
GpioCtrlRegs.GPCMUX2.bit.GPIO75 = 2; // EM1A9
GpioCtrlRegs.GPCMUX2.bit.GPIO76 = 2; // EM1A10
GpioCtrlRegs.GPCMUX2.bit.GPIO77 = 2; // EM1A11
// 제어 신호
GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 2; // EM1WE
GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 2; // EM1OE
EDIS;
// EMIF1 클럭 활성화
EALLOW;
CpuSysRegs.PCLKCR8.bit.EMIF1 = 1; // EMIF1 모듈 클럭 활성화
EDIS;
// EMIF1 CS2 설정 (비동기 SRAM)
EALLOW;
Emif1Regs.ASYNC_CS2_CTRL.bit.CS_EN = 1; // CS2 활성화
Emif1Regs.ASYNC_CS2_CTRL.bit.ASIZE = 1; // 16비트 데이터 버스
Emif1Regs.ASYNC_CS2_CTRL.bit.W_SETUP = 1; // 쓰기 설정 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.W_STROBE = 4; // 쓰기 스트로브 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.W_HOLD = 1; // 쓰기 홀드 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.R_SETUP = 1; // 읽기 설정 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.R_STROBE = 4; // 읽기 스트로브 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.R_HOLD = 1; // 읽기 홀드 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.TURN_AROUND = 1; // 턴어라운드 시간
EDIS;
// 메모리 테스트
volatile Uint16 *sram = (volatile Uint16 *)SRAM_BASE;
sram[0] = 0x1234; // 데이터 쓰기
Uint16 read_data = sram[0]; // 데이터 읽기
// LED 점등 (정상 동작 확인)
EALLOW;
GpioCtrlRegs.GPBDIR.bit.GPIO31 = 1; // GPIO31 출력(LED)
GpioDataRegs.GPBSET.bit.GPIO31 = 1; // LED 켜기
EDIS;
for(;;); // 무한 루프
}
설명:
- 기능: EMIF1 CS2를 통해 비동기 SRAM에 데이터 쓰기 및 읽기.
- 설정: 16비트 데이터 버스, 읽기/쓰기 타이밍 설정, CS2 활성화.
- GPIO:
- 칩 선택: EM1CS2 (GPIO34)
- 데이터: EM1D0
15 (GPIO4047, GPIO64~71) - 주소: EM1A0
11 (GPIO5863, GPIO72~77) - 제어: EM1WE (GPIO56), EM1OE (GPIO57)
- LED: GPIO31
- 출력: SRAM_BASE(0x08000000)에 0x1234 쓰기 및 읽기, 정상 동작 시 LED ON.
5.2 예제 2: SDRAM 초기화 및 액세스
// File: emif_sdram.c
// Description: TMS320F28377D EMIF SDRAM 초기화 및 액세스 예제 (Bitfield 구조)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D
#include "F28x_Project.h"
#define SDRAM_BASE 0x08000000 // EMIF1 SDRAM 메모리 주소
void main(void) {
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 초기화
IER = 0x0000; // CPU 인터럽트 비활성화
IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
InitPieVectTable(); // PIE 벡터 테이블 초기화
// GPIO 설정 (EMIF1 SDRAM, 데이터, 주소, 뱅크, 제어 신호)
EALLOW;
// SDRAM 제어
GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 2; // EM1SDCE
GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 2; // EM1CAS
GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 2; // EM1RAS
// 뱅크 주소
GpioCtrlRegs.GPBMUX1.bit.GPIO36 = 2; // EM1BA0
GpioCtrlRegs.GPBMUX1.bit.GPIO37 = 2; // EM1BA1
// 데이터 (EM1D0~EM1D15, 16비트 버스)
GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 2; // EM1D0
GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 2; // EM1D1
GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 2; // EM1D2
GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 2; // EM1D3
GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 2; // EM1D4
GpioCtrlRegs.GPBMUX1.bit.GPIO45 = 2; // EM1D5
GpioCtrlRegs.GPBMUX1.bit.GPIO46 = 2; // EM1D6
GpioCtrlRegs.GPBMUX1.bit.GPIO47 = 2; // EM1D7
GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 2; // EM1D8
GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 2; // EM1D9
GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 2; // EM1D10
GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 2; // EM1D11
GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 2; // EM1D12
GpioCtrlRegs.GPCMUX1.bit.GPIO69 = 2; // EM1D13
GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 2; // EM1D14
GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 2; // EM1D15
// 주소 (EM1A0~EM1A11, 예시로 12비트 주소 사용)
GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 2; // EM1A0
GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 2; // EM1A1
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 2; // EM1A2
GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 2; // EM1A3
GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 2; // EM1A4
GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 2; // EM1A5
GpioCtrlRegs.GPCMUX2.bit.GPIO72 = 2; // EM1A6
GpioCtrlRegs.GPCMUX2.bit.GPIO73 = 2; // EM1A7
GpioCtrlRegs.GPCMUX2.bit.GPIO74 = 2; // EM1A8
GpioCtrlRegs.GPCMUX2.bit.GPIO75 = 2; // EM1A9
GpioCtrlRegs.GPCMUX2.bit.GPIO76 = 2; // EM1A10
GpioCtrlRegs.GPCMUX2.bit.GPIO77 = 2; // EM1A11
// 제어 신호
GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 2; // EM1WE
GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 2; // EM1OE
EDIS;
// EMIF1 클럭 활성화
EALLOW;
CpuSysRegs.PCLKCR8.bit.EMIF1 = 1; // EMIF1 모듈 클럭 활성화
EDIS;
// SDRAM 설정
EALLOW;
Emif1Regs.SDRAM_CR.bit.SD_EN = 1; // SDRAM 활성화
Emif1Regs.SDRAM_CR.bit.PAGE_SIZE = 1; // 512워드 페이지
Emif1Regs.SDRAM_CR.bit.BANK_SIZE = 0; // 4뱅크 (EM1BA[1:0] 사용)
Emif1Regs.SDRAM_CR.bit.CL = 3; // CAS 지연 3
Emif1Regs.SDRAM_CR.bit.IBANK = 1; // 2 내부 뱅크
// SDRAM 타이밍 설정 (200MHz SYSCLK 기준)
Emif1Regs.SDRAM_TR.bit.T_RFC = 12; // 자동 리프레시 주기 (60ns)
Emif1Regs.SDRAM_TR.bit.T_RP = 4; // 로우 프리차지 (20ns)
Emif1Regs.SDRAM_TR.bit.T_RCD = 4; // 로우 활성화에서 컬럼 액세스 (20ns)
Emif1Regs.SDRAM_TR.bit.T_WR = 2; // 쓰기 복구 (10ns)
Emif1Regs.SDRAM_TR.bit.T_RAS = 8; // 로우 활성화 (40ns)
Emif1Regs.SDRAM_TR.bit.T_RC = 14; // 로우 사이클 (70ns)
// SDRAM 리프레시 주기 설정
Emif1Regs.SDRAM_RCR.bit.REFRESH_RATE = 781; // 7.81us 리프레시 주기 (200MHz 기준)
EDIS;
// 지연 (SDRAM 초기화 완료 대기)
asm(" RPT #100 || NOP");
// 메모리 테스트
volatile Uint16 *sdram = (volatile Uint16 *)SDRAM_BASE;
sdram[0] = 0xABCD; // 데이터 쓰기
Uint16 read_data = sdram[0]; // 데이터 읽기
// LED 점등 (정상 동작 확인)
EALLOW;
GpioCtrlRegs.GPBDIR.bit.GPIO31 = 1; // GPIO31 출력(LED)
GpioDataRegs.GPBSET.bit.GPIO31 = 1; // LED 켜기
EDIS;
for(;;); // 무한 루프
}
설명:
- 기능: EMIF1을 통해 SDRAM 초기화 및 데이터 쓰기/읽기, EM1BA[1:0]로 뱅크 선택.
- 설정: 512워드 페이지, 4뱅크, CAS 지연 3, 타이밍 파라미터 설정, 7.81us 리프레시 주기.
- GPIO:
- SDRAM 제어: EM1SDCE (GPIO32), EM1CAS (GPIO33), EM1RAS (GPIO35)
- 뱅크 주소: EM1BA0 (GPIO36), EM1BA1 (GPIO37)
- 데이터: EM1D0
15 (GPIO4047, GPIO64~71) - 주소: EM1A0
11 (GPIO5863, GPIO72~77) - 제어: EM1WE (GPIO56), EM1OE (GPIO57)
- LED: GPIO31
- 출력: SDRAM_BASE(0x08000000)에 0xABCD 쓰기 및 읽기, 정상 동작 시 LED ON.
5.3 예제 3: EMIF 인터럽트 기반 데이터 전송
// File: emif_interrupt.c
// Description: TMS320F28377D EMIF 인터럽트 기반 데이터 전송 예제 (Bitfield 구조)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D
#include "F28x_Project.h"
#define SRAM_BASE 0x08000000 // EMIF1 CS2 메모리 주소
volatile Uint16 data_buffer = 0x0000;
__interrupt void emif1_isr(void)
{
// 데이터 쓰기
volatile Uint16 *sram = (volatile Uint16 *)SRAM_BASE;
data_buffer = (data_buffer == 0x5555) ? 0xAAAA : 0x5555; // 데이터 토글
sram[0] = data_buffer;
// 인터럽트 플래그 클리어
Emif1Regs.INT_CLR.bit.WR_INT = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP12;
}
void main(void) {
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 초기화
IER = 0x0000; // CPU 인터럽트 비활성화
IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
InitPieVectTable(); // PIE 벡터 테이블 초기화
// 인터럽트 벡터 설정
EALLOW;
PieVectTable.EMIF1_INT = &emif1_isr; // EMIF1 인터럽트 벡터 설정
EDIS;
// GPIO 설정 (EMIF1 CS2, 데이터, 주소, 제어 신호)
EALLOW;
// 칩 선택
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 2; // EM1CS2
// 데이터 (EM1D0~EM1D15, 16비트 버스)
GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 2; // EM1D0
GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 2; // EM1D1
GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 2; // EM1D2
GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 2; // EM1D3
GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 2; // EM1D4
GpioCtrlRegs.GPBMUX1.bit.GPIO45 = 2; // EM1D5
GpioCtrlRegs.GPBMUX1.bit.GPIO46 = 2; // EM1D6
GpioCtrlRegs.GPBMUX1.bit.GPIO47 = 2; // EM1D7
GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 2; // EM1D8
GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 2; // EM1D9
GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 2; // EM1D10
GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 2; // EM1D11
GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 2; // EM1D12
GpioCtrlRegs.GPCMUX1.bit.GPIO69 = 2; // EM1D13
GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 2; // EM1D14
GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 2; // EM1D15
// 주소 (EM1A0~EM1A11, 예시로 12비트 주소 사용)
GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 2; // EM1A0
GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 2; // EM1A1
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 2; // EM1A2
GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 2; // EM1A3
GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 2; // EM1A4
GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 2; // EM1A5
GpioCtrlRegs.GPCMUX2.bit.GPIO72 = 2; // EM1A6
GpioCtrlRegs.GPCMUX2.bit.GPIO73 = 2; // EM1A7
GpioCtrlRegs.GPCMUX2.bit.GPIO74 = 2; // EM1A8
GpioCtrlRegs.GPCMUX2.bit.GPIO75 = 2; // EM1A9
GpioCtrlRegs.GPCMUX2.bit.GPIO76 = 2; // EM1A10
GpioCtrlRegs.GPCMUX2.bit.GPIO77 = 2; // EM1A11
// 제어 신호
GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 2; // EM1WE
GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 2; // EM1OE
EDIS;
// EMIF1 클럭 활성화
EALLOW;
CpuSysRegs.PCLKCR8.bit.EMIF1 = 1; // EMIF1 모듈 클럭 활성화
EDIS;
// EMIF1 CS2 설정 (비동기 SRAM)
EALLOW;
Emif1Regs.ASYNC_CS2_CTRL.bit.CS_EN = 1; // CS2 활성화
Emif1Regs.ASYNC_CS2_CTRL.bit.ASIZE = 1; // 16비트 데이터 버스
Emif1Regs.ASYNC_CS2_CTRL.bit.W_SETUP = 1; // 쓰기 설정 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.W_STROBE = 4; // 쓰기 스트로브 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.W_HOLD = 1; // 쓰기 홀드 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.R_SETUP = 1; // 읽기 설정 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.R_STROBE = 4; // 읽기 스트로브 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.R_HOLD = 1; // 읽기 홀드 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.TURN_AROUND = 1; // 턴어라운드 시간
// 인터럽트 설정
Emif1Regs.INT_EN.bit.WR_INT_EN = 1; // 쓰기 인터럽트 활성화
PieCtrlRegs.PIEIER12.bit.INTx1 = 1; // PIE 그룹 12, EMIF1 인터럽트 활성화
IER |= M_INT12; // CPU 인터럽트 12 활성화
EDIS;
EINT; // 글로벌 인터럽트 활성화
// 초기 데이터 쓰기
volatile Uint16 *sram = (volatile Uint16 *)SRAM_BASE;
sram[0] = data_buffer;
// LED 점등 (정상 동작 확인)
EALLOW;
GpioCtrlRegs.GPBDIR.bit.GPIO31 = 1; // GPIO31 출력(LED)
GpioDataRegs.GPBSET.bit.GPIO31 = 1; // LED 켜기
EDIS;
for(;;); // 무한 루프
}
설명:
- 기능: EMIF1 CS2를 통해 비동기 SRAM에 인터럽트 기반으로 데이터(0x5555, 0xAAAA) 토글 쓰기.
- 설정: 16비트 데이터 버스, 읽기/쓰기 타이밍 설정, 쓰기 인터럽트 활성화.
- GPIO:
- 칩 선택: EM1CS2 (GPIO34)
- 데이터: EM1D0
15 (GPIO4047, GPIO64~71) - 주소: EM1A0
11 (GPIO5863, GPIO72~77) - 제어: EM1WE (GPIO56), EM1OE (GPIO57)
- LED: GPIO31
- 출력: SRAM_BASE(0x08000000)에 데이터 토글 쓰기, 정상 동작 시 LED ON.
5.4 예제 4: EMIF2 NOR Flash 읽기
// File: emif2_nor_flash.c
// Description: TMS320F28377D EMIF2 NOR Flash 읽기 예제 (Bitfield 구조)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D
#include "F28x_Project.h"
#define NOR_BASE 0x00100000 // EMIF2 CS0 메모리 주소
void main(void) {
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 초기화
IER = 0x0000; // CPU 인터럽트 비활성화
IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
InitPieVectTable(); // PIE 벡터 테이블 초기화
// GPIO 설정 (EMIF2 CS0, 데이터, 주소, 제어 신호)
EALLOW;
// 칩 선택
GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 2; // EM2CS0
// 데이터 (EM2D0~EM2D15, 16비트 버스)
GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 2; // EM2D0
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 2; // EM2D1
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 2; // EM2D2
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 2; // EM2D3
GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 2; // EM2D4
GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 2; // EM2D5
GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 2; // EM2D6
GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 2; // EM2D7
GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 2; // EM2D8
GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 2; // EM2D9
GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 2; // EM2D10
GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 2; // EM2D11
GpioCtrlRegs.GPBMUX1.bit.GPIO48 = 2; // EM2D12
GpioCtrlRegs.GPBMUX1.bit.GPIO49 = 2; // EM2D13
GpioCtrlRegs.GPBMUX1.bit.GPIO50 = 2; // EM2D14
GpioCtrlRegs.GPBMUX1.bit.GPIO51 = 2; // EM2D15
// 주소 (EM2A0~EM2A11)
GpioCtrlRegs.GPBMUX1.bit.GPIO52 = 2; // EM2A0
GpioCtrlRegs.GPBMUX1.bit.GPIO53 = 2; // EM2A1
GpioCtrlRegs.GPBMUX1.bit.GPIO54 = 2; // EM2A2
GpioCtrlRegs.GPBMUX1.bit.GPIO55 = 2; // EM2A3
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 2; // EM2A4
GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 2; // EM2A5
GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 2; // EM2A6
GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 2; // EM2A7
GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 2; // EM2A8
GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 2; // EM2A9
GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 2; // EM2A10
GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 2; // EM2A11
// 제어 신호
GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 2; // EM2WE
GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 2; // EM2OE
EDIS;
// EMIF2 클럭 활성화
EALLOW;
CpuSysRegs.PCLKCR8.bit.EMIF2 = 1; // EMIF2 모듈 클럭 활성화
EDIS;
// EMIF2 CS0 설정 (비동기 NOR Flash)
EALLOW;
Emif2Regs.ASYNC_CS0_CTRL.bit.CS_EN = 1; // CS0 활성화
Emif2Regs.ASYNC_CS0_CTRL.bit.ASIZE = 1; // 16비트 데이터 버스
Emif2Regs.ASYNC_CS0_CTRL.bit.W_SETUP = 2; // 쓰기 설정 시간
Emif2Regs.ASYNC_CS0_CTRL.bit.W_STROBE = 6; // 쓰기 스트로브 시간
Emif2Regs.ASYNC_CS0_CTRL.bit.W_HOLD = 2; // 쓰기 홀드 시간
Emif2Regs.ASYNC_CS0_CTRL.bit.R_SETUP = 2; // 읽기 설정 시간
Emif2Regs.ASYNC_CS0_CTRL.bit.R_STROBE = 6; // 읽기 스트로브 시간
Emif2Regs.ASYNC_CS0_CTRL.bit.R_HOLD = 2; // 읽기 홀드 시간
Emif2Regs.ASYNC_CS0_CTRL.bit.TURN_AROUND = 2; // 턴어라운드 시간
EDIS;
// 메모리 테스트
volatile Uint16 *nor = (volatile Uint16 *)NOR_BASE;
Uint16 read_data = nor[0]; // 데이터 읽기
// LED 점등 (정상 동작 확인)
EALLOW;
GpioCtrlRegs.GPBDIR.bit.GPIO31 = 1; // GPIO31 출력(LED)
GpioDataRegs.GPBSET.bit.GPIO31 = 1; // LED 켜기
EDIS;
for(;;); // 무한 루프
}
설명:
- 기능: EMIF2 CS0를 통해 NOR Flash에서 데이터 읽기.
- 설정: 16비트 데이터 버스, 읽기/쓰기 타이밍 설정(NOR Flash에 적합), CS0 활성화.
- GPIO:
- 칩 선택: EM2CS0 (GPIO28)
- 데이터: EM2D0
15 (GPIO1627, GPIO48~51) - 주소: EM2A0
11 (GPIO5255, GPIO60~67) - 제어: EM2WE (GPIO30), EM2OE (GPIO31)
- LED: GPIO31
- 출력: NOR_BASE(0x00100000)에서 데이터 읽기, 정상 동작 시 LED ON.
5.5 예제 5: EMIF1 DMA 데이터 전송
// File: emif_dma.c
// Description: TMS320F28377D EMIF1 DMA 데이터 전송 예제 (Bitfield 구조)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D
#include "F28x_Project.h"
#define SRAM_BASE 0x08000000 // EMIF1 CS2 메모리 주소
#define BUFFER_SIZE 16
Uint16 internal_buffer[BUFFER_SIZE] = {0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888,
0x9999, 0xAAAA, 0xBBBB, 0xCCCC, 0xDDDD, 0xEEEE, 0xFFFF, 0x0000};
void main(void) {
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 초기화
IER = 0x0000; // CPU 인터럽트 비활성화
IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
InitPieVectTable(); // PIE 벡터 테이블 초기화
// GPIO 설정 (EMIF1 CS2, 데이터, 주소, 제어 신호)
EALLOW;
// 칩 선택
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 2; // EM1CS2
// 데이터 (EM1D0~EM1D15, 16비트 버스)
GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 2; // EM1D0
GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 2; // EM1D1
GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 2; // EM1D2
GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 2; // EM1D3
GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 2; // EM1D4
GpioCtrlRegs.GPBMUX1.bit.GPIO45 = 2; // EM1D5
GpioCtrlRegs.GPBMUX1.bit.GPIO46 = 2; // EM1D6
GpioCtrlRegs.GPBMUX1.bit.GPIO47 = 2; // EM1D7
GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 2; // EM1D8
GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 2; // EM1D9
GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 2; // EM1D10
GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 2; // EM1D11
GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 2; // EM1D12
GpioCtrlRegs.GPCMUX1.bit.GPIO69 = 2; // EM1D13
GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 2; // EM1D14
GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 2; // EM1D15
// 주소 (EM1A0~EM1A11, 예시로 12비트 주소 사용)
GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 2; // EM1A0
GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 2; // EM1A1
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 2; // EM1A2
GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 2; // EM1A3
GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 2; // EM1A4
GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 2; // EM1A5
GpioCtrlRegs.GPCMUX2.bit.GPIO72 = 2; // EM1A6
GpioCtrlRegs.GPCMUX2.bit.GPIO73 = 2; // EM1A7
GpioCtrlRegs.GPCMUX2.bit.GPIO74 = 2; // EM1A8
GpioCtrlRegs.GPCMUX2.bit.GPIO75 = 2; // EM1A9
GpioCtrlRegs.GPCMUX2.bit.GPIO76 = 2; // EM1A10
GpioCtrlRegs.GPCMUX2.bit.GPIO77 = 2; // EM1A11
// 제어 신호
GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 2; // EM1WE
GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 2; // EM1OE
EDIS;
// EMIF1 클럭 활성화
EALLOW;
CpuSysRegs.PCLKCR8.bit.EMIF1 = 1; // EMIF1 모듈 클럭 활성화
EDIS;
// EMIF1 CS2 설정 (비동기 SRAM)
EALLOW;
Emif1Regs.ASYNC_CS2_CTRL.bit.CS_EN = 1; // CS2 활성화
Emif1Regs.ASYNC_CS2_CTRL.bit.ASIZE = 1; // 16비트 데이터 버스
Emif1Regs.ASYNC_CS2_CTRL.bit.W_SETUP = 1; // 쓰기 설정 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.W_STROBE = 4; // 쓰기 스트로브 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.W_HOLD = 1; // 쓰기 홀드 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.R_SETUP = 1; // 읽기 설정 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.R_STROBE = 4; // 읽기 스트로브 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.R_HOLD = 1; // 읽기 홀드 시간
Emif1Regs.ASYNC_CS2_CTRL.bit.TURN_AROUND = 1; // 턴어라운드 시간
EDIS;
// DMA 초기화
EALLOW;
CpuSysRegs.PCLKCR0.bit.DMA = 1; // DMA 클럭 활성화
EDIS;
DMAInitialize();
// DMA 채널 1 설정 (내부 메모리 -> EMIF1 SRAM)
DMACH1AddrConfig((volatile Uint16 *)SRAM_BASE, internal_buffer);
DMACH1BurstConfig(15, 1, 1); // 16워드 전송, 소스/대상 1워드 증가
DMACH1TransferConfig(0, 0, 0); // 단일 전송
DMACH1ModeConfig(DMA_EMIF1, PERINT_ENABLE, false, true, false, 0, 0, false);
StartDMACH1();
// 지연 (DMA 전송 완료 대기)
asm(" RPT #100 || NOP");
// LED 점등 (정상 동작 확인)
EALLOW;
GpioCtrlRegs.GPBDIR.bit.GPIO31 = 1; // GPIO31 출력(LED)
GpioDataRegs.GPBSET.bit.GPIO31 = 1; // LED 켜기
EDIS;
for(;;); // 무한 루프
}
설명:
- 기능: EMIF1 CS2를 통해 내부 메모리에서 SRAM으로 DMA를 사용한 데이터 전송.
- 설정: 16비트 데이터 버스, 읽기/쓰기 타이밍 설정, DMA 채널 1 설정(16워드 전송).
- GPIO:
- 칩 선택: EM1CS2 (GPIO34)
- 데이터: EM1D0
15 (GPIO4047, GPIO64~71) - 주소: EM1A0
11 (GPIO5863, GPIO72~77) - 제어: EM1WE (GPIO56), EM1OE (GPIO57)
- LED: GPIO31
- 출력: SRAM_BASE(0x08000000)에 internal_buffer 데이터 전송, 정상 동작 시 LED ON.
5.6 예제 6: 병렬 ADC 데이터 읽기
// File: emif_adc.c
// Description: TMS320F28377D EMIF 병렬 ADC 데이터 읽기 예제 (Bitfield 구조)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D
#include "F28x_Project.h"
#define ADC_BASE 0x08010000 // EMIF1 CS3 메모리 주소
#define ADC_CONTROL_ADDR 0x08010002 // ADC 제어 레지스터 주소 (예: 변환 시작)
volatile Uint16 adc_data = 0;
void main(void) {
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 초기화
IER = 0x0000; // CPU 인터럽트 비활성화
IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
InitPieVectTable(); // PIE 벡터 테이블 초기화
// GPIO 설정 (EMIF1 CS3, 데이터, 제어 신호)
EALLOW;
// 칩 선택
GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 2; // EM1CS3
// 데이터 (EM1D0~EM1D15, 16비트 ADC)
GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 2; // EM1D0
GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 2; // EM1D1
GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 2; // EM1D2
GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 2; // EM1D3
GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 2; // EM1D4
GpioCtrlRegs.GPBMUX1.bit.GPIO45 = 2; // EM1D5
GpioCtrlRegs.GPBMUX1.bit.GPIO46 = 2; // EM1D6
GpioCtrlRegs.GPBMUX1.bit.GPIO47 = 2; // EM1D7
GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 2; // EM1D8
GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 2; // EM1D9
GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 2; // EM1D10
GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 2; // EM1D11
GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 2; // EM1D12
GpioCtrlRegs.GPCMUX1.bit.GPIO69 = 2; // EM1D13
GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 2; // EM1D14
GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 2; // EM1D15
// 제어 신호
GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 2; // EM1OE (ADC 읽기)
GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 2; // EM1WE (ADC 제어 신호)
// 주소 (최소 주소 라인, 제어 레지스터 접근용)
GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 2; // EM1A0
GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 2; // EM1A1
EDIS;
// EMIF1 클럭 활성화
EALLOW;
CpuSysRegs.PCLKCR8.bit.EMIF1 = 1; // EMIF1 모듈 클럭 활성화
EDIS;
// EMIF1 CS3 설정 (비동기 ADC)
EALLOW;
Emif1Regs.ASYNC_CS3_CTRL.bit.CS_EN = 1; // CS3 활성화
Emif1Regs.ASYNC_CS3_CTRL.bit.ASIZE = 1; // 16비트 데이터 버스
Emif1Regs.ASYNC_CS3_CTRL.bit.W_SETUP = 1; // 쓰기 설정 시간
Emif1Regs.ASYNC_CS3_CTRL.bit.W_STROBE = 2; // 쓰기 스트로브 시간
Emif1Regs.ASYNC_CS3_CTRL.bit.W_HOLD = 1; // 쓰기 홀드 시간
Emif1Regs.ASYNC_CS3_CTRL.bit.R_SETUP = 1; // 읽기 설정 시간
Emif1Regs.ASYNC_CS3_CTRL.bit.R_STROBE = 2; // 읽기 스트로브 시간
Emif1Regs.ASYNC_CS3_CTRL.bit.R_HOLD = 1; // 읽기 홀드 시간
Emif1Regs.ASYNC_CS3_CTRL.bit.TURN_AROUND = 1; // 턴어라운드 시간
EDIS;
// ADC 초기화 (변환 시작)
volatile Uint16 *adc_control = (volatile Uint16 *)ADC_CONTROL_ADDR;
*adc_control = 0x0001; // 변환 시작 명령 (ADC 데이터시트 참조)
// 지연 (ADC 변환 완료 대기, 데이터시트 기준)
asm(" RPT #50 || NOP");
// ADC 데이터 읽기
volatile Uint16 *adc = (volatile Uint16 *)ADC_BASE;
adc_data = *adc; // 16비트 ADC 데이터 읽기
// LED 점등 (정상 동작 확인)
EALLOW;
GpioCtrlRegs.GPBDIR.bit.GPIO31 = 1; // GPIO31 출력(LED)
GpioDataRegs.GPBSET.bit.GPIO31 = 1; // LED 켜기
EDIS;
for(;;); // 무한 루프
}
설명:
- 기능: EMIF1 CS3를 통해 병렬 16비트 ADC에서 데이터 읽기.
- 설정: 16비트 데이터 버스, 빠른 읽기/쓰기 타이밍(ADC에 최적화), CS3 활성화.
- GPIO:
- 칩 선택: EM1CS3 (GPIO35)
- 데이터: EM1D0
15 (GPIO4047, GPIO64~71) - 주소: EM1A0
1 (GPIO5859, 제어 레지스터 접근용) - 제어: EM1WE (GPIO56, ADC 제어), EM1OE (GPIO57, 데이터 읽기)
- LED: GPIO31
- 출력: ADC_BASE(0x08010000)에서 변환된 데이터 읽기, 정상 동작 시 LED ON.
- 참고: ADC 데이터시트에 따라 제어 명령(예: 변환 시작)과 타이밍 조정 필요.
5.7 예제 7: 병렬 DAC 데이터 쓰기
// File: emif_dac.c
// Description: TMS320F28377D EMIF 병렬 DAC 데이터 쓰기 예제 (Bitfield 구조)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D
#include "F28x_Project.h"
#define DAC_BASE 0x08020000 // EMIF1 CS4 메모리 주소
#define DAC_CONTROL_ADDR 0x08020002 // DAC 제어 레지스터 주소 (예: 출력 업데이트)
void main(void) {
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 초기화
IER = 0x0000; // CPU 인터럽트 비활성화
IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
InitPieVectTable(); // PIE 벡터 테이블 초기화
// GPIO 설정 (EMIF1 CS4, 데이터, 제어 신호)
EALLOW;
// 칩 선택
GpioCtrlRegs.GPBMUX1.bit.GPIO36 = 2; // EM1CS4
// 데이터 (EM1D0~EM1D15, 16비트 DAC)
GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 2; // EM1D0
GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 2; // EM1D1
GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 2; // EM1D2
GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 2; // EM1D3
GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 2; // EM1D4
GpioCtrlRegs.GPBMUX1.bit.GPIO45 = 2; // EM1D5
GpioCtrlRegs.GPBMUX1.bit.GPIO46 = 2; // EM1D6
GpioCtrlRegs.GPBMUX1.bit.GPIO47 = 2; // EM1D7
GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 2; // EM1D8
GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 2; // EM1D9
GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 2; // EM1D10
GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 2; // EM1D11
GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 2; // EM1D12
GpioCtrlRegs.GPCMUX1.bit.GPIO69 = 2; // EM1D13
GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 2; // EM1D14
GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 2; // EM1D15
// 제어 신호
GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 2; // EM1WE (DAC 쓰기)
GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 2; // EM1OE
// 주소 (최소 주소 라인, 제어 레지스터 접근용)
GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 2; // EM1A0
GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 2; // EM1A1
EDIS;
// EMIF1 클럭 활성화
EALLOW;
CpuSysRegs.PCLKCR8.bit.EMIF1 = 1; // EMIF1 모듈 클럭 활성화
EDIS;
// EMIF1 CS4 설정 (비동기 DAC)
EALLOW;
Emif1Regs.ASYNC_CS4_CTRL.bit.CS_EN = 1; // CS4 활성화
Emif1Regs.ASYNC_CS4_CTRL.bit.ASIZE = 1; // 16비트 데이터 버스
Emif1Regs.ASYNC_CS4_CTRL.bit.W_SETUP = 1; // 쓰기 설정 시간
Emif1Regs.ASYNC_CS4_CTRL.bit.W_STROBE = 2; // 쓰기 스트로브 시간
Emif1Regs.ASYNC_CS4_CTRL.bit.W_HOLD = 1; // 쓰기 홀드 시간
Emif1Regs.ASYNC_CS4_CTRL.bit.R_SETUP = 1; // 읽기 설정 시간
Emif1Regs.ASYNC_CS4_CTRL.bit.R_STROBE = 2; // 읽기 스트로브 시간
Emif1Regs.ASYNC_CS4_CTRL.bit.R_HOLD = 1; // 읽기 홀드 시간
Emif1Regs.ASYNC_CS4_CTRL.bit.TURN_AROUND = 1; // 턴어라운드 시간
EDIS;
// DAC 데이터 쓰기
volatile Uint16 *dac = (volatile Uint16 *)DAC_BASE;
*dac = 0x7FFF; // 16비트 DAC에 중간 값 쓰기 (예: 0V~3.3V 기준)
// DAC 출력 업데이트
volatile Uint16 *dac_control = (volatile Uint16 *)DAC_CONTROL_ADDR;
*dac_control = 0x0001; // 출력 업데이트 명령 (DAC 데이터시트 참조)
// 지연 (DAC 출력 안정화 대기, 데이터시트 기준)
asm(" RPT #50 || NOP");
// LED 점등 (정상 동작 확인)
EALLOW;
GpioCtrlRegs.GPBDIR.bit.GPIO31 = 1; // GPIO31 출력(LED)
GpioDataRegs.GPBSET.bit.GPIO31 = 1; // LED 켜기
EDIS;
for(;;); // 무한 루프
}
설명:
- 기능: EMIF1 CS4를 통해 병렬 16비트 DAC에 데이터 쓰기.
- 설정: 16비트 데이터 버스, 빠른 쓰기 타이밍(DAC에 최적화), CS4 활성화.
- GPIO:
- 칩 선택: EM1CS4 (GPIO36)
- 데이터: EM1D0
15 (GPIO4047, GPIO64~71) - 주소: EM1A0
1 (GPIO5859, 제어 레지스터 접근용) - 제어: EM1WE (GPIO56, 데이터 쓰기), EM1OE (GPIO57)
- LED: GPIO31
- 출력: DAC_BASE(0x08020000)에 0x7FFF 쓰기(중간 전압 출력), 정상 동작 시 LED ON.
- 참고: DAC 데이터시트에 따라 제어 명령(예: 출력 업데이트)과 타이밍 조정 필요.
6. 사용 방법
6.1 환경 설정
- C2000Ware 설치: C:\ti\c2000\C2000Ware_x_xx_xx_xx에서 라이브러리 다운로드.
- CCS 프로젝트: TMS320F28377D 타겟으로 프로젝트 생성, F28x_Project.h 포함.
- 링커 파일: device_support\f2837xd 폴더에서 링커 파일 추가.
6.2 코드 실행
- 각 예제를 별도의 .c 파일로 저장하거나, main.c에 복사.
- 원하는 예제만 실행되도록 다른 코드 주석 처리.
6.3 하드웨어 준비
- 메모리/장치 연결: EMIF1 또는 EMIF2 핀에 SRAM, SDRAM, NOR Flash, ADC, DAC 연결. SDRAM의 경우 EMIF_BA[1:0] 핀 연결 필수.
- 타이밍 확인: 메모리 또는 장치(ADC/DAC 포함) 데이터시트에 따라 타이밍 파라미터 조정.
- LED: GPIO31에 LED 연결 (정상 동작 확인용).
- 디버깅 도구: 오실로스코프 또는 로직 분석기로 신호 확인.
6.4 디버깅
- CCS Expressions 창: Emif1Regs.ASYNC_CSx_CTRL, Emif1Regs.SDRAM_CR, Emif1Regs.SDRAM_TR, Emif2Regs.ASYNC_CS0_CTRL 확인.
- 인터럽트 상태: Emif1Regs.INT_RAW로 인터럽트 플래그 점검.
- 메모리/장치 테스트: 읽기/쓰기 데이터 일치 여부 확인.
- 문제 해결:
- 메모리/장치 액세스 실패: GPIO 설정(특히 EMIF_BA[1:0], ADC/DAC 제어), 타이밍 파라미터 확인.
- 인터럽트 미발생: INT_EN, PIEIER12, IER 설정 확인.
- DMA 전송 실패: DMA 설정(DMACH1AddrConfig, DMACH1BurstConfig) 확인.
- SDRAM 뱅크 액세스 오류: SDRAM_CR.bit.BANK_SIZE, EMIF_BA[1:0] 핀 매핑 확인.
- ADC/DAC 오류: 데이터시트 기반으로 제어 신호 및 타이밍 점검.
7. 추가 팁
- 캘리브레이션: Device_cal() 호출로 클럭 보정.
- 타이밍 최적화: 메모리 또는 장치(ADC/DAC 포함) 데이터시트 기반으로 최소 타이밍 설정.
- EMIF_BA[1:0] 확인: SDRAM 사용 시 뱅크 선택이 올바르게 매핑되었는지 확인 (예: GPIO36, GPIO37 for EM1BA[1:0]).
- ADC/DAC 설정: 장치별 데이터시트를 참조하여 제어 레지스터 명령 및 타이밍 최적화.
- C2000Ware 참고: C:\ti\c2000\C2000Ware_x_xx_xx_xx\device_support\f2837xd\examples\cpu1\emif.
- 문제 해결:
- 데이터 오류: ASIZE, PAGE_SIZE, BANK_SIZE, EMIF_BA[1:0], ADC/DAC 설정 확인.
- SDRAM 초기화 실패: SDRAM_RCR, 타이밍 설정, EMIF_BA[1:0] 핀 점검.
- ADC/DAC 동작 실패: EMIF 타이밍 및 제어 신호(EMxWE, EMxOE) 점검.
- TI 리소스: TI E2E 포럼, C2000Ware 예제.
8. 결론
이 문서는 TMS320F28377D EMIF 모듈의 설정 방법과 Bitfield 구조를 활용한 예제 코드를 제공하여, 초보자부터 숙련된 개발자까지 쉽게 활용할 수 있도록 구성했습니다. 비동기 SRAM 읽기/쓰기, SDRAM 초기화(EMIF_BA[1:0] 포함), 인터럽트 기반 데이터 전송, NOR Flash 읽기, DMA 데이터 전송, 병렬 ADC 데이터 읽기, 병렬 DAC 데이터 쓰기 예제를 통해 다양한 애플리케이션에 적용 가능합니다.
키워드: TMS320F28377D, EMIF, C2000, SRAM, SDRAM, NOR Flash, ADC, DAC, 비동기 메모리, 동기 메모리, DMA, EMIF_BA, 마이크로컨트롤러, Code Composer Studio, 인터럽트, 타이밍 설정, 메모리 매핑
'MCU > C2000' 카테고리의 다른 글
[TMS320F28377D] SPI 사용법 : Bitfield 구조 활용 예제 코드 (1) | 2025.08.18 |
---|---|
[TMS320F28377D] DMA 사용법 : Bitfield 구조 활용 예제 코드 (0) | 2025.08.18 |
[TMS320F28377D] CLA 사용법 : Bitfield 구조 활용 예제 코드 (1) | 2025.08.18 |
[TMS320F28377D] CPU1, CPU2 멀티코어 사용법 : Bitfield 구조 활용 예제 코드 (1) | 2025.08.18 |
[TMS320F28377D] eCAP 사용법 : Bitfield 구조 활용 예제 코드 (1) | 2025.08.17 |
[TMS320F28377D] eQEP 사용법 : Bitfield 구조 활용 예제 코드 (0) | 2025.08.17 |
[TMS320F28377D] ePWM 사용법 : Bitfield 구조 활용 예제 코드 (1) | 2025.08.17 |
[TMS320F28388D] CPU1, CPU2 멀티코어 사용법: DriverLib API로 멀티코어 설정 및 코드 (0) | 2025.08.17 |