이 문서에서는 Texas Instruments의 TMS320F28388D 마이크로컨트롤러에서 eCAP(Enhanced Capture) 모듈을 DriverLib API를 사용하여 설정하고 사용하는 방법을 상세히 다룹니다. C2000 시리즈의 고성능 마이크로컨트롤러인 TMS320F28388D의 eCAP 모듈을 활용하여 외부 신호의 타이밍 이벤트를 캡처하거나 PWM 신호를 분석하는 방법을 배우고, 다양한 예제 코드를 통해 실제 구현 방법을 익힐 수 있습니다. 각 코드는 Code Composer Studio(CCS) 환경에서 바로 컴파일 및 실행 가능하며, 상세한 주석과 계산식을 포함합니다.
1. TMS320F28388D eCAP 개요
TMS320F28388D는 Texas Instruments의 C2000 시리즈에 속하는 고성능 32비트 마이크로컨트롤러로, 최대 6개의 eCAP 모듈(eCAP1~eCAP6)을 제공합니다. 각 모듈은 외부 신호의 상승/하강 에지를 캡처하거나 PWM 신호의 주기와 듀티 사이클을 측정하는 데 최적화되어 있습니다. eCAP 모듈의 주요 특징은 다음과 같습니다:
- 타임스탬프 캡처: 최대 4개의 이벤트를 32비트 타임스탬프 레지스터(CAP1~CAP4)에 기록.
- PWM 분석: 주기와 듀티 사이클 측정을 통해 신호 특성 분석.
- APWM 모드: 간단한 비대칭 PWM 신호 생성 가능.
- 프리스케일러: 입력 이벤트를 분주하여 캡처 빈도 조정.
- 인터럽트 지원: 에지 감지, 카운터 오버플로우 등 다양한 이벤트에 대한 인터럽트 제공.
- 고해상도 타이밍: 시스템 클럭(SYSCLK, 기본 200MHz)에 동기화된 나노초 단위 측정.
eCAP은 모터 제어, 전력 변환, 센서 인터페이스 등 정밀한 타이밍 분석이 필요한 애플리케이션에 적합합니다. DriverLib API는 레지스터 직접 조작 대신 추상화된 함수를 제공하여 eCAP 설정을 간소화합니다.
2. 주요 eCAP DriverLib API 함수
TMS320F28388D의 eCAP 모듈을 제어하기 위해 자주 사용되는 DriverLib API 함수와 그 사용 방법을 아래에 정리했습니다. 각 함수는 eCAP 설정, 인터럽트 처리, 타임스탬프 읽기 등 특정 작업에 최적화되어 있습니다.
2.1. eCAP 설정 관련 함수
- ECap_enableTimeStampCapture(base)
- 설명: 타임스탬프 캡처 기능을 활성화하여 외부 신호의 이벤트를 기록할 수 있게 합니다.
- 매개변수: base: eCAP 모듈의 베이스 주소 (예: ECAP1_BASE).
- 사용 예: eCAP1의 타임스탬프 캡처 활성화.
- ECap_setCaptureMode(base, mode)
- 설명: 캡처 모드를 설정하여 연속(4개 이벤트 반복) 또는 원샷(4개 이벤트 후 정지) 모드를 선택합니다.
- 매개변수: base: eCAP 모듈의 베이스 주소, mode: 캡처 모드 (ECAP_CONTINUOUS_CAPTURE_MODE 또는 ECAP_ONE_SHOT_CAPTURE_MODE).
- 사용 예: 연속 캡처 모드 설정.
- ECap_setEventPolarity(base, event)
- 설명: 캡처할 이벤트의 극성(상승 또는 하강 에지)을 설정합니다.
- 매개변수: base: eCAP 모듈의 베이스 주소, event: 이벤트 극성 (ECAP_EVNT_RISING_EDGE 또는 ECAP_EVNT_FALLING_EDGE).
- 사용 예: 상승 에지 캡처 설정.
- ECap_setEventPrescaler(base, prescale)
- 설명: 입력 이벤트의 프리스케일러 값을 설정하여 캡처 빈도를 조정합니다.
- 매개변수: base: eCAP 모듈의 베이스 주소, prescale: 프리스케일러 값 (0~255, 0은 분주 없음).
- 사용 예: 프리스케일러 비활성화 (1:1).
- ECap_startCounter(base) / ECap_stopCounter(base)
- 설명: 32비트 타임스탬프 카운터를 시작하거나 정지합니다.
- 매개변수: base: eCAP 모듈의 베이스 주소.
- 사용 예: eCAP 카운터 시작.
2.2. 인터럽트 관련 함수
- ECap_enableInterrupt(base, interruptMask)
- 설명: 특정 eCAP 인터럽트를 활성화하여 이벤트 발생 시 ISR 호출을 가능하게 합니다.
- 매개변수: base: eCAP 모듈의 베이스 주소, interruptMask: 인터럽트 소스 (예: ECAP_ISR_SOURCE_CAPTURE_EVENT_1, ECAP_ISR_SOURCE_COUNTER_OVERFLOW).
- 사용 예: eCAP1의 첫 번째 캡처 이벤트 인터럽트 활성화.
- ECap_clearInterrupt(base, interruptMask)
- 설명: 인터럽트 플래그를 지워 다음 인터럽트를 처리할 수 있도록 합니다.
- 매개변수: base: eCAP 모듈의 베이스 주소, interruptMask: 지울 인터럽트 소스.
- Interrupt_register(intNumber, handler)
- 설명: eCAP 인터럽트 핸들러를 등록하여 특정 이벤트에 대한 ISR를 지정합니다.
- 매개변수: intNumber: 인터럽트 번호 (예: INT_ECAP1), handler: 인터럽트 서비스 루틴(ISR) 함수 포인터.
- 사용 예: eCAP1 인터럽트에 ISR 등록.
2.3. 캡처 데이터 읽기 관련 함수
- ECap_getCaptureTimeStamp(base, event)
- 설명: 지정된 캡처 이벤트의 타임스탬프를 읽어 이벤트 발생 시간을 반환합니다.
- 매개변수: base: eCAP 모듈의 베이스 주소, event: 읽을 캡처 이벤트 (ECAP_CAPTURE_EVENT_1 ~ ECAP_CAPTURE_EVENT_4).
- 반환값: 32비트 타임스탬프 값 (uint32_t, SYSCLK 틱 단위).
- 사용 예: CAP1의 타임스탬프 읽기.
2.4. APWM 모드 관련 함수
- ECap_setAPWMMode(base, enable)
- 설명: eCAP 모듈을 APWM(Asymmetric PWM) 모드로 설정하여 PWM 신호 생성을 활성화합니다.
- 매개변수: base: eCAP 모듈의 베이스 주소, enable: APWM 모드 활성화 (true) 또는 비활성화 (false).
- 사용 예: eCAP1을 APWM 모드로 설정.
- ECap_setAPWMPeriod(base, period)
- 설명: APWM 모드에서 PWM 주기를 설정하여 출력 신호의 주파수를 결정합니다.
- 매개변수: base: eCAP 모듈의 베이스 주소, period: 주기 값 (SYSCLK 틱 단위).
- 사용 예: 10kHz PWM 주기 설정.
- ECap_setAPWMCompare(base, compare)
- 설명: APWM 모드에서 비교 값을 설정하여 듀티 사이클을 조정합니다.
- 매개변수: base: eCAP 모듈의 베이스 주소, compare: 비교 값 (듀티 사이클 결정).
- 사용 예: 50% 듀티 사이클 설정.
3. eCAP 설정 및 동작 원리
TMS320F28388D의 eCAP 모듈을 설정하고 동작시키는 일반적인 절차는 다음과 같습니다:
- 시스템 초기화: 시스템 클럭을 초기화하여 SYSCLK(200MHz)을 설정합니다 (Device_init()).
- GPIO 설정: eCAP 입력/출력 핀을 설정하여 외부 신호를 수신하거나 PWM 신호를 출력합니다 (initECAPGPIO).
- eCAP 모듈 설정: eCAP 클럭을 활성화하여 모듈 동작을 준비합니다 (SysCtl_enablePeripheral). 캡처 모드, 이벤트 극성, 프리스케일러를 설정하여 캡처 동작을 정의합니다 (ECap_setCaptureMode, ECap_setEventPolarity, ECap_setEventPrescaler).
- 인터럽트 설정 (선택): 인터럽트 활성화 및 ISR 등록하여 캡처 이벤트 처리 (ECap_enableInterrupt, Interrupt_register).
- eCAP 활성화 및 캡처 시작: eCAP 카운터를 시작하여 타임스탬프 기록을 활성화합니다 (ECap_startCounter).
- 결과 처리: 캡처된 타임스탬프를 읽거나 인터럽트를 통해 결과를 처리합니다 (ECap_getCaptureTimeStamp).
4. eCAP 예제 코드
아래는 TMS320F28388D의 eCAP 모듈을 다양한 방식으로 사용하는 10개의 독립적인 예제 코드입니다. 모든 코드는 Code Composer Studio(CCS)에서 C2000Ware 환경(C:\ti\c2000)에서 바로 컴파일 및 실행 가능하도록 작성되었습니다. GPIO 설정은 initECAPGPIO
함수로 분리되었으며, 설정값은 SYSCLK(200MHz) 기준 계산식으로 정의됩니다. 상세한 주석이 포함되어 있습니다.
4.1. 공통 GPIO 설정 함수
모든 예제에서 사용되는 GPIO 설정 함수로, eCAP1에 연결된 GPIO24를 입력 또는 출력으로 구성합니다.
#include "driverlib.h"
#include "device.h"
// eCAP1 GPIO 설정 함수
void initECAPGPIO(uint32_t pin, bool isInput)
{
// GPIO24를 eCAP1에 연결 (TMS320F28388D 핀맵 기준)
GPIO_setPinConfig(GPIO_24_ECAP1); // GPIO24를 eCAP1 핀 기능으로 설정
// 핀 방향 설정: 입력 또는 출력
GPIO_setDirectionMode(pin, isInput ? GPIO_DIR_MODE_IN : GPIO_DIR_MODE_OUT); // isInput=true면 입력, false면 출력
// 입력 모드일 경우: 비동기 입력 설정
if (isInput)
{
GPIO_setQualificationMode(pin, GPIO_QUAL_ASYNC); // 비동기 모드로 입력 지연 최소화 (직접 신호 처리)
}
// 출력 모드일 경우: 표준 출력 설정
else
{
GPIO_setPadConfig(pin, GPIO_PIN_TYPE_STD); // 표준 출력 설정 (풀업/풀다운 없이 안정적 출력)
}
}
설명:
- 기능: GPIO24를 eCAP1 핀으로 설정하고 입력/출력 모드를 구성.
- 매개변수: pin: 설정할 GPIO 번호 (예: 24), isInput: true(입력 모드), false(출력 모드).
- 설정: 입력: 비동기 모드(GPIO_QUAL_ASYNC)로 지연 최소화, 출력: 표준 출력(GPIO_PIN_TYPE_STD)으로 안정적인 PWM 출력.
4.2. 예제 1: 소프트웨어로 상승 에지 캡처
이 예제는 eCAP1 모듈을 사용하여 GPIO24에 입력된 신호의 상승 에지를 캡처하고 타임스탬프를 읽습니다.
#include "driverlib.h"
#include "device.h"
// GPIO 설정 함수 (위에서 정의)
void initECAPGPIO(uint32_t pin, bool isInput);
// eCAP 캡처 결과 저장 변수
uint32_t capResult;
void main(void)
{
// 시스템 클럭 초기화 (SYSCLK = 200MHz)
Device_init();
// eCAP1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1); // eCAP1 모듈에 클럭 공급 (필수)
// GPIO24를 eCAP1 입력 핀으로 설정
initECAPGPIO(24, true); // 입력 모드로 GPIO24 설정 (비동기 입력)
// eCAP1 설정: 연속 모드, 상승 에지 캡처
ECap_stopCounter(ECAP1_BASE); // 카운터 정지 (안전한 설정을 위해 초기화)
ECap_enableTimeStampCapture(ECAP1_BASE); // 타임스탬프 캡처 기능 활성화
ECap_setCaptureMode(ECAP1_BASE, ECAP_CONTINUOUS_CAPTURE_MODE); // 연속 캡처 모드 (CAP1~CAP4 반복)
ECap_setEventPolarity(ECAP1_BASE, ECAP_EVNT_RISING_EDGE); // 상승 에지 감지 (외부 신호 상승 시 기록)
ECap_setEventPrescaler(ECAP1_BASE, 0); // 프리스케일러 비활성화 (1:1, 최대 해상도)
// eCAP1 안정화를 위해 1ms 지연
// 계산식: 1ms = SYSCLK * 시간 = 200e6 * 0.001 = 200,000틱
DEVICE_DELAY_US(1000);
// eCAP 카운터 시작
ECap_startCounter(ECAP1_BASE); // 32비트 타임스탬프 카운터 시작 (SYSCLK 기준)
// 무한 루프
for(;;)
{
// CAP1의 타임스탬프 읽기
capResult = ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_1); // CAP1 타임스탬프 (SYSCLK 틱)
// 결과 처리: capResult는 SYSCLK 틱 단위 (200MHz 기준, 1틱 = 5ns)
// 시간(초) = capResult * (1 / 200e6) = capResult * 5e-9
DEVICE_DELAY_US(100000); // 100ms 대기 (200e6 * 0.1 = 20,000,000틱)
}
}
설명:
- 기능: eCAP1 모듈로 GPIO24에 입력된 신호의 상승 에지를 캡처하여 타임스탬프를 저장.
- 설정: GPIO:
initECAPGPIO(24, true)
로 입력 핀 설정, eCAP: 연속 캡처 모드, 상승 에지 감지, 프리스케일러 비활성화, 계산식: 타임스탬프(초) = capResult * 5e-9. - 결과: capResult 변수에 CAP1 타임스탬프 저장 (SYSCLK 틱 단위).
- 주기: 100ms마다 타임스탬프 읽기.
4.3. 예제 2: 인터럽트를 사용한 PWM 주기 측정
이 예제는 eCAP1 모듈을 사용하여 PWM 신호의 주기를 측정하고 인터럽트로 결과를 처리합니다.
#include "driverlib.h"
#include "device.h"
// GPIO 설정 함수 (위에서 정의)
void initECAPGPIO(uint32_t pin, bool isInput);
// PWM 주기 저장 변수 (인터럽트에서 업데이트)
volatile uint32_t pwmPeriod;
// 인터럽트 서비스 루틴 (ISR)
__interrupt void ecap1ISR(void)
{
// CAP1과 CAP2의 타임스탬프 차이로 PWM 주기 계산
pwmPeriod = ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_2) -
ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_1); // 단위: SYSCLK 틱 (1틱 = 5ns)
// 인터럽트 플래그 지우기 (다음 인터럽트 준비)
ECap_clearInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_2);
// PIE 인터럽트 ACK (그룹 4, eCAP1 인터럽트 처리 완료)
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}
void main(void)
{
// 시스템 클럭 초기화 (SYSCLK = 200MHz)
Device_init();
// eCAP1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1); // eCAP1 모듈에 클럭 공급
// GPIO24를 eCAP1 입력 핀으로 설정
initECAPGPIO(24, true); // 입력 모드로 GPIO24 설정 (비동기 입력)
// eCAP1 설정: 연속 모드, 상승 에지 캡처
ECap_stopCounter(ECAP1_BASE); // 카운터 정지 (안전한 설정을 위해 초기화)
ECap_enableTimeStampCapture(ECAP1_BASE); // 타임스탬프 캡처 기능 활성화
ECap_setCaptureMode(ECAP1_BASE, ECAP_CONTINUOUS_CAPTURE_MODE); // 연속 캡처 모드
ECap_setEventPolarity(ECAP1_BASE, ECAP_EVNT_RISING_EDGE); // 상승 에지 감지
ECap_setEventPrescaler(ECAP1_BASE, 0); // 프리스케일러 비활성화 (1:1)
// 인터럽트 설정
Interrupt_register(INT_ECAP1, &ecap1ISR); // eCAP1 ISR 등록
ECap_enableInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_2); // CAP2 이벤트 인터럽트 활성화
Interrupt_enable(INT_ECAP1); // eCAP1 인터럽트 활성화
// eCAP1 안정화를 위해 1ms 지연 (200e6 * 0.001 = 200,000틱)
DEVICE_DELAY_US(1000);
// eCAP 카운터 시작
ECap_startCounter(ECAP1_BASE); // 32비트 타임스탬프 카운터 시작
// 무한 루프
for(;;)
{
// pwmPeriod 변수로 주기 값 활용
// 주기(초) = pwmPeriod * (1 / 200e6) = pwmPeriod * 5e-9
DEVICE_DELAY_US(100000); // 100ms 대기 (200e6 * 0.1 = 20,000,000틱)
}
}
설명:
- 기능: eCAP1 모듈로 GPIO24에 입력된 PWM 신호의 상승 에지를 캡처하여 주기를 측정.
- 설정: GPIO:
initECAPGPIO(24, true)
로 입력 핀 설정, eCAP: 연속 캡처 모드, 상승 에지 감지, CAP2 이벤트 인터럽트, 계산식: 주기(초) = pwmPeriod * 5e-9. - 인터럽트: CAP2 이벤트 발생 시 ISR에서 주기 계산.
- 결과: pwmPeriod 변수에 주기 저장 (SYSCLK 틱 단위).
- 주기: 인터럽트 기반, 100ms 대기.
4.4. 예제 3: ePWM 동기화된 캡처
이 예제는 ePWM1의 동기화 신호를 사용하여 eCAP1 모듈로 외부 신호를 캡처합니다.
#include "driverlib.h"
#include "device.h"
// GPIO 설정 함수 (위에서 정의)
void initECAPGPIO(uint32_t pin, bool isInput);
// 캡처 결과 저장 버퍼
#define RESULTS_BUFFER_SIZE 256
uint32_t capResults[RESULTS_BUFFER_SIZE];
volatile uint16_t index = 0;
// ePWM 초기화 함수
void initEPWM(void)
{
// ePWM1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1); // ePWM1 모듈에 클럭 공급
// ePWM1 시간 기준 설정 (100kHz PWM)
// 계산식: 주기 = SYSCLK / 주파수 = 200e6 / 100e3 = 2000틱
EPWM_setTimeBasePeriod(EPWM1_BASE, 200000000 / 100000); // 100kHz 주기
EPWM_setCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP); // 업 카운터 모드
// 동기화 신호 설정 (카운터 0일 때 동기화 출력)
EPWM_enableSyncOut(EPWM1_BASE, EPWM_SYNC_OUT_SOURCE_ZERO); // 동기화 신호 활성화
// ePWM 카운터 시작
EPWM_setTimeBaseCounter(EPWM1_BASE, 0); // 카운터 초기화
}
// 인터럽트 서비스 루틴
__interrupt void ecap1ISR(void)
{
// CAP1의 타임스탬프 읽기
capResults[index] = ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_1); // SYSCLK 틱 단위
// 인덱스 증가 및 버퍼 오버플로우 방지
index++;
if (index >= RESULTS_BUFFER_SIZE)
{
index = 0; // 순환 버퍼로 오버플로우 방지
}
// 인터럽트 플래그 지우기
ECap_clearInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_1);
// PIE 인터럽트 ACK (그룹 4)
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}
void main(void)
{
// 시스템 클럭 초기화 (SYSCLK = 200MHz)
Device_init();
// eCAP1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1); // eCAP1 모듈에 클럭 공급
// GPIO24를 eCAP1 입력 핀으로 설정
initECAPGPIO(24, true); // 입력 모드로 GPIO24 설정 (비동기 입력)
// eCAP1 설정: 연속 모드, 상승 에지 캡처
ECap_stopCounter(ECAP1_BASE); // 카운터 정지 (설정 전 초기화)
ECap_enableTimeStampCapture(ECAP1_BASE); // 타임스탬프 캡처 기능 활성화
ECap_setCaptureMode(ECAP1_BASE, ECAP_CONTINUOUS_CAPTURE_MODE); // 연속 캡처 모드
ECap_setEventPolarity(ECAP1_BASE, ECAP_EVNT_RISING_EDGE); // 상승 에지 감지
ECap_setEventPrescaler(ECAP1_BASE, 0); // 프리스케일러 비활성화 (1:1)
// ePWM1 동기화 신호로 eCAP 동기화
ECap_setSyncInPulseSource(ECAP1_BASE, ECAP_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1); // ePWM1 동기화 신호 사용
// 인터럽트 설정
Interrupt_register(INT_ECAP1, &ecap1ISR); // eCAP1 ISR 등록
ECap_enableInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_1); // CAP1 이벤트 인터럽트 활성화
Interrupt_enable(INT_ECAP1); // eCAP1 인터럽트 활성화
// ePWM1 초기화
initEPWM(); // 100kHz 동기화 신호 생성
// eCAP1 안정화를 위해 1ms 지연 (200e6 * 0.001 = 200,000틱)
DEVICE_DELAY_US(1000);
// eCAP 카운터 시작
ECap_startCounter(ECAP1_BASE); // 32비트 타임스탬프 카운터 시작
// 무한 루프
for(;;)
{
// capResults 배열에 저장된 데이터 사용
// 타임스탬프(초) = capResults[i] * (1 / 200e6) = capResults[i] * 5e-9
DEVICE_DELAY_US(1000000); // 1초 대기 (200e6 * 1 = 200,000,000틱)
}
}
설명:
- 기능: ePWM1의 동기화 신호로 eCAP1을 동기화하여 GPIO24 신호를 캡처.
- 설정: GPIO:
initECAPGPIO(24, true)
로 입력 핀 설정, eCAP: 연속 캡처 모드, 상승 에지 감지, ePWM1 동기화, ePWM: 100kHz 주기 (200e6 / 100e3 = 2000틱), 계산식: 타임스탬프(초) = capResults[i] * 5e-9. - 결과: capResults 버퍼에 타임스탬프 저장 (SYSCLK 틱 단위).
- 버퍼 관리: 순환 버퍼로 오버플로우 방지.
- 주기: 인터럽트 기반, 1초 대기.
4.5. 예제 4: APWM 모드로 PWM 생성 (10kHz, 50% 듀티)
이 예제는 eCAP1 모듈을 APWM 모드로 사용하여 10kHz, 50% 듀티 사이클의 PWM 신호를 생성합니다.
#include "driverlib.h"
#include "device.h"
// GPIO 설정 함수 (위에서 정의)
void initECAPGPIO(uint32_t pin, bool isInput);
void main(void)
{
// 시스템 클럭 초기화 (SYSCLK = 200MHz)
Device_init();
// eCAP1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1); // eCAP1 모듈에 클럭 공급
// GPIO24를 eCAP1 출력 핀으로 설정
initECAPGPIO(24, false); // 출력 모드로 GPIO24 설정 (표준 출력)
// eCAP1 설정: APWM 모드
ECap_stopCounter(ECAP1_BASE); // 카운터 정지 (설정 전 초기화)
ECap_setAPWMMode(ECAP1_BASE, true); // APWM 모드 활성화
// 주기 설정: 10kHz = 200e6 / 주기틱 -> 주기틱 = 200e6 / 10e3 = 20,000틱
ECap_setAPWMPeriod(ECAP1_BASE, 200000000 / 10000); // 10kHz 주기
// 비교 값 설정: 50% 듀티 = 주기 / 2 = 20,000 / 2 = 10,000틱
ECap_setAPWMCompare(ECAP1_BASE, (200000000 / 10000) / 2); // 50% 듀티 사이클
ECap_setAPWMPolarity(ECAP1_BASE, ECAP_APWM_ACTIVE_HIGH); // 활성 고전압 출력
// eCAP1 안정화를 위해 1ms 지연 (200e6 * 0.001 = 200,000틱)
DEVICE_DELAY_US(1000);
// eCAP 카운터 시작
ECap_startCounter(ECAP1_BASE); // PWM 신호 생성 시작
// 무한 루프
for(;;)
{
// PWM 신호는 하드웨어로 자동 생성
DEVICE_DELAY_US(1000000); // 1초 대기 (200e6 * 1 = 200,000,000틱)
}
}
설명:
- 기능: eCAP1을 APWM 모드로 설정하여 GPIO24에서 10kHz, 50% 듀티 사이클 PWM 신호 생성.
- 설정: GPIO:
initECAPGPIO(24, false)
로 출력 핀 설정, APWM: 10kHz 주기 (200e6 / 10e3 = 20,000틱), 50% 듀티 (20,000 / 2 = 10,000틱), 계산식: 주기틱 = 200e6 / 주파수, 비교값 = 주기틱 / 2. - 결과: GPIO24에서 10kHz PWM 신호 출력.
- 주기: 하드웨어로 자동 생성, 1초 대기.
4.6. 예제 5: 하강 에지 캡처
이 예제는 eCAP1 모듈을 사용하여 GPIO24에 입력된 신호의 하강 에지를 캡처합니다.
#include "driverlib.h"
#include "device.h"
// GPIO 설정 함수 (위에서 정의)
void initECAPGPIO(uint32_t pin, bool isInput);
// eCAP 캡처 결과 저장 변수
uint32_t capResult;
void main(void)
{
// 시스템 클럭 초기화 (SYSCLK = 200MHz)
Device_init();
// eCAP1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1); // eCAP1 모듈에 클럭 공급
// GPIO24를 eCAP1 입력 핀으로 설정
initECAPGPIO(24, true); // 입력 모드로 GPIO24 설정 (비동기 입력)
// eCAP1 설정: 연속 모드, 하강 에지 캡처
ECap_stopCounter(ECAP1_BASE); // 카운터 정지 (설정 전 초기화)
ECap_enableTimeStampCapture(ECAP1_BASE); // 타임스탬프 캡처 기능 활성화
ECap_setCaptureMode(ECAP1_BASE, ECAP_CONTINUOUS_CAPTURE_MODE); // 연속 캡처 모드
ECap_setEventPolarity(ECAP1_BASE, ECAP_EVNT_FALLING_EDGE); // 하강 에지 감지
ECap_setEventPrescaler(ECAP1_BASE, 0); // 프리스케일러 비활성화 (1:1)
// eCAP1 안정화를 위해 1ms 지연 (200e6 * 0.001 = 200,000틱)
DEVICE_DELAY_US(1000);
// eCAP 카운터 시작
ECap_startCounter(ECAP1_BASE); // 32비트 타임스탬프 카운터 시작
// 무한 루프
for(;;)
{
// CAP1의 타임스탬프 읽기
capResult = ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_1); // CAP1 타임스탬프 (SYSCLK 틱)
// 결과 처리: capResult는 SYSCLK 틱 단위 (1틱 = 5ns)
// 시간(초) = capResult * 5e-9
DEVICE_DELAY_US(100000); // 100ms 대기 (200e6 * 0.1 = 20,000,000틱)
}
}
설명:
- 기능: eCAP1 모듈로 GPIO24에 입력된 신호의 하강 에지를 캡처.
- 설정: GPIO:
initECAPGPIO(24, true)
로 입력 핀 설정, eCAP: 연속 캡처 모드, 하강 에지 감지, 프리스케일러 비활성화, 계산식: 타임스탬프(초) = capResult * 5e-9. - 결과: capResult 변수에 CAP1 타임스탬프 저장.
- 주기: 100ms마다 타임스탬프 읽기.
4.7. 예제 6: 원샷 캡처 모드
이 예제는 eCAP1 모듈을 원샷 모드로 설정하여 4개의 이벤트를 캡처한 후 정지합니다.
#include "driverlib.h"
#include "device.h"
// GPIO 설정 함수 (위에서 정의)
void initECAPGPIO(uint32_t pin, bool isInput);
// 캡처 결과 저장 배열
uint32_t capResults[4];
void main(void)
{
// 시스템 클럭 초기화 (SYSCLK = 200MHz)
Device_init();
// eCAP1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1); // eCAP1 모듈에 클럭 공급
// GPIO24를 eCAP1 입력 핀으로 설정
initECAPGPIO(24, true); // 입력 모드로 GPIO24 설정 (비동기 입력)
// eCAP1 설정: 원샷 모드, 상승 에지 캡처
ECap_stopCounter(ECAP1_BASE); // 카운터 정지 (설정 전 초기화)
ECap_enableTimeStampCapture(ECAP1_BASE); // 타임스탬프 캡처 기능 활성화
ECap_setCaptureMode(ECAP1_BASE, ECAP_ONE_SHOT_CAPTURE_MODE); // 원샷 캡처 모드 (4개 이벤트 후 정지)
ECap_setEventPolarity(ECAP1_BASE, ECAP_EVNT_RISING_EDGE); // 상승 에지 감지
ECap_setEventPrescaler(ECAP1_BASE, 0); // 프리스케일러 비활성화 (1:1)
// eCAP1 안정화를 위해 1ms 지연 (200e6 * 0.001 = 200,000틱)
DEVICE_DELAY_US(1000);
// eCAP 카운터 시작
ECap_startCounter(ECAP1_BASE); // 32비트 타임스탬프 카운터 시작
// 무한 루프
for(;;)
{
// 원샷 모드: 4개 이벤트 캡처 후 정지
if (ECap_getCaptureStatus(ECAP1_BASE) & ECAP_ONE_SHOT_DONE)
{
// CAP1~CAP4 타임스탬프 읽기
capResults[0] = ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_1);
capResults[1] = ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_2);
capResults[2] = ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_3);
capResults[3] = ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_4);
// 결과 처리: capResults는 SYSCLK 틱 단위 (1틱 = 5ns)
// 시간(초) = capResults[i] * 5e-9
break; // 캡처 완료 후 루프 종료
}
DEVICE_DELAY_US(100000); // 100ms 대기 (200e6 * 0.1 = 20,000,000틱)
}
}
설명:
- 기능: eCAP1을 원샷 모드로 설정하여 GPIO24 신호의 4개 상승 에지 캡처 후 정지.
- 설정: GPIO:
initECAPGPIO(24, true)
로 입력 핀 설정, eCAP: 원샷 캡처 모드, 상승 에지 감지, 계산식: 타임스탬프(초) = capResults[i] * 5e-9. - 결과: capResults 배열에 4개 타임스탬프 저장.
- 주기: 캡처 완료 후 종료, 대기 100ms.
4.8. 예제 7: 듀티 사이클 측정
이 예제는 eCAP1 모듈을 사용하여 PWM 신호의 듀티 사이클을 측정합니다.
#include "driverlib.h"
#include "device.h"
// GPIO 설정 함수 (위에서 정의)
void initECAPGPIO(uint32_t pin, bool isInput);
// PWM 주기와 듀티 사이클 저장 변수
volatile uint32_t pwmPeriod;
volatile uint32_t pwmDuty;
// 인터럽트 서비스 루틴
__interrupt void ecap1ISR(void)
{
// 주기: CAP2(상승) - CAP1(상승)
pwmPeriod = ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_2) -
ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_1);
// 듀티: CAP3(하강) - CAP1(상승)
pwmDuty = ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_3) -
ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_1);
// 인터럽트 플래그 지우기
ECap_clearInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_3);
// PIE 인터럽트 ACK
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}
void main(void)
{
// 시스템 클럭 초기화 (SYSCLK = 200MHz)
Device_init();
// eCAP1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1);
// GPIO24를 eCAP1 입력 핀으로 설정
initECAPGPIO(24, true);
// eCAP1 설정: 연속 모드, 상승/하강 에지 캡처
ECap_stopCounter(ECAP1_BASE);
ECap_enableTimeStampCapture(ECAP1_BASE);
ECap_setCaptureMode(ECAP1_BASE, ECAP_CONTINUOUS_CAPTURE_MODE);
ECap_setEventPolarity(ECAP1_BASE, ECAP_EVNT_RISING_EDGE); // CAP1, CAP2: 상승 에지
ECap_setEventPolarity(ECAP1_BASE, ECAP_EVNT_FALLING_EDGE); // CAP3: 하강 에지
ECap_setEventPrescaler(ECAP1_BASE, 0);
// 인터럽트 설정 (CAP3 이벤트)
Interrupt_register(INT_ECAP1, &ecap1ISR);
ECap_enableInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_3);
Interrupt_enable(INT_ECAP1);
// eCAP1 안정화를 위해 1ms 지연 (200e6 * 0.001 = 200,000틱)
DEVICE_DELAY_US(1000);
// eCAP 카운터 시작
ECap_startCounter(ECAP1_BASE);
// 무한 루프
for(;;)
{
// pwmPeriod: 주기 (초) = pwmPeriod * 5e-9
// pwmDuty: 듀티 시간 (초) = pwmDuty * 5e-9
// 듀티 비율 (%) = (pwmDuty / pwmPeriod) * 100
DEVICE_DELAY_US(100000); // 100ms 대기 (200e6 * 0.1 = 20,000,000틱)
}
}
설명:
- 기능: eCAP1으로 PWM 신호의 주기와 듀티 사이클을 측정.
- 설정: GPIO:
initECAPGPIO(24, true)
로 입력 핀 설정, eCAP: CAP1, CAP2(상승), CAP3(하강)으로 주기와 듀티 측정, 계산식: 듀티 비율 (%) = (pwmDuty / pwmPeriod) * 100. - 결과: pwmPeriod(주기), pwmDuty(듀티 시간) 저장.
- 주기: 인터럽트 기반, 100ms 대기.
4.9. 예제 8: 프리스케일러 사용
이 예제는 eCAP1 모듈에 프리스케일러를 적용하여 저속 신호를 캡처합니다.
#include "driverlib.h"
#include "device.h"
// GPIO 설정 함수 (위에서 정의)
void initECAPGPIO(uint32_t pin, bool isInput);
// eCAP 캡처 결과 저장 변수
uint32_t capResult;
void main(void)
{
// 시스템 클럭 초기화 (SYSCLK = 200MHz)
Device_init();
// eCAP1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1);
// GPIO24를 eCAP1 입력 핀으로 설정
initECAPGPIO(24, true);
// eCAP1 설정: 연속 모드, 상승 에지, 프리스케일러
ECap_stopCounter(ECAP1_BASE);
ECap_enableTimeStampCapture(ECAP1_BASE);
ECap_setCaptureMode(ECAP1_BASE, ECAP_CONTINUOUS_CAPTURE_MODE);
ECap_setEventPolarity(ECAP1_BASE, ECAP_EVNT_RISING_EDGE);
// 프리스케일러: 32분주 (1 이벤트 = 32 입력 펄스)
ECap_setEventPrescaler(ECAP1_BASE, 32);
// eCAP1 안정화를 위해 1ms 지연 (200e6 * 0.001 = 200,000틱)
DEVICE_DELAY_US(1000);
// eCAP 카운터 시작
ECap_startCounter(ECAP1_BASE);
// 무한 루프
for(;;)
{
// CAP1의 타임스탬프 읽기
capResult = ECap_getCaptureTimeStamp(ECAP1_BASE, ECAP_CAPTURE_EVENT_1);
// 결과 처리: capResult는 SYSCLK 틱 단위
// 실제 시간(초) = capResult * (32 / 200e6) = capResult * 1.6e-7
DEVICE_DELAY_US(100000); // 100ms 대기 (200e6 * 0.1 = 20,000,000틱)
}
}
설명:
- 기능: eCAP1으로 저속 신호 캡처(프리스케일러 32 적용).
- 설정: GPIO:
initECAPGPIO(24, true)
로 입력 핀 설정, eCAP: 연속 캡처, 상승 에지, 프리스케일러 32, 계산식: 시간(초) = capResult * (32 / 200e6). - 결과: capResult에 타임스탬프 저장.
- 주기: 100ms마다 읽기.
4.10. 예제 9: APWM 모드로 1kHz PWM 생성
이 예제는 eCAP1 모듈을 APWM 모드로 사용하여 1kHz, 25% 듀티 사이클의 PWM 신호를 생성합니다.
#include "driverlib.h"
#include "device.h"
// GPIO 설정 함수 (위에서 정의)
void initECAPGPIO(uint32_t pin, bool isInput);
void main(void)
{
// 시스템 클럭 초기화 (SYSCLK = 200MHz)
Device_init();
// eCAP1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1);
// GPIO24를 eCAP1 출력 핀으로 설정
initECAPGPIO(24, false);
// eCAP1 설정: APWM 모드
ECap_stopCounter(ECAP1_BASE);
ECap_setAPWMMode(ECAP1_BASE, true);
// 주기 설정: 1kHz = 200e6 / 주기틱 -> 주기틱 = 200e6 / 1e3 = 200,000틱
ECap_setAPWMPeriod(ECAP1_BASE, 200000000 / 1000);
// 비교 값 설정: 25% 듀티 = 주기 / 4 = 200,000 / 4 = 50,000틱
ECap_setAPWMCompare(ECAP1_BASE, (200000000 / 1000) / 4);
ECap_setAPWMPolarity(ECAP1_BASE, ECAP_APWM_ACTIVE_HIGH);
// eCAP1 안정화를 위해 1ms 지연 (200e6 * 0.001 = 200,000틱)
DEVICE_DELAY_US(1000);
// eCAP 카운터 시작
ECap_startCounter(ECAP1_BASE);
// 무한 루프
for(;;)
{
// PWM 신호는 하드웨어로 자동 생성
DEVICE_DELAY_US(1000000); // 1초 대기 (200e6 * 1 = 200,000,000틱)
}
}
설명:
- 기능: eCAP1으로 1kHz, 25% 듀티 사이클 PWM 신호 생성.
- 설정: GPIO:
initECAPGPIO(24, false)
로 출력 핀 설정, APWM: 1kHz 주기 (200e6 / 1e3 = 200,000틱), 25% 듀티 (200,000 / 4 = 50,000틱), 계산식: 주기틱 = 200e6 / 주파수, 비교값 = 주기틱 / 4. - 결과: GPIO24에서 1kHz PWM 신호 출력.
- 주기: 하드웨어로 자동 생성, 1초 대기.
4.11. 예제 10: 카운터 오버플로우 인터럽트
이 예제는 eCAP1 모듈의 카운터 오버플로우 인터럽트를 사용하여 오버플로우 이벤트를 감지합니다.
#include "driverlib.h"
#include "device.h"
// GPIO 설정 함수 (위에서 정의)
void initECAPGPIO(uint32_t pin, bool isInput);
// 오버플로우 카운트 변수
volatile uint32_t overflowCount;
// 인터럽트 서비스 루틴
__interrupt void ecap1ISR(void)
{
// 오버플로우 카운트 증가
overflowCount++;
// 인터럽트 플래그 지우기
ECap_clearInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_COUNTER_OVERFLOW);
// PIE 인터럽트 ACK
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}
void main(void)
{
// 시스템 클럭 초기화 (SYSCLK = 200MHz)
Device_init();
// eCAP1 클럭 활성화
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1);
// GPIO24를 eCAP1 입력 핀으로 설정
initECAPGPIO(24, true);
// eCAP1 설정: 연속 모드, 상승 에지
ECap_stopCounter(ECAP1_BASE);
ECap_enableTimeStampCapture(ECAP1_BASE);
ECap_setCaptureMode(ECAP1_BASE, ECAP_CONTINUOUS_CAPTURE_MODE);
ECap_setEventPolarity(ECAP1_BASE, ECAP_EVNT_RISING_EDGE);
ECap_setEventPrescaler(ECAP1_BASE, 0);
// 인터럽트 설정 (카운터 오버플로우)
Interrupt_register(INT_ECAP1, &ecap1ISR);
ECap_enableInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_COUNTER_OVERFLOW);
Interrupt_enable(INT_ECAP1);
// eCAP1 안정화를 위해 1ms 지연 (200e6 * 0.001 = 200,000틱)
DEVICE_DELAY_US(1000);
// eCAP 카운터 시작
ECap_startCounter(ECAP1_BASE);
// 무한 루프
for(;;)
{
// overflowCount로 오버플로우 횟수 확인
// 오버플로우 주기 = 2^32 / 200e6 = 21.47483648초
DEVICE_DELAY_US(1000000); // 1초 대기 (200e6 * 1 = 200,000,000틱)
}
}
설명:
- 기능: eCAP1 카운터 오버플로우 이벤트를 인터럽트로 감지.
- 설정: GPIO:
initECAPGPIO(24, true)
로 입력 핀 설정, eCAP: 연속 캡처, 상승 에지, 오버플로우 인터럽트, 계산식: 오버플로우 주기 = 2^32 / 200e6 = 21.47483648초. - 결과: overflowCount에 오버플로우 횟수 저장.
- 주기: 인터럽트 기반, 1초 대기.
5. 추가 고려 사항
- 타임스탬프 단위: 타임스탬프는 SYSCLK(200MHz) 틱 단위로 기록됩니다. 시간(초) = 타임스탬프 * (1 / 200e6) = 타임스탬프 * 5e-9.
- 프리스케일러: 고속 신호 캡처 시 프리스케일러(ECap_setEventPrescaler)를 조정하여 카운터 오버플로우 방지.
- GPIO 설정: 입력은 비동기 모드(GPIO_QUAL_ASYNC), 출력은 표준 출력(GPIO_PIN_TYPE_STD)으로 설정.
- C2000Ware: 코드는 C2000Ware의 DriverLib(C:\ti\c2000)를 기반으로 작성되었습니다.
- 디버깅: CCS의 .syscfg GUI 툴로 eCAP 설정을 시각적으로 구성 가능.
키워드: TMS320F28388D, eCAP, DriverLib, C2000, 캡처 모듈, PWM 분석, APWM, 마이크로컨트롤러, Code Composer Studio, ePWM 동기화
'MCU > C2000' 카테고리의 다른 글
[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 |
[TMS320F28388D] ePWM 사용법: DriverLib API로 ePWM 설정 및 코드 (0) | 2025.08.16 |
[TMS320F28335] 기반 PSFB 컨버터 설계 및 위상 천이 PWM 제어 코드 (PSFB Converter Design and TMS320F28335-Based Phase-Shift PWM Control Code) (0) | 2025.08.10 |
[TMS320F28335] LLC 공진 컨버터 설계 및 제어 코드 가이드 (0) | 2025.08.09 |
[TMS320F28388D] ADC 사용법: DriverLib API로 ADC 설정 및 코드 (0) | 2025.08.08 |