1. TMS320F28377D SDFM 모듈 개요
TI의 TMS320F28377D는 C2000 Delfino 시리즈의 32비트 마이크로컨트롤러로, 고정밀 아날로그-디지털 변환을 위한 Sigma-Delta Filter Module(SDFM)을 제공합니다. SDFM은 고해상도 데이터 수집을 가능하게 하여 모터 제어, 전력 변환, 센서 인터페이스 등에 적합합니다. 이 문서에서는 SDFM 모듈의 설정 방법, Bitfield 구조를 활용한 레지스터 설정, 그리고 실용적인 예제 코드를 제공하여 초보자와 숙련된 개발자 모두가 쉽게 활용할 수 있도록 돕겠습니다.
SDFM 주요 사양
- 채널: 최대 8개 독립 SDFM 채널(SD1~SD8)
- 클럭 소스: 시스템 클럭(SYSCLK, 최대 200MHz) 또는 외부 클럭
- 해상도: 최대 24비트
- 샘플링 속도: 최대 1.28MSPS
- 필터: Sinc3, Sinc2, Sinc1, Fast-Settling
- 오버샘플링 비율(OSR): 32, 64, 128, 256
- 주요 기능:
- 고해상도 아날로그-디지털 변환
- 데이터 필터링 및 데시메이션
- 비교기 인터럽트 및 트리거
- PWM 동기화 지원
- Manchester 코딩 지원
- 인터럽트: 데이터 준비 완료, 비교기 이벤트, 에러 조건
2. SDFM Bitfield 설정 상세
SDFM 모듈의 레지스터는 F2837xD_sdfm.h에 Bitfield 구조로 정의되어 있습니다. 주요 레지스터는 다음과 같습니다:
2.1 SDMFILEN (Sigma-Delta 마스터 필터 활성화 레지스터)
- bit.MFE: 마스터 필터 활성화
- 1: 마스터 필터 활성화 (Manchester 코딩 등).
- 0: 비활성화.
- 예: Sdfm_enableMFE(SDFM1) 또는 Sdfm1Regs.SDMFILEN.bit.MFE = 1.
2.2 SDCTLPARMx (x=1~4, 채널별 제어 파라미터 레지스터)
- bit.MOD: 모듈레이터 모드
- 0: MODE_0 (일반 모드).
- 2: MODE_2 (Manchester 코딩).
- 예: Sdfm_configureInputCtrl(SDFM1, FILTER1, MODE_2)로 Manchester 모드 설정.
2.3 SDDFPARMx (x=1~4, 데이터 필터 파라미터 레지스터)
- bit.SST: Sinc 필터 타입
- 0: SincFast.
- 1: Sinc1.
- 2: Sinc2.
- 3: Sinc3.
- 예: Sdfm_configureData_filter(SDFM1, FILTER1, ..., SINC3, ...)로 Sinc3 설정.
- bit.DOSR: 데이터 오버샘플링 비율 (OSR = DOSR + 1)
- 범위: 0~
127 (OSR=1~128). - 예: DOSR=127 → OSR=128.
- 범위: 0~
- bit.FEN: 필터 활성화
- 1: 활성화.
- 0: 비활성화.
- bit.SDSYNCEN: PWM 동기화 활성화
- 1: ePWM 동기화 활성화 (예: ePWM1).
- 0: 비활성화.
- 예: Sdfm_configureExternalreset(SDFM1, FILTER_1_EXT_RESET_ENABLE, ...)로 ePWM 동기화.
2.4 SDDPARMx (x=1~4, 데이터 출력 파라미터 레지스터)
- bit.DR: 데이터 표현
- 1: 32비트.
- 0: 16비트.
- 예: Sdfm_configureData_filter(SDFM1, FILTER1, ..., DATA_32_BIT, ...)로 32비트 설정.
- bit.SH: 데이터 시프트 비트
- 범위: 0~31.
- 예: SHIFT_0_BITS로 시프트 없음.
2.5 SDCMPHx (x=1~4, 비교기 고 임계값 레지스터)
- bit.HLT: 고 임계값 (16비트)
- 데이터가 HLT를 초과하면 이벤트 발생.
- 예: Sdfm1Regs.SDCMPH1.bit.HLT = 0x7FFF로 설정.
2.6 SDCMPLx (x=1~4, 비교기 저 임계값 레지스터)
- bit.LLT: 저 임계값 (16비트)
- 데이터가 LLT 미만이면 이벤트 발생.
- 예: Sdfm1Regs.SDCMPL1.bit.LLT = 0x8000로 설정.
2.7 SDCPARMx (x=1~4, 인터럽트 제어 레지스터)
- bit.AE: 데이터 준비 인터럽트 활성화
- 1: 활성화 (데이터 준비 시 인터럽트 발생).
- 0: 비활성화.
- 예: Sdfm_configureInterrupt(SDFM1, FILTER1, ..., AE_ENABLE).
- bit.IEH: 고 임계값 인터럽트 활성화
- 1: 활성화.
- 0: 비활성화.
- bit.IEL: 저 임계값 인터럽트 활성화
- 1: 활성화.
- 0: 비활성화.
- bit.MFIE: 모듈레이터 오류 인터럽트 활성화
- 1: 활성화.
- 0: 비활성화.
3. SDFM 설정 절차
SDFM 모듈을 설정하려면 다음 단계를 따릅니다:
시스템 초기화:
- InitSysCtrl(): 시스템 클럭(200MHz) 및 PLL 초기화.
- 인터럽트 비활성화 및 PIE 초기화:
- DINT: 모든 인터럽트 비활성화.
- InitPieCtrl(): PIE(Peripheral Interrupt Expansion) 초기화.
- IER = 0x0000: CPU 인터럽트 비활성화.
- IFR = 0x0000: 대기 중인 인터럽트 플래그 지우기.
- InitPieVectTable(): 인터럽트 벡터 테이블 초기화.
SDFM 클럭 활성화:
- 클럭 활성화:
- CpuSysRegs.PCLKCR6.bit.SD1 = 1: SDFM1 모듈 클럭 활성화 (SYSCLK=200MHz).
- 보호된 레지스터 접근을 위해 EALLOW와 EDIS 사용.
- 예:
EALLOW; CpuSysRegs.PCLKCR6.bit.SD1 = 1; EDIS;
GPIO 설정:
- SDFM 데이터 및 클럭 핀 설정:
- 예: GPIO24~27을 SDFM1 채널 1, 2로 설정 (SD1_D1, SD1_C1, SD1_D2, SD1_C2).
- GPIO_SetupPinMux 사용 권장 (대신 GpioCtrlRegs.GPAMUX2 가능).
- 예:
EALLOW; GPIO_SetupPinMux(24, GPIO_MUX_CPU1, 3); // SD1_D1 GPIO_SetupPinMux(25, GPIO_MUX_CPU1, 3); // SD1_C1 EDIS;
SDFM 설정:
- 모듈 활성화:
- Sdfm_enableMFE(SDFM1) 또는 Sdfm1Regs.SDMFILEN.bit.MFE = 1로 마스터 필터 활성화.
- 필터 설정:
- Sdfm_configureInputCtrl(SDFM1, FILTER1, MODE_2): 모듈레이터 모드 (예: Manchester).
- Sdfm_configureData_filter(SDFM1, FILTER1, FILTER_ENABLE, SINC3, OSR_128, DATA_32_BIT, SHIFT_0_BITS):
- SDDFPARM1.bit.SST=3: Sinc3 필터.
- SDDFPARM1.bit.DOSR=127: OSR=128.
- SDDFPARM1.bit.FEN=1: 필터 활성화.
- SDDPARM1.bit.DR=1: 32비트 데이터.
- SDDPARM1.bit.SH=0: 시프트 없음.
비교기 설정 (필요 시):
- 임계값 설정:
- Sdfm1Regs.SDCMPH1.bit.HLT: 고 임계값 (예: 0x7FFF).
- Sdfm1Regs.SDCMPL1.bit.LLT: 저 임계값 (예: 0x8000).
- 인터럽트 활성화:
- Sdfm_configureInterrupt(SDFM1, FILTER1, IEH_ENABLE, IEL_ENABLE, ...)로 고/저 임계값 인터럽트 설정.
인터럽트 설정 (필요 시):
- 데이터 준비 인터럽트:
- Sdfm_configureInterrupt(SDFM1, FILTER1, ..., AE_ENABLE)로 SDCPARM1.bit.AE=1 설정.
- 모듈레이터 오류 인터럽트:
- Sdfm_configureInterrupt(SDFM1, FILTER1, ..., MFIE_ENABLE)로 SDCPARM1.bit.MFIE=1.
- PIE 벡터 등록:
- InitPieVectTable() 후 인터럽트 서비스 루틴(ISR) 등록.
- 예: PieVectTable.SD1_INT = &sdfm_isr;.
모듈 실행:
- PWM 동기화 (필요 시):
- Sdfm_configureExternalreset(SDFM1, FILTER_1_EXT_RESET_ENABLE, ...)로 ePWM 동기화.
- 또는 Sdfm1Regs.SDDFPARM1.bit.SDSYNCEN = 1.
- 데이터 수집 시작:
- Sdfm1Regs.SDDATA1.bit.DATA32HI로 데이터 읽기.
- 예:
if (Sdfm1Regs.SDIFLG.bit.AF1 == 1) { data = Sdfm1Regs.SDDATA1.bit.DATA32HI; Sdfm1Regs.SDIFLGCLR.bit.AF1 = 1; }
4. SDFM 설정 고려사항
- 클럭 설정: SYSCLK(200MHz)에서 SDCLK 설정 (예: 20MHz)
- OSR: 높은 OSR(예: 256)는 해상도 증가, 샘플링 속도 감소
- 필터 선택: Sinc3는 고해상도, Fast는 빠른 응답
- PWM 동기화: 다중 채널 동기화를 위해 SDDFPARM1.bit.SDSYNCEN 사용
- Manchester 코딩: 외부 Sigma-Delta 모듈 사용 시 SDCTL.bit.MFE 활성화
- 인터럽트: 실시간 데이터 처리를 위해 SDINT 설정
5. 실용적인 SDFM 예제 코드 (Bitfield 구조)
아래는 SDFM 모듈을 Bitfield 구조로 설정한 4개의 실용적인 예제 코드입니다. 각 예제는 Code Composer Studio(CCS)와 C2000Ware 환경에서 실행 가능합니다.
5.1 예제 1: 기본 SDFM 데이터 수집
/**
* main.c
* Description: TMS320F28377D SDFM 기본 데이터 수집 예제 (Bitfield 구조, F2837xD_sdfm.h 참조)
* Compiler: Code Composer Studio (TI C2000 Compiler)
* Target: TMS320F28377D
*/
#include "F28x_Project.h"
#define BLINKY_LED_GPIO 31
// GPIO 설정 함수
void setupGpio(void)
{
EALLOW;
// SDFM1 채널 1 GPIO 설정
GPIO_SetupPinMux(24, GPIO_MUX_CPU1, 3); // GPIO24를 SD1_D1로 설정
GPIO_SetupPinMux(25, GPIO_MUX_CPU1, 3); // GPIO25를 SD1_C1로 설정
// LED GPIO 설정
GPIO_SetupPinMux(BLINKY_LED_GPIO, GPIO_MUX_CPU1, 0); // GPIO31을 일반 GPIO로 설정
GPIO_SetupPinOptions(BLINKY_LED_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL);
EDIS;
}
void main(void)
{
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
InitGpio(); // 기본 GPIO 초기화
setupGpio(); // 사용자 정의 GPIO 설정
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 초기화
IER = 0x0000; // CPU 인터럽트 비활성화
IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
InitPieVectTable(); // PIE 벡터 테이블 초기화
// SDFM1 클럭 활성화
EALLOW;
CpuSysRegs.PCLKCR6.bit.SD1 = 1; // SDFM1 모듈 클럭 활성화
EDIS;
// SDFM1 설정 (Bitfield 사용, F2837xD_sdfm.h 참조)
EALLOW;
Sdfm1Regs.SDCTL.bit.MIE = 0; // 마스터 인터럽트 비활성화
Sdfm1Regs.SDMFILEN.bit.MFE = 1; // Manchester 코딩 활성화 (외부 모듈 가정)
Sdfm1Regs.SDCTLPARM1.bit.MOD = 0; // Delta-Sigma 모듈레이터 모드 (일반 모드)
Sdfm1Regs.SDDFPARM1.bit.SST = 3; // Sinc3 필터
Sdfm1Regs.SDDFPARM1.bit.DOSR = 127; // OSR = 128 (DOSR+1)
Sdfm1Regs.SDDFPARM1.bit.FEN = 1; // 필터 활성화
Sdfm1Regs.SDDFPARM1.bit.SDSYNCEN = 0; // PWM 동기화 비활성화
Sdfm1Regs.SDDFPARM1.bit.AE = 0; // Ack 비활성화
Sdfm1Regs.SDDPARM1.bit.DR = 1; // 32비트 데이터 표현
Sdfm1Regs.SDDPARM1.bit.SH = 0; // 32비트 모드에서 시프트 없음
Sdfm1Regs.SDIFLGCLR.bit.MF1 = 1; // 모듈레이터 오류 플래그 클리어
EDIS;
EINT; // 글로벌 인터럽트 활성화
ERTM; // 실시간 모드 활성화
// 데이터 저장용 변수
volatile Uint32 data = 0;
for(;;)
{
// 모듈레이터 오류 확인
if (Sdfm1Regs.SDIFLG.bit.MF1 == 1)
{
// 오류 발생 시 LED 빠르게 깜빡임
GPIO_WritePin(BLINKY_LED_GPIO, 0);
DELAY_US(1000 * 100); // 100ms
GPIO_WritePin(BLINKY_LED_GPIO, 1);
DELAY_US(1000 * 100); // 100ms
Sdfm1Regs.SDIFLGCLR.bit.MF1 = 1; // 오류 플래그 클리어
}
// 데이터 준비 확인
else if (Sdfm1Regs.SDIFLG.bit.AF1 == 1)
{
data = Sdfm1Regs.SDDATA1.bit.DATA32HI; // 32비트 데이터 읽기
Sdfm1Regs.SDIFLGCLR.bit.AF1 = 1; // Ack 플래그 클리어
GPIO_WritePin(BLINKY_LED_GPIO, 0); // LED 끄기 (데이터 수집 표시)
DELAY_US(1000 * 500); // 500ms 지연
GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
DELAY_US(1000 * 500); // 500ms 지연
}
}
}
설명:
- 기능: SDFM1 채널 1로 아날로그 데이터를 수집 (Sinc3 필터, OSR=128).
- 설정: Sinc3 필터, OSR=128, PWM 동기화 비활성화.
- GPIO: GPIO24(SD1_D1), GPIO25(SD1_C1), GPIO31(LED).
- 출력: Sdfm1Regs.SDDATA1.bit.DATA에서 데이터 읽기, 정상 동작 시 LED ON.
5.2 예제 2: 비교기 인터럽트를 사용한 임계값 감지
/**
* sdfm_comparator_interrupt.c
* Description: TMS320F28377D SDFM 비교기 인터럽트 예제 (Bitfield 구조, F2837xD_sdfm.h 참조)
* Compiler: Code Composer Studio (TI C2000 Compiler)
* Target: TMS320F28377D
*/
#include "F28x_Project.h"
#define BLINKY_LED_GPIO 31
volatile Uint16 threshold_exceeded = 0; // 임계값 초과 플래그
// SDFM1 인터럽트 서비스 루틴
__interrupt void sdfm1_isr(void)
{
threshold_exceeded = 1; // 임계값 초과 감지
GPIO_WritePin(BLINKY_LED_GPIO, !GPIO_ReadPin(BLINKY_LED_GPIO)); // LED 토글
Sdfm1Regs.SDIFLGCLR.bit.IFH1 = 1; // 높은 임계값 인터럽트 플래그 클리어
PieCtrlRegs.PIEACK.all = PIEACK_GROUP8; // PIE 그룹 8 ACK
}
// GPIO 설정 함수
void setupGpio(void)
{
EALLOW;
// SDFM1 채널 1 GPIO 설정
GPIO_SetupPinMux(24, GPIO_MUX_CPU1, 3); // GPIO24를 SD1_D1로 설정
GPIO_SetupPinMux(25, GPIO_MUX_CPU1, 3); // GPIO25를 SD1_C1로 설정
// LED GPIO 설정
GPIO_SetupPinMux(BLINKY_LED_GPIO, GPIO_MUX_CPU1, 0); // GPIO31을 일반 GPIO로 설정
GPIO_SetupPinOptions(BLINKY_LED_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL);
EDIS;
}
void main(void)
{
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭 및 PLL 초기화
InitGpio(); // 기본 GPIO 초기화
setupGpio(); // 사용자 정의 GPIO 설정
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE 초기화
IER = 0x0000; // CPU 인터럽트 비활성화
IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
InitPieVectTable(); // PIE 벡터 테이블 초기화
// 인터럽트 벡터 설정
EALLOW;
PieVectTable.SD1_INT = &sdfm1_isr; // SDFM1 인터럽트 벡터 설정
EDIS;
// SDFM1 클럭 활성화
EALLOW;
CpuSysRegs.PCLKCR6.bit.SD1 = 1; // SDFM1 모듈 클럭 활성화
EDIS;
// SDFM1 설정 (Bitfield 사용, F2837xD_sdfm.h 참조)
EALLOW;
Sdfm1Regs.SDCTL.bit.MIE = 1; // 마스터 인터럽트 활성화
Sdfm1Regs.SDMFILEN.bit.MFE = 1; // Manchester 코딩 활성화 (외부 모듈 가정)
Sdfm1Regs.SDCTLPARM1.bit.MOD = 0; // Delta-Sigma 모듈레이터 모드 (일반 모드)
Sdfm1Regs.SDDFPARM1.bit.SST = 3; // Sinc3 필터
Sdfm1Regs.SDDFPARM1.bit.DOSR = 127; // OSR = 128 (DOSR+1)
Sdfm1Regs.SDDFPARM1.bit.FEN = 1; // 필터 활성화
Sdfm1Regs.SDDFPARM1.bit.SDSYNCEN = 0; // PWM 동기화 비활성화
Sdfm1Regs.SDDFPARM1.bit.AE = 0; // Ack 비활성화
Sdfm1Regs.SDDPARM1.bit.DR = 1; // 32비트 데이터 표현
Sdfm1Regs.SDDPARM1.bit.SH = 0; // 32비트 모드에서 시프트 없음
Sdfm1Regs.SDIFLGCLR.bit.MF1 = 1; // 모듈레이터 오류 플래그 클리어
// 비교기 설정
Sdfm1Regs.SDCMPH1.bit.HLT = 0x7FFF; // 높은 임계값 (50% 최대)
Sdfm1Regs.SDCPARM1.bit.COSR = 31; // 비교기 OSR = 32 (COSR+1)
Sdfm1Regs.SDCPARM1.bit.CS1_CS0 = 3; // 비교기 Sinc3 필터
Sdfm1Regs.SDCPARM1.bit.IEH = 1; // 높은 임계값 인터럽트 활성화
EDIS;
// 인터럽트 활성화
EALLOW;
PieCtrlRegs.PIEIER8.bit.INTx1 = 1; // PIE 그룹 8, SDFM1 인터럽트 활성화
IER |= M_INT8; // CPU 인터럽트 8 활성화
EDIS;
EINT; // 글로벌 인터럽트 활성화
ERTM; // 실시간 모드 활성화
// 데이터 저장용 변수
volatile Uint32 data = 0;
for(;;)
{
// 모듈레이터 오류 확인
if (Sdfm1Regs.SDIFLG.bit.MF1 == 1)
{
// 오류 발생 시 LED 빠르게 깜빡임
GPIO_WritePin(BLINKY_LED_GPIO, 0);
DELAY_US(1000 * 100); // 100ms
GPIO_WritePin(BLINKY_LED_GPIO, 1);
DELAY_US(1000 * 100); // 100ms
Sdfm1Regs.SDIFLGCLR.bit.MF1 = 1; // 오류 플래그 클리어
}
// 데이터 준비 확인
else if (Sdfm1Regs.SDIFLG.bit.AF1 == 1)
{
data = Sdfm1Regs.SDDATA1.bit.DATA32HI; // 32비트 데이터 읽기
Sdfm1Regs.SDIFLGCLR.bit.AF1 = 1; // Ack 플래그 클리어
if (!threshold_exceeded)
{
// 임계값 미초과 시 정상 LED 깜빡임
GPIO_WritePin(BLINKY_LED_GPIO, 0);
DELAY_US(1000 * 500); // 500ms
GPIO_WritePin(BLINKY_LED_GPIO, 1);
DELAY_US(1000 * 500); // 500ms
}
}
}
}
설명:
- 기능: SDFM1 채널 1로 데이터 수집, 높은 임계값 초과 시 인터럽트 발생 및 LED 토글.
- 설정: Sinc3 필터, OSR=128, 높은 임계값 0x7FFF, 비교기 인터럽트 활성화.
- GPIO: GPIO24(SD1_D1), GPIO25(SD1_C1), GPIO31(LED).
- 출력: 데이터 초과 시 LED 토글, 정상 동작 시 데이터 읽기.
5.3 예제 3: PWM 동기화를 사용한 SDFM 데이터 수집
/**
* @file main.c
* @brief TMS320F28377D SDFM과 ePWM 동기화를 통한 데이터 수집 예제
* @details
* - SDFM1 필터1을 사용하여 Sigma-Delta 데이터를 수집하며, ePWM1과 동기화.
* - ePWM1은 100kHz, 50% 듀티 PWM 신호를 생성하여 SDFM 동기화 신호 제공.
* - GPIO31에 연결된 LED로 동작 상태 표시 (정상: 500ms 깜빡임, 오류: 100ms 깜빡임).
* - F2837xD_sdfm.h, F2837xD_sdfm_drivers.h, F2837xD_epwm.h, F2837xD_EPwm_defines.h 참조.
* - C2000Ware_6_00_00_00 기반, Code Composer Studio (TI C2000 Compiler) 사용.
* - 대상: TMS320F28377D (CPU1, RAM 기반).
*/
/* 필수 헤더 파일 포함 */
#include "F28x_Project.h" // F2837xD 기본 헤더 (SDFM, ePWM, GPIO 등 포함)
#include "F2837xD_sdfm_drivers.h" // SDFM 드라이버 함수 및 정의 (Sdfm_configureXXX, MODE_2 등)
/* 상수 정의 */
#define BLINKY_LED_GPIO 31 // LED 연결 GPIO 핀 번호 (GPIO31)
/**
* @brief GPIO 핀을 SDFM, ePWM, LED 용도로 설정
* @details
* - GPIO24: SDFM1 데이터 입력 (SD1_D1)
* - GPIO25: SDFM1 클럭 입력 (SD1_C1)
* - GPIO0: ePWM1A 출력 (PWM 신호)
* - GPIO31: LED 출력 (상태 표시)
* - EALLOW/EDIS로 보호 레지스터 접근 제어
*/
void setupGpio(void)
{
EALLOW; // 보호된 레지스터 접근 허용
// SDFM1 채널 1 GPIO 설정
GPIO_SetupPinMux(24, GPIO_MUX_CPU1, 3); // GPIO24를 SD1_D1로 설정 (SDFM 데이터 입력)
GPIO_SetupPinMux(25, GPIO_MUX_CPU1, 3); // GPIO25를 SD1_C1로 설정 (SDFM 클럭 입력)
// ePWM1 GPIO 설정
GPIO_SetupPinMux(0, GPIO_MUX_CPU1, 1); // GPIO0을 ePWM1A로 설정 (PWM 출력)
// LED GPIO 설정
GPIO_SetupPinMux(BLINKY_LED_GPIO, GPIO_MUX_CPU1, 0); // GPIO31을 일반 GPIO로 설정
GPIO_SetupPinOptions(BLINKY_LED_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL); // 출력, 푸시-풀 모드
EDIS; // 보호 레지스터 접근 비활성화
}
/**
* @brief 메인 함수 - SDFM과 ePWM을 설정하고 데이터 수집 및 상태 표시
* @details
* - 시스템, GPIO, 인터럽트 초기화
* - ePWM1(100kHz, 50% 듀티) 및 SDFM1(Sinc2, OSR=64, 32비트) 설정
* - 무한 루프에서 SDFM 데이터 수집, 오류 처리, LED 상태 표시
*/
void main(void)
{
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭(200MHz), PLL, 주변 장치 초기화
InitGpio(); // 모든 GPIO를 기본 상태로 초기화
setupGpio(); // 사용자 정의 GPIO 설정 (SDFM, ePWM, LED)
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE(Peripheral Interrupt Expansion) 초기화
IER = 0x0000; // CPU 인터럽트 비활성화
IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
InitPieVectTable(); // 인터럽트 벡터 테이블 초기화
// SDFM1 및 ePWM1 클럭 활성화
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR6.bit.SD1 = 1; // SDFM1 모듈 클럭 활성화 (SYSCLK=200MHz)
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
EDIS; // 보호 레지스터 접근 비활성화
// ePWM1 설정 (F2837xD_EPwm_defines.h 참조)
EALLOW;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 업 카운트 모드 (카운터 증가, 0b00)
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // 클럭 분주비 1/1 (SYSCLK=200MHz)
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2; // 고속 클럭 분주비 1/2 (TBCLK=100MHz)
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // 동기화 출력 = TBCTR=0 (SDFM 동기화 신호, 0b01)
EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드 (중단 없이 동작, 0b10)
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 위상 로드 비활성화 (0b0)
EPwm1Regs.TBPRD = 1000; // 주기 = 1000 TBCLK (100MHz/1000 = 100kHz PWM)
EPwm1Regs.CMPA.bit.CMPA = 500; // 50% 듀티 (CMPA = TBPRD/2, High에서 Low로 전환)
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 출력 High (0b10)
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 출력 Low (0b01)
EPwm1Regs.TBSTS.bit.SYNCI = 0; // 동기화 입력 상태 초기화
EDIS;
// SDFM1 설정 (F2837xD_sdfm.h, F2837xD_sdfm_drivers.h 참조)
EALLOW;
Sdfm_enableMFE(SDFM1); // 마스터 필터 활성화 (SDMFILEN.bit.MFE=1, Manchester 코딩)
Sdfm_configureInputCtrl(SDFM1, FILTER1, MODE_2); // 필터1, Manchester 모드 (SDCTLPARM1.bit.MOD=2)
Sdfm_configureData_filter(SDFM1, FILTER1, FILTER_ENABLE, SINC2, OSR_64, DATA_32_BIT, SHIFT_0_BITS);
// - SDDFPARM1.bit.FEN=1: 필터 활성화
// - SDDFPARM1.bit.SST=2: Sinc2 필터
// - SDDFPARM1.bit.DOSR=63: OSR=64 (DOSR+1)
// - SDDPARM1.bit.DR=1: 32비트 데이터
// - SDDPARM1.bit.SH=0: 시프트 없음
Sdfm_configureInterrupt(SDFM1, FILTER1, IEH_DISABLE, IEL_DISABLE, MFIE_DISABLE, AE_DISABLE);
// 인터럽트 비활성화 (SDCPARM1.bit.IEH, IEL, MFIE=0, SDDFPARM1.bit.AE=0)
Sdfm_configureExternalreset(SDFM1, FILTER_1_EXT_RESET_ENABLE, FILTER_2_EXT_RESET_DISABLE,
FILTER_3_EXT_RESET_DISABLE, FILTER_4_EXT_RESET_DISABLE);
// 필터1에 ePWM 동기화 활성화 (SDDFPARM1.bit.SDSYNCEN=1, ePWM1 연결)
Sdfm1Regs.SDIFLGCLR.bit.MF1 = 1; // 모듈레이터 오류 플래그 클리어 (SDIFLG.bit.MF1)
EDIS;
EINT; // 글로벌 인터럽트 활성화
ERTM; // 실시간 모드 활성화 (디버깅용)
// 데이터 저장용 변수
volatile Uint32 data = 0; // SDFM 필터1 데이터 저장 (32비트)
// 무한 루프: 데이터 수집 및 오류 처리
for(;;)
{
// 모듈레이터 오류 확인
if (Sdfm1Regs.SDIFLG.bit.MF1 == 1) // SDIFLG.bit.MF1: 필터1 모듈레이터 오류
{
// 오류 발생 시 LED 빠르게 깜빡임 (100ms)
GPIO_WritePin(BLINKY_LED_GPIO, 0); // LED 끄기
DELAY_US(1000 * 100); // 100ms 지연
GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
DELAY_US(1000 * 100); // 100ms 지연
Sdfm1Regs.SDIFLGCLR.bit.MF1 = 1; // 오류 플래그 클리어
}
// 동기화 상태 확인
else if (EPwm1Regs.TBSTS.bit.SYNCI == 1) // TBSTS.bit.SYNCI: ePWM 동기화 오류
{
// 동기화 오류 시 LED 빠르게 깜빡임 (100ms)
GPIO_WritePin(BLINKY_LED_GPIO, 0); // LED 끄기
DELAY_US(1000 * 100); // 100ms 지연
GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
DELAY_US(1000 * 100); // 100ms 지연
EPwm1Regs.TBSTS.bit.SYNCI = 0; // 동기화 플래그 클리어
}
// 데이터 준비 확인
else if (Sdfm1Regs.SDIFLG.bit.AF1 == 1) // SDIFLG.bit.AF1: 필터1 데이터 준비 완료
{
data = Sdfm1Regs.SDDATA1.bit.DATA32HI; // 32비트 데이터 읽기 (상위 16비트)
Sdfm1Regs.SDIFLGCLR.bit.AF1 = 1; // Ack 플래그 클리어
GPIO_WritePin(BLINKY_LED_GPIO, 0); // LED 끄기 (데이터 수집 표시)
DELAY_US(1000 * 500); // 500ms 지연
GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
DELAY_US(1000 * 500); // 500ms 지연
}
}
}
설명:
- 기능: SDFM1 채널 1로 ePWM1과 동기화된 데이터 수집 (Sinc2 필터, OSR=64).
- 설정: Sinc2 필터, OSR=64, ePWM1 동기화 활성화, ePWM1 100kHz PWM.
- GPIO: GPIO24(SD1_D1), GPIO25(SD1_C1), GPIO0(ePWM1A), GPIO31(LED).
- 출력: ePWM1 동기화된 데이터 읽기, 정상 동작 시 LED ON.
5.4 예제 4: 다중 SDFM 채널 설정
/**
* @file sdfm_multi_channel.c
* @brief TMS320F28377D SDFM 다중 채널(1, 2) 데이터 수집 예제
* @details
* - SDFM1 채널 1(Sinc3, OSR=128, 32비트) 및 채널 2(Sinc2, OSR=64, 32비트)를 사용하여 Sigma-Delta 데이터 수집.
* - PWM 동기화 비활성화 상태 유지 (SDDFPARM1/2.bit.SDSYNCEN=0).
* - GPIO31 LED로 상태 표시: 정상 데이터(500ms 깜빡임), 모듈레이터 오류(100ms 깜빡임).
* - F2837xD_sdfm.h, F2837xD_sdfm_drivers.h 참조.
* - C2000Ware_6_00_00_00 기반, Code Composer Studio (TI C2000 Compiler) 사용.
* - 대상: TMS320F28377D (CPU1, RAM 기반).
*/
/* 필수 헤더 파일 포함 */
#include "F28x_Project.h" // F2837xD 기본 헤더 (SDFM, GPIO 등 포함)
#include "F2837xD_sdfm_drivers.h" // SDFM 드라이버 함수 및 정의 (Sdfm_configureXXX, MODE_2 등)
/* 상수 정의 */
#define BLINKY_LED_GPIO 31 // LED 연결 GPIO 핀 번호 (GPIO31)
/**
* @brief GPIO 핀을 SDFM 및 LED 용도로 설정
* @details
* - GPIO24: SDFM1 채널 1 데이터 입력 (SD1_D1)
* - GPIO25: SDFM1 채널 1 클럭 입력 (SD1_C1)
* - GPIO26: SDFM1 채널 2 데이터 입력 (SD1_D2)
* - GPIO27: SDFM1 채널 2 클럭 입력 (SD1_C2)
* - GPIO31: LED 출력 (상태 표시)
* - EALLOW/EDIS로 보호 레지스터 접근 제어
*/
void setupGpio(void)
{
EALLOW; // 보호된 레지스터 접근 허용
// SDFM1 채널 1 GPIO 설정
GPIO_SetupPinMux(24, GPIO_MUX_CPU1, 3); // GPIO24를 SD1_D1로 설정 (데이터 입력)
GPIO_SetupPinMux(25, GPIO_MUX_CPU1, 3); // GPIO25를 SD1_C1로 설정 (클럭 입력)
// SDFM1 채널 2 GPIO 설정
GPIO_SetupPinMux(26, GPIO_MUX_CPU1, 3); // GPIO26를 SD1_D2로 설정 (데이터 입력)
GPIO_SetupPinMux(27, GPIO_MUX_CPU1, 3); // GPIO27를 SD1_C2로 설정 (클럭 입력)
// LED GPIO 설정
GPIO_SetupPinMux(BLINKY_LED_GPIO, GPIO_MUX_CPU1, 0); // GPIO31을 일반 GPIO로 설정
GPIO_SetupPinOptions(BLINKY_LED_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL); // 출력, 푸시-풀 모드
GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 초기 상태: 켜기
EDIS; // 보호 레지스터 접근 비활성화
}
/**
* @brief 메인 함수 - SDFM 다중 채널 설정, 데이터 수집 및 상태 표시
* @details
* - 시스템, GPIO, 인터럽트 초기화.
* - SDFM1 채널 1: Sinc3, OSR=128, 32비트, PWM 동기화 비활성화.
* - SDFM1 채널 2: Sinc2, OSR=64, 32비트, PWM 동기화 비활성화.
* - 무한 루프에서 데이터 수집, 모듈레이터 오류 확인, LED 상태 표시.
*/
void main(void)
{
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭(200MHz), PLL, 주변 장치 초기화
InitGpio(); // 모든 GPIO를 기본 상태로 초기화
setupGpio(); // 사용자 정의 GPIO 설정 (SDFM 채널 1,2, LED)
DINT; // 모든 인터럽트 비활성화
InitPieCtrl(); // PIE(Peripheral Interrupt Expansion) 초기화
IER = 0x0000; // CPU 인터럽트 비활성화
IFR = 0x0000; // 대기 중인 인터럽트 플래그 지우기
InitPieVectTable(); // 인터럽트 벡터 테이블 초기화
// SDFM1 클럭 활성화
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR6.bit.SD1 = 1; // SDFM1 모듈 클럭 활성화 (SYSCLK=200MHz)
EDIS; // 보호 레지스터 접근 비활성화
// SDFM1 설정 (F2837xD_sdfm.h, F2837xD_sdfm_drivers.h 참조)
EALLOW;
Sdfm_enableMFE(SDFM1); // 마스터 필터 활성화 (SDMFILEN.bit.MFE=1, Manchester 코딩)
// 채널 1 설정
Sdfm_configureInputCtrl(SDFM1, FILTER1, MODE_2); // 필터1, Manchester 모드 (SDCTLPARM1.bit.MOD=2)
Sdfm_configureData_filter(SDFM1, FILTER1, FILTER_ENABLE, SINC3, OSR_128, DATA_32_BIT, SHIFT_0_BITS);
// - SDDFPARM1.bit.FEN=1: 필터 활성화
// - SDDFPARM1.bit.SST=3: Sinc3 필터
// - SDDFPARM1.bit.DOSR=127: OSR=128 (DOSR+1)
// - SDDPARM1.bit.DR=1: 32비트 데이터
// - SDDPARM1.bit.SH=0: 시프트 없음
// - SDDFPARM1.bit.SDSYNCEN=0: PWM 동기화 비활성화 (기존 코드 유지)
Sdfm_configureInterrupt(SDFM1, FILTER1, IEH_DISABLE, IEL_DISABLE, MFIE_DISABLE, AE_DISABLE);
// 인터럽트 비활성화 (SDCPARM1.bit.IEH, IEL, MFIE=0, SDDFPARM1.bit.AE=0)
// 채널 2 설정
Sdfm_configureInputCtrl(SDFM1, FILTER2, MODE_2); // 필터2, Manchester 모드 (SDCTLPARM2.bit.MOD=2)
Sdfm_configureData_filter(SDFM1, FILTER2, FILTER_ENABLE, SINC2, OSR_64, DATA_32_BIT, SHIFT_0_BITS);
// - SDDFPARM2.bit.FEN=1: 필터 활성화
// - SDDFPARM2.bit.SST=2: Sinc2 필터
// - SDDFPARM2.bit.DOSR=63: OSR=64 (DOSR+1)
// - SDDPARM2.bit.DR=1: 32비트 데이터
// - SDDPARM2.bit.SH=0: 시프트 없음
// - SDDFPARM2.bit.SDSYNCEN=0: PWM 동기화 비활성화 (기존 코드 유지)
Sdfm_configureInterrupt(SDFM1, FILTER2, IEH_DISABLE, IEL_DISABLE, MFIE_DISABLE, AE_DISABLE);
// 인터럽트 비활성화 (SDCPARM2.bit.IEH, IEL, MFIE=0, SDDFPARM2.bit.AE=0)
Sdfm1Regs.SDIFLGCLR.bit.MF1 = 1; // 채널 1 모듈레이터 오류 플래그 클리어
Sdfm1Regs.SDIFLGCLR.bit.MF2 = 1; // 채널 2 모듈레이터 오류 플래그 클리어
EDIS;
EINT; // 글로벌 인터럽트 활성화
ERTM; // 실시간 모드 활성화 (디버깅용)
// 데이터 저장용 변수
volatile Uint32 data1 = 0; // SDFM 채널 1 데이터 저장 (32비트)
volatile Uint32 data2 = 0; // SDFM 채널 2 데이터 저장 (32비트)
// 무한 루프: 데이터 수집 및 오류 처리
for(;;)
{
// 모듈레이터 오류 확인
if (Sdfm1Regs.SDIFLG.bit.MF1 == 1 || Sdfm1Regs.SDIFLG.bit.MF2 == 1) // 채널 1, 2 모듈레이터 오류
{
// 오류 발생 시 LED 빠르게 깜빡임 (100ms)
GPIO_WritePin(BLINKY_LED_GPIO, 0); // LED 끄기
DELAY_US(1000 * 100); // 100ms 지연
GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
DELAY_US(1000 * 100); // 100ms 지연
Sdfm1Regs.SDIFLGCLR.bit.MF1 = 1; // 채널 1 오류 플래그 클리어
Sdfm1Regs.SDIFLGCLR.bit.MF2 = 1; // 채널 2 오류 플래그 클리어
}
// 데이터 준비 확인
else if (Sdfm1Regs.SDIFLG.bit.AF1 == 1 || Sdfm1Regs.SDIFLG.bit.AF2 == 1) // 채널 1, 2 데이터 준비
{
if (Sdfm1Regs.SDIFLG.bit.AF1 == 1) // 채널 1 데이터 준비
{
data1 = Sdfm1Regs.SDDATA1.bit.DATA32HI; // 채널 1 32비트 데이터 읽기 (상위 16비트)
Sdfm1Regs.SDIFLGCLR.bit.AF1 = 1; // 채널 1 Ack 플래그 클리어
}
if (Sdfm1Regs.SDIFLG.bit.AF2 == 1) // 채널 2 데이터 준비
{
data2 = Sdfm1Regs.SDDATA2.bit.DATA32HI; // 채널 2 32비트 데이터 읽기 (상위 16비트)
Sdfm1Regs.SDIFLGCLR.bit.AF2 = 1; // 채널 2 Ack 플래그 클리어
}
GPIO_WritePin(BLINKY_LED_GPIO, 0); // LED 끄기 (데이터 수집 표시)
DELAY_US(1000 * 500); // 500ms 지연
GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
DELAY_US(1000 * 500); // 500ms 지연
}
}
}
설명:
- 기능: SDFM1 채널 1(Sinc3, OSR=128)과 채널 2(Sinc2, OSR=64)로 동시 데이터 수집.
- 설정: 채널 1은 Sinc3, OSR=128; 채널 2는 Sinc2, OSR=64; PWM 동기화 비활성화.
- GPIO: GPIO24(SD1_D1), GPIO25(SD1_C1), GPIO26(SD1_D2), GPIO27(SD1_C2), GPIO31(LED).
- 출력: 두 채널 데이터 동시 읽기, 정상 동작 시 LED ON.
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 하드웨어 준비
- SDFM 입력: GPIO24(SD1_D1), GPIO25(SD1_C1), GPIO26(SD1_D2), GPIO27(SD1_C2)에 Sigma-Delta 모듈 연결
- LED: GPIO31에 LED 연결 (정상 동작 확인용)
- 외부 클럭: 필요 시 SD1_C1, SD1_C2에 외부 클럭 소스 연결
- PWM 동기화: 예제 3의 경우 GPIO0(ePWM1A)에 오실로스코프 연결
6.4 디버깅
- CCS Expressions 창: Sdfm1Regs.SDDATA1.bit.DATA, Sdfm1Regs.SDDATA2.bit.DATA로 데이터 확인
- 레지스터 점검: Sdfm1Regs.SDCTL, Sdfm1Regs.SDDFPARM1, Sdfm1Regs.SDDFPARM2 모니터링
- 인터럽트 확인: Sdfm1Regs.SDINTFLG로 이벤트 상태 점검
7. 추가 팁
- 캘리브레이션: Device_cal() 호출로 클럭 보정
- 노이즈 감소: 아날로그 입력에 저역통과 필터 사용
- C2000Ware 참고: C:\ti\c2000\C2000Ware_x_xx_xx_xx\device_support\f2837xd\examples\cpu1\sdfm
- 문제 해결:
- 데이터 오류: SDCTL.bit.SDEN, SDDFPARM1.bit.FEN 확인
- 인터럽트 실패: SDINT.bit.CMPHINTEN, SDINT.bit.DRINTEN 확인
- 동기화 문제: SDDFPARM1.bit.SDSYNCEN, SDSYNC1.bit.SDSYNCSEL 확인
- TI 리소스: TI E2E 포럼, C2000Ware 예제
8. 결론
이 문서는 TMS320F28377D SDFM 모듈의 설정 방법과 Bitfield 구조를 활용한 예제 코드를 제공하여 고해상도 아날로그-디지털 변환 애플리케이션에 쉽게 적용할 수 있도록 구성했습니다. 기본 데이터 수집, 비교기 인터럽트, PWM 동기화, 다중 채널 설정 예제를 통해 다양한 애플리케이션(모터 제어, 센서 인터페이스 등)에 활용 가능합니다.
키워드: TMS320F28377D, SDFM, C2000, Sigma-Delta, 마이크로컨트롤러, Code Composer Studio, 고해상도 ADC, Sinc 필터, 오버샘플링, PWM 동기화, Manchester 코딩
'MCU > C2000' 카테고리의 다른 글
TI C2000 DSP ePWM Module 설정 가이드 (0) | 2025.09.14 |
---|---|
TI C2000 DSP TMS320F28377D, TMS320F28379D, TMS320F28388D 비교 (2) | 2025.08.18 |
C2000 DSP CMD 파일: 상세 설명, 구조, 작성 방법 및 예제 (2) | 2025.08.18 |
TMS320F28377D DSP ePWM CMPASS 사용법: Bitfield 구조 활용 예제 코드(수정) (0) | 2025.08.18 |
TMS320F28377D DSP SPI 사용법 : Bitfield 구조 활용 예제 코드(수정) (2) | 2025.08.18 |
TMS320F28377D DSP DMA 사용법 : Bitfield 구조 활용 예제 코드(수정) (0) | 2025.08.18 |
TMS320F28377D DSP CAN 사용법 : Bitfield 구조 활용 예제 코드(수정) (0) | 2025.08.18 |
TMS320F28377D DSP EMIF 사용법 : Bitfield 구조 활용 예제 코드(수정) (1) | 2025.08.17 |