이 문서에서는 Texas Instruments의 TMS320F28388D 마이크로컨트롤러에서 SDFM(Sigma-Delta Filter Module) 모듈을 DriverLib API를 사용하여 설정하고 사용하는 방법을 상세히 다룹니다. C2000 시리즈의 고성능 마이크로컨트롤러인 TMS320F28388D의 SDFM 모듈을 활용하여 시그마-델타 아날로그 신호를 디지털 데이터로 변환하는 방법을 배우고, 다양한 독립적인 예제 코드를 통해 실제 구현 방법을 익힐 수 있습니다. 각 코드에는 상세한 주석이 포함되어 있으며, Code Composer Studio(CCS) 환경에서 실행 가능합니다.
1. TMS320F28388D SDFM 개요
TMS320F28388D는 Texas Instruments의 C2000 시리즈에 속하는 고성능 32비트 마이크로컨트롤러로, 최대 8개의 SDFM 채널을 제공합니다. SDFM 모듈은 시그마-델타 방식의 아날로그-디지털 변환을 지원하며, 전력 관리, 모터 제어, 센서 인터페이스 등 고해상도 데이터 처리가 필요한 실시간 애플리케이션에 최적화되어 있습니다.
SDFM 모듈의 주요 특징
- 고해상도 변환: 16비트 이상의 고해상도 디지털 데이터 출력 지원.
- 다채널 처리: 최대 8개의 독립적인 시그마-델타 채널 제공.
- 필터링 옵션: Sinc 필터(Sinc1, Sinc2, Sinc3)를 통해 다양한 필터링 설정 가능.
- 인터럽트 지원: 데이터 준비 완료, 오버플로우, 언더플로우 등 다양한 이벤트에 대한 인터럽트 처리.
- 클럭 및 동기화: 외부 또는 내부 클럭 소스를 사용하여 유연한 동기화 가능.
- DriverLib 지원: 하드웨어 레지스터를 직접 조작하는 대신 추상화된 API로 설정 간소화.
2. 주요 SDFM DriverLib API 함수
아래는 TMS320F28388D의 SDFM 모듈을 제어하기 위해 자주 사용되는 DriverLib API 함수와 그 사용 방법입니다.
2.1. SDFM 기본 설정 관련 함수
- SDFM_enableModule(base)
- 설명: SDFM 모듈을 활성화합니다.
- 매개변수: base (SDFM 모듈의 베이스 주소, 예: SDFM1_BASE).
- SDFM_disableModule(base)
- 설명: SDFM 모듈을 비활성화합니다.
- SDFM_setupModulatorClock(base, modulator, clockMode, clock)
- 설명: 모듈레이터 클럭 소스와 주파수를 설정합니다.
- 매개변수: modulator (채널 번호), clockMode (내부/외부), clock (주파수 설정).
- 사용 예: SDFM_setupModulatorClock(SDFM1_BASE, SDFM_MODULATOR_1, SDFM_MODULATOR_CLK_SYSCLK, 20);
- SDFM_selectClockSource(base, modulator, clockSource)
- 설명: 특정 모듈레이터의 클럭 소스를 선택합니다.
- 매개변수: clockSource (예: SDFM_CLK_SRC_SYSCLK).
2.2. 필터 설정 관련 함수
- SDFM_configDataFilter(base, filter, filterType, osr)
- 설명: 데이터 필터의 종류(Sinc1/2/3)와 오버샘플링 비율(OSR)을 설정합니다.
- 매개변수: filter (필터 번호, 예: SDFM_FILTER_1), filterType (Sinc1/2/3), osr (오버샘플링 비율, 1~256).
- 사용 예: SDFM_configDataFilter(SDFM1_BASE, SDFM_FILTER_1, SDFM_FILTER_SINC3, 128);
- SDFM_enableDataFilter(base, filter)
- 설명: 특정 데이터 필터를 활성화합니다.
- SDFM_disableDataFilter(base, filter)
- 설명: 특정 데이터 필터를 비활성화합니다.
2.3. 인터럽트 관련 함수
- SDFM_enableInterrupt(base, filter, interruptSource)
- 설명: 특정 필터의 인터럽트를 활성화합니다.
- 매개변수: interruptSource (예: SDFM_INT_DATA_READY).
- SDFM_clearInterruptStatus(base, filter)
- 설명: 인터럽트 플래그를 지웁니다.
- Interrupt_register(intNumber, handler)
- 설명: 인터럽트 서비스 루틴(ISR)을 등록합니다.
2.4. 데이터 읽기 관련 함수
- SDFM_getFilterData(base, filter)
- 설명: 지정된 필터의 변환된 데이터를 읽습니다.
- 반환값: 16비트 또는 32비트 필터링된 데이터.
3. SDFM 설정 및 동작 원리
- 시스템 초기화: 시스템 클럭과 GPIO 초기화(Device_init(), Device_initGPIO()), 인터럽트 모듈 초기화.
- SDFM 모듈 설정: 클럭 활성화, 모듈레이터 클럭 설정, 필터 타입 및 OSR 설정.
- 인터럽트 설정(선택): 데이터 준비 완료 인터럽트 활성화.
- GPIO 설정: SDFM 입력 핀(SD-Dx, SD-Cx) 설정.
- SDFM 활성화: 모듈 및 필터 활성화, 데이터 읽기 시작.
4. SDFM 예제 코드
아래는 독립적인 SDFM 예제 코드로, C2000Ware의 DriverLib를 기반으로 작성되었습니다. GPIO 설정은 별도의 initGPIO() 함수로 분리되어 있으며, 모든 코드는 CCS에서 바로 실행 가능합니다. 각 코드에는 상세한 주석을 추가하여 초보자도 이해할 수 있도록 했습니다.
4.1. 예제 1: 기본 SDFM 데이터 읽기
SDFM1의 채널 1을 사용하여 Sinc3 필터로 데이터를 읽습니다.
#include "driverlib.h" // C2000 DriverLib 헤더 파일 포함
#include "device.h" // 디바이스별 정의(예: TMS320F28388D) 포함
// 디버깅 및 상태 추적을 위한 전역 변수
volatile uint32_t sdfmStatus = 0; // 0: 초기화 완료, 1: SDFM 동작 중, 0xFFFF: 오류
volatile int32_t filterData = 0; // SDFM 필터에서 변환된 데이터를 저장하는 변수
// GPIO 초기화 함수
void initGPIO(void)
{
// GPIO48을 SDFM1 데이터 입력(SD1_D1)으로 설정
// SDFM 데이터 입력 핀으로 시그마-델타 데이터 스트림 수신
GPIO_setPinConfig(GPIO_48_SD1_D1);
GPIO_setDirectionMode(48, GPIO_DIR_MODE_IN); // 입력 모드로 설정
GPIO_setPadConfig(48, GPIO_PULL_UP); // 풀업 저항 활성화(외부 회로에 따라 조정 가능)
// GPIO49를 SDFM1 클럭 입력(SD1_C1)으로 설정
// SDFM 클럭 입력 핀으로 시그마-델타 모듈레이터 클럭 수신
GPIO_setPinConfig(GPIO_49_SD1_C1);
GPIO_setDirectionMode(49, GPIO_DIR_MODE_IN); // 입력 모드로 설정
GPIO_setPadConfig(49, GPIO_PULL_UP); // 풀업 저항 활성화
// GPIO31을 디버깅용 LED로 설정 (LAUNCHXL-F28379D 기준)
// 정상 동작 여부를 표시하기 위해 사용
GPIO_setPinConfig(GPIO_31_GPIO31);
GPIO_setDirectionMode(31, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
GPIO_setPadConfig(31, GPIO_PULL_UP); // 풀업 저항 활성화
GPIO_writePin(31, 0); // 초기 상태: LED OFF
}
// SDFM1 초기화 함수
void initSDFM(void)
{
// SDFM1 모듈의 클럭 활성화
// 시스템 클럭을 SDFM1 모듈에 공급하여 동작 가능 상태로 전환
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SDFM1);
// 모듈레이터 클럭 설정: 20MHz로 설정
// SDFM_MODULATOR_1(첫 번째 채널)에 시스템 클럭 기반 20MHz 클럭 설정
SDFM_setupModulatorClock(SDFM1_BASE, SDFM_MODULATOR_1, SDFM_MODULATOR_CLK_20MHZ);
// 데이터 필터 설정: Sinc3 필터, 오버샘플링 비율(OSR)=128
// Sinc3는 고해상도 변환에 적합, OSR=128은 해상도와 속도의 균형 제공
SDFM_configDataFilter(SDFM1_BASE, SDFM_FILTER_1, SDFM_FILTER_SINC3, 128);
SDFM_enableDataFilter(SDFM1_BASE, SDFM_FILTER_1); // 필터 1 활성화
// SDFM1 모듈 활성화
// 모든 설정 완료 후 모듈을 동작 상태로 전환
SDFM_enableModule(SDFM1_BASE);
// 상태 업데이트: SDFM 동작 중
sdfmStatus = 1;
}
void main(void)
{
// 시스템 클럭, 주변 장치, PLL, Watchdog 초기화
// Device_init()는 TMS320F28388D의 기본 설정을 수행
Device_init();
// GPIO 기본 초기화
// C2000Ware의 기본 GPIO 설정 초기화
Device_initGPIO();
// SDFM 관련 GPIO 설정
// SDFM 데이터 및 클럭 입력 핀과 디버깅용 LED 설정
initGPIO();
// 인터럽트 모듈 초기화
// 인터럽트 벡터 테이블과 컨트롤러 초기화 (확장성을 위해 포함)
Interrupt_initModule();
Interrupt_initVectorTable();
// 시스템 클럭 확인
// 200MHz가 아닌 경우 오류 처리
uint32_t sysClockHz = SysCtl_getClock(DEVICE_OSCSRC_FREQ);
if (sysClockHz != 200000000)
{
sdfmStatus = 0xFFFF; // 오류 상태 설정
GPIO_writePin(31, 0); // LED OFF로 오류 표시
ESTOP0; // 디버깅용 정지 (CCS에서 브레이크포인트 확인 가능)
}
// SDFM1 모듈 초기화
// 모듈레이터 클럭, 필터 설정, 모듈 활성화
initSDFM();
// 초기화 오류 확인
// 초기화 실패 시 오류 처리
if (sdfmStatus != 1)
{
sdfmStatus = 0xFFFF; // 오류 상태 설정
GPIO_writePin(31, 0); // LED OFF로 오류 표시
ESTOP0; // 디버깅용 정지
}
// 글로벌 인터럽트 활성화
// 모든 인터럽트 처리를 가능하게 함 (확장성을 위해 포함)
EINT;
// Watchdog 활성화
// 실시간 애플리케이션에서 저전력 모드 방지
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_WD);
SysCtl_serviceWatchdog();
// 무한 루프: SDFM 데이터 읽기 및 상태 표시
for(;;)
{
// SDFM 필터 1에서 변환된 데이터 읽기
// 시그마-델타 데이터 스트림을 필터링한 결과 저장
filterData = SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_1);
// 디버깅용: 상태 표시
// 정상 동작(sdfmStatus=1) 시 LED ON, 오류 시 OFF
GPIO_writePin(31, (sdfmStatus == 1) ? 1 : 0);
DEVICE_DELAY_US(1000000); // 1초 대기 (CPU 부하 감소 및 디버깅용)
}
}
설명:
- 기능: SDFM1의 채널 1을 사용하여 Sinc3 필터로 아날로그 데이터를 디지털로 변환.
- 설정: 20MHz 모듈레이터 클럭, Sinc3 필터, OSR=128.
- GPIO: GPIO48(SD1_D1), GPIO49(SD1_C1), GPIO31(LED).
- 출력: 변환된 데이터는 filterData 변수에 저장, 정상 동작 시 LED ON.
4.2. 예제 2: 인터럽트를 사용한 SDFM 데이터 읽기
SDFM1의 데이터 준비 완료 인터럽트를 사용하여 데이터를 읽습니다.
#include "driverlib.h" // C2000 DriverLib 헤더 파일 포함
#include "device.h" // 디바이스별 정의(예: TMS320F28388D) 포함
// 디버깅 및 상태 추적을 위한 전역 변수
volatile uint32_t sdfmStatus = 0; // 0: 초기화 완료, 1: SDFM 동작 중, 0xFFFF: 오류
volatile int32_t filterData = 0; // SDFM 필터에서 변환된 데이터를 저장하는 변수
// GPIO 초기화 함수
void initGPIO(void)
{
// GPIO48을 SDFM1 데이터 입력(SD1_D1)으로 설정
// 시그마-델타 데이터 스트림 입력 핀
GPIO_setPinConfig(GPIO_48_SD1_D1);
GPIO_setDirectionMode(48, GPIO_DIR_MODE_IN); // 입력 모드로 설정
GPIO_setPadConfig(48, GPIO_PULL_UP); // 풀업 저항 활성화
// GPIO49를 SDFM1 클럭 입력(SD1_C1)으로 설정
// 시그마-델타 모듈레이터 클럭 입력 핀
GPIO_setPinConfig(GPIO_49_SD1_C1);
GPIO_setDirectionMode(49, GPIO_DIR_MODE_IN); // 입력 모드로 설정
GPIO_setPadConfig(49, GPIO_PULL_UP); // 풀업 저항 활성화
// GPIO31을 디버깅용 LED로 설정
// 정상 동작 여부를 표시
GPIO_setPinConfig(GPIO_31_GPIO31);
GPIO_setDirectionMode(31, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
GPIO_setPadConfig(31, GPIO_PULL_UP); // 풀업 저항 활성화
GPIO_writePin(31, 0); // 초기 상태: LED OFF
}
// 인터럽트 서비스 루틴 (ISR)
__interrupt void sdfm1ISR(void)
{
// SDFM 필터 1에서 변환된 데이터 읽기
// 데이터 준비 완료 인터럽트 발생 시 호출됨
filterData = SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_1);
// 인터럽트 플래그 지우기
// 다음 인터럽트를 위해 플래그 초기화
SDFM_clearInterruptStatus(SDFM1_BASE, SDFM_FILTER_1);
// PIE 인터럽트 그룹 ACK
// 인터럽트 그룹 8(SDFM 관련) 처리 완료 신호
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
// 상태 업데이트: SDFM 동작 중
sdfmStatus = 1;
}
// SDFM1 초기화 함수
void initSDFM(void)
{
// SDFM1 모듈의 클럭 활성화
// 시스템 클럭을 SDFM1 모듈에 공급
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SDFM1);
// 모듈레이터 클럭 설정: 20MHz
// SDFM_MODULATOR_1에 20MHz 클럭 설정
SDFM_setupModulatorClock(SDFM1_BASE, SDFM_MODULATOR_1, SDFM_MODULATOR_CLK_20MHZ);
// 데이터 필터 설정: Sinc3 필터, OSR=128
// 고해상도 변환을 위해 Sinc3 필터 사용
SDFM_configDataFilter(SDFM1_BASE, SDFM_FILTER_1, SDFM_FILTER_SINC3, 128);
SDFM_enableDataFilter(SDFM1_BASE, SDFM_FILTER_1); // 필터 1 활성화
// 인터럽트 설정: 데이터 준비 완료 시 인터럽트 발생
// SDFM_INT_DATA_READY로 데이터 변환 완료 시 ISR 호출
SDFM_enableInterrupt(SDFM1_BASE, SDFM_FILTER_1, SDFM_INT_DATA_READY);
// SDFM1 모듈 활성화
// 모든 설정 완료 후 모듈 동작 시작
SDFM_enableModule(SDFM1_BASE);
}
void main(void)
{
// 시스템 클럭, 주변 장치, PLL, Watchdog 초기화
Device_init();
// GPIO 기본 초기화
Device_initGPIO();
// SDFM 관련 GPIO 설정
// SDFM 데이터/클럭 입력 및 디버깅용 LED 설정
initGPIO();
// 인터럽트 모듈 초기화
// 인터럽트 벡터 테이블과 컨트롤러 설정
Interrupt_initModule();
Interrupt_initVectorTable();
// SDFM1 인터럽트 ISR 등록
// INT_SDFM1 인터럽트에 sdfm1ISR 함수 연결
Interrupt_register(INT_SDFM1, &sdfm1ISR);
// 시스템 클럭 확인
// 200MHz가 아닌 경우 오류 처리
uint32_t sysClockHz = SysCtl_getClock(DEVICE_OSCSRC_FREQ);
if (sysClockHz != 200000000)
{
sdfmStatus = 0xFFFF; // 오류 상태 설정
GPIO_writePin(31, 0); // LED OFF로 오류 표시
ESTOP0; // 디버깅용 정지
}
// SDFM1 모듈 초기화
// 모듈레이터 클럭, 필터, 인터럽트 설정
initSDFM();
// 초기화 오류 확인
if (sdfmStatus != 1)
{
sdfmStatus = 0xFFFF; // 오류 상태 설정
GPIO_writePin(31, 0); // LED OFF로 오류 표시
ESTOP0; // 디버깅용 정지
}
// 글로벌 인터럽트 활성화
EINT;
// Watchdog 활성화
// 실시간 애플리케이션에서 저전력 모드 방지
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_WD);
SysCtl_serviceWatchdog();
// 무한 루프: 상태 표시
for(;;)
{
// 디버깅용: 상태 표시
// 정상 동작 시 LED ON
GPIO_writePin(31, (sdfmStatus == 1) ? 1 : 0);
DEVICE_DELAY_US(1000000); // 1초 대기
}
}
설명:
- 기능: SDFM1의 데이터 준비 완료 인터럽트를 사용하여 변환된 데이터를 읽음.
- 설정: 20MHz 모듈레이터 클럭, Sinc3 필터, OSR=128, 데이터 준비 완료 인터럽트 활성화.
- GPIO: GPIO48(SD1_D1), GPIO49(SD1_C1), GPIO31(LED).
- 결과: 변환된 데이터는 ISR에서 filterData 변수에 저장, 정상 동작 시 LED ON.
4.3. 예제 3: 다중 채널 SDFM 설정
SDFM1의 채널 1과 2를 동시에 사용하여 데이터를 읽습니다.
#include "driverlib.h" // C2000 DriverLib 헤더 파일 포함
#include "device.h" // 디바이스별 정의 포함
// 디버깅 및 상태 추적을 위한 전역 변수
volatile uint32_t sdfmStatus = 0; // 0: 초기화 완료, 1: SDFM 동작 중, 0xFFFF: 오류
volatile int32_t filterData1 = 0; // 채널 1 필터 데이터
volatile int32_t filterData2 = 0; // 채널 2 필터 데이터
// GPIO 초기화 함수
void initGPIO(void)
{
// GPIO48을 SDFM1 데이터 입력(SD1_D1)으로 설정
// 채널 1의 시그마-델타 데이터 스트림 입력
GPIO_setPinConfig(GPIO_48_SD1_D1);
GPIO_setDirectionMode(48, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(48, GPIO_PULL_UP);
// GPIO49를 SDFM1 클럭 입력(SD1_C1)으로 설정
// 채널 1의 모듈레이터 클럭 입력
GPIO_setPinConfig(GPIO_49_SD1_C1);
GPIO_setDirectionMode(49, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(49, GPIO_PULL_UP);
// GPIO50을 SDFM1 데이터 입력(SD1_D2)으로 설정
// 채널 2의 시그마-델타 데이터 스트림 입력
GPIO_setPinConfig(GPIO_50_SD1_D2);
GPIO_setDirectionMode(50, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(50, GPIO_PULL_UP);
// GPIO51를 SDFM1 클럭 입력(SD1_C2)으로 설정
// 채널 2의 모듈레이터 클럭 입력
GPIO_setPinConfig(GPIO_51_SD1_C2);
GPIO_setDirectionMode(51, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(51, GPIO_PULL_UP);
// GPIO31을 디버깅용 LED로 설정
GPIO_setPinConfig(GPIO_31_GPIO31);
GPIO_setDirectionMode(31, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(31, GPIO_PULL_UP);
GPIO_writePin(31, 0); // 초기 상태: LED OFF
}
// SDFM1 초기화 함수
void initSDFM(void)
{
// SDFM1 모듈의 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SDFM1);
// 채널 1 모듈레이터 클럭 설정: 20MHz
SDFM_setupModulatorClock(SDFM1_BASE, SDFM_MODULATOR_1, SDFM_MODULATOR_CLK_20MHZ);
// 채널 2 모듈레이터 클럭 설정: 20MHz
SDFM_setupModulatorClock(SDFM1_BASE, SDFM_MODULATOR_2, SDFM_MODULATOR_CLK_20MHZ);
// 채널 1 필터 설정: Sinc3, OSR=128
// 고해상도 변환에 적합
SDFM_configDataFilter(SDFM1_BASE, SDFM_FILTER_1, SDFM_FILTER_SINC3, 128);
SDFM_enableDataFilter(SDFM1_BASE, SDFM_FILTER_1);
// 채널 2 필터 설정: Sinc2, OSR=64
// 빠른 응답에 적합
SDFM_configDataFilter(SDFM1_BASE, SDFM_FILTER_2, SDFM_FILTER_SINC2, 64);
SDFM_enableDataFilter(SDFM1_BASE, SDFM_FILTER_2);
// SDFM1 모듈 활성화
SDFM_enableModule(SDFM1_BASE);
// 상태 업데이트
sdfmStatus = 1;
}
void main(void)
{
// 시스템 초기화
Device_init();
Device_initGPIO();
// SDFM 관련 GPIO 설정
initGPIO();
// 인터럽트 모듈 초기화
Interrupt_initModule();
Interrupt_initVectorTable();
// 시스템 클럭 확인
uint32_t sysClockHz = SysCtl_getClock(DEVICE_OSCSRC_FREQ);
if (sysClockHz != 200000000)
{
sdfmStatus = 0xFFFF;
GPIO_writePin(31, 0);
ESTOP0;
}
// SDFM1 초기화
initSDFM();
// 초기화 오류 확인
if (sdfmStatus != 1)
{
sdfmStatus = 0xFFFF;
GPIO_writePin(31, 0);
ESTOP0;
}
// 글로벌 인터럽트 활성화
EINT;
// Watchdog 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_WD);
SysCtl_serviceWatchdog();
// 무한 루프
for(;;)
{
// 채널 1, 2의 필터 데이터 읽기
filterData1 = SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_1);
filterData2 = SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_2);
// 디버깅용: 상태 표시
GPIO_writePin(31, (sdfmStatus == 1) ? 1 : 0);
DEVICE_DELAY_US(1000000);
}
}
설명:
- 기능: SDFM1의 채널 1(Sinc3, OSR=128)과 채널 2(Sinc2, OSR=64)를 사용하여 두 채널의 데이터를 읽음.
- 설정: 20MHz 모듈레이터 클럭, 두 필터 독립 설정.
- GPIO: GPIO48(SD1_D1), GPIO49(SD1_C1), GPIO50(SD1_D2), GPIO51(SD1_C2), GPIO31(LED).
- 결과: 두 채널의 변환된 데이터는 filterData1, filterData2에 저장, 정상 동작 시 LED ON.
- 용도: 다중 센서 데이터 수집.
4.4. 예제 4: SDFM과 ePWM 동기화
SDFM1과 ePWM1을 동기화하여 ePWM의 SOCA 신호로 SDFM 데이터 샘플링을 트리거합니다.
#include "driverlib.h" // C2000 DriverLib 헤더 파일 포함
#include "device.h" // 디바이스별 정의 포함
// 디버깅 및 상태 추적을 위한 전역 변수
volatile uint32_t sdfmStatus = 0; // 0: 초기화 완료, 1: SDFM 동작 중, 0xFFFF: 오류
volatile int32_t filterData = 0; // SDFM 필터 데이터
// GPIO 초기화 함수
void initGPIO(void)
{
// GPIO48을 SDFM1 데이터 입력(SD1_D1)으로 설정
GPIO_setPinConfig(GPIO_48_SD1_D1);
GPIO_setDirectionMode(48, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(48, GPIO_PULL_UP);
// GPIO49를 SDFM1 클럭 입력(SD1_C1)으로 설정
GPIO_setPinConfig(GPIO_49_SD1_C1);
GPIO_setDirectionMode(49, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(49, GPIO_PULL_UP);
// GPIO0을 ePWM1A로 설정
// PWM 신호 출력용
GPIO_setPinConfig(GPIO_0_EPWM1A);
GPIO_setDirectionMode(0, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(0, GPIO_PULL_UP);
// GPIO31을 디버깅용 LED로 설정
GPIO_setPinConfig(GPIO_31_GPIO31);
GPIO_setDirectionMode(31, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(31, GPIO_PULL_UP);
GPIO_writePin(31, 0);
}
// SDFM1 및 ePWM1 초기화 함수
void initSDFM(void)
{
// SDFM1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SDFM1);
// ePWM1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1);
// ePWM1 설정: 100kHz PWM
// 주기 = 200MHz / 100kHz = 2000
EPWM_setTimeBasePeriod(EPWM1_BASE, 2000);
EPWM_setCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP); // Up 카운터 모드
EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO, EPWM_AQ_OUTPUT_HIGH); // 카운터=0일 때 HIGH
EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_ON_TIMEBASE_CMPA_UP, EPWM_AQ_OUTPUT_LOW); // CMPA에서 LOW
EPWM_setCompareA(EPWM1_BASE, 1000); // 50% 듀티 사이클
// SOCA 트리거 설정: 카운터=0일 때 발생
// SDFM 동기화를 위해 ePWM1의 SOCA 신호 사용
EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO);
EPWM_setADCTriggerEventPrescale(EPWM1_BASE, EPWM_SOC_A, 1);
// SDFM 모듈레이터 클럭 설정: 20MHz
SDFM_setupModulatorClock(SDFM1_BASE, SDFM_MODULATOR_1, SDFM_MODULATOR_CLK_20MHZ);
// 필터 설정: Sinc3, OSR=128
SDFM_configDataFilter(SDFM1_BASE, SDFM_FILTER_1, SDFM_FILTER_SINC3, 128);
SDFM_enableDataFilter(SDFM1_BASE, SDFM_FILTER_1);
// SDFM 동기화: ePWM1 SOCA 신호 사용
SDFM_selectClockSource(SDFM1_BASE, SDFM_MODULATOR_1, SDFM_CLK_SRC_EPWM1_SOCA);
// SDFM 및 ePWM 모듈 활성화
SDFM_enableModule(SDFM1_BASE);
EPWM_enableModule(EPWM1_BASE);
// 상태 업데이트
sdfmStatus = 1;
}
void main(void)
{
// 시스템 초기화
Device_init();
Device_initGPIO();
// SDFM 및 ePWM 관련 GPIO 설정
initGPIO();
// 인터럽트 모듈 초기화
Interrupt_initModule();
Interrupt_initVectorTable();
// 시스템 클럭 확인
uint32_t sysClockHz = SysCtl_getClock(DEVICE_OSCSRC_FREQ);
if (sysClockHz != 200000000)
{
sdfmStatus = 0xFFFF;
GPIO_writePin(31, 0);
ESTOP0;
}
// SDFM1 및 ePWM1 초기화
initSDFM();
// 초기화 오류 확인
if (sdfmStatus != 1)
{
sdfmStatus = 0xFFFF;
GPIO_writePin(31, 0);
ESTOP0;
}
// 글로벌 인터럽트 활성화
EINT;
// Watchdog 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_WD);
SysCtl_serviceWatchdog();
// 무한 루프
for(;;)
{
// 필터 데이터 읽기
filterData = SDFM_getFilterData(SDFM1_BASE, SDFM_FILTER_1);
// 디버깅용: 상태 표시
GPIO_writePin(31, (sdfmStatus == 1) ? 1 : 0);
DEVICE_DELAY_US(1000000);
}
}
설명:
- 기능: ePWM1의 SOCA 신호로 SDFM1 데이터 샘플링을 동기화.
- 설정: ePWM1(100kHz, 50% 듀티), SDFM1(Sinc3, OSR=128), ePWM1 SOCA로 동기화.
- GPIO: GPIO48(SD1_D1), GPIO49(SD1_C1), GPIO0(ePWM1A), GPIO31(LED).
- 결과: ePWM1의 주기에 맞춰 데이터 샘플링, 변환된 데이터는 filterData에 저장, 정상 동작 시 LED ON.
- 용도: PWM 기반 모터 제어와 센서 데이터 동기화.
5. 추가 고려 사항
- OSR 선택: 오버샘플링 비율(OSR)은 해상도와 샘플링 속도의 균형을 결정. OSR이 높을수록 해상도는 높아지지만 샘플링 속도는 느려짐.
- 필터 선택: Sinc3는 고해상도에 적합, Sinc1은 빠른 응답에 적합. 애플리케이션 요구사항에 따라 선택.
- 클럭 설정: 모듈레이터 클럭은 일반적으로 10~20MHz로 설정. 외부 클럭 사용 시 동기화 주의.
- GPIO 설정: SDFM 핀은 외부 풀업 저항이 필요할 수 있음. 회로 설계 확인.
- C2000Ware: 예제 코드는 C2000Ware의 DriverLib 기반. C:\ti\c2000에 설치.
- 디버깅: Code Composer Studio의 .syscfg 툴로 SDFM 및 GPIO 설정 시각적 구성 가능.
키워드: TMS320F28388D, SDFM, DriverLib, C2000, 시그마-델타, 아날로그-디지털 변환, Code Composer Studio, Sinc 필터, 인터럽트, 동기화, 다중 채널
'MCU > C2000' 카테고리의 다른 글
[TMS320F28388D] CPU1, CPU2 멀티코어 사용법: DriverLib API로 멀티코어 설정 및 코드 (0) | 2025.08.17 |
---|---|
[TMS320F28388D] DMA 사용법: DriverLib API로 DMA 설정 및 코드 (1) | 2025.08.17 |
[TMS320F28388D] SPI 사용법: DriverLib API로 SPI 설정 및 코드 (1) | 2025.08.17 |
[TMS320F28388D] CAN 사용법: DriverLib API로 CAN 설정 및 코드 (0) | 2025.08.17 |
[TMS320F28388D] CLB 사용법: DriverLib API로 CLB 설정 및 코드 (0) | 2025.08.17 |
[TMS320F28388D] CLA 사용법: DriverLib API로 CLA 설정 및 코드 (0) | 2025.08.17 |
[TMS320F28388D] EMIF 사용법: DriverLib API로 EMIF 설정 및 코드 (0) | 2025.08.17 |
[TMS320F28388D] eQEP 사용법: DriverLib API로 eQEP 설정 및 코드 (0) | 2025.08.17 |