TI의 TMS320F28377D는 C2000 Delfino 시리즈의 32비트 마이크로컨트롤러로, 고속 PWM 애플리케이션에 최적화된 ePWM(Enhanced Pulse Width Modulation) 모듈과 CMPASS(Comparator Subsystem)를 제공합니다. CMPASS는 아날로그 신호를 디지털 트립 신호로 변환하여 ePWM의 트립 존(Trip Zone) 또는 디지털 비교기(Digital Compare, DC) 모듈과 연동, 과전류 보호 및 정밀 제어를 가능하게 합니다. 이 문서에서는 CMPASS 설정 방법과 Bitfield 구조를 활용한 세 가지 실용적인 예제 코드를 제공하여 초보자와 숙련된 개발자 모두가 쉽게 활용할 수 있도록 설명합니다.
1. CMPASS 개요
CMPASS는 ePWM 모듈과 결합된 아날로그 비교기 서브시스템으로, 외부 아날로그 신호(예: 전류 센서 출력)를 디지털 신호로 변환하여 트립 이벤트 또는 ADC 트리거를 생성합니다. 주요 특징은 다음과 같습니다:
- 입력: 아날로그 비교기(CMP1~CMP8)로 외부 신호 입력.
- 출력: 디지털 트립 신호(TZ1~TZ6) 또는 디지털 비교(DC) 이벤트.
- 기능:
- 과전류/과전압 보호를 위한 트립 존 트리거.
- ePWM 출력 제어(예: 출력 차단).
- ADC 트리거 또는 인터럽트 발생.
- 설정 레지스터:
- COMPCTL: 비교기 제어(활성화, 입력 선택 등).
- TZDCSEL: 트립 존 디지털 비교 선택.
- DCTRIPSEL: 디지털 비교기 입력 선택.
- TZSEL: 트립 존 소스 선택.
2. CMPSS Bitfield 설정 상세
CMPSS 관련 레지스터는 F2837xD_cmpss.h 및 F2837xD_epwm.h 헤더 파일을 통해 Bitfield 구조로 접근합니다. 주요 레지스터는 다음과 같습니다:
2.1 COMPCTL (비교기 제어 레지스터)
- bit.COMPDACE: 비교기 및 DAC 활성화 (1: 활성화).
- bit.COMPHSOURCE: High 비교기 입력 선택 (0: CMPxA 핀, 1: 내부 DAC).
- bit.COMPHINV: High 비교기 출력 반전 (0: 비반전, 1: 반전).
- bit.CTRIPHSEL: High 비교기 트립 출력 선택 (예: 2=DCAEVT1).
- bit.COMPLSOURCE: Low 비교기 입력 선택 (0: CMPxB 핀, 1: 내부 DAC).
- bit.COMPLINV: Low 비교기 출력 반전 (0: 비반전, 1: 반전).
- bit.CTRIPLSEL: Low 비교기 트립 출력 선택 (예: 2=DCBEVT1).
2.2 TZDCSEL (트립 존 디지털 비교 선택)
- bit.DCAEVT1: 디지털 비교기 A 이벤트 1 선택.
- bit.DCAEVT2: 디지털 비교기 A 이벤트 2 선택.
- bit.DCBEVT1: 디지털 비교기 B 이벤트 1 선택.
- bit.DCBEVT2: 디지털 비교기 B 이벤트 2 선택.
2.3 TZSEL (트립 존 선택)
- bit.CBC1: Cycle-by-Cycle 트립 소스 (DCAEVT1).
- bit.CBC2: Cycle-by-Cycle 트립 소스 (DCAEVT2).
- bit.OSHT1: One-Shot 트립 소스 (DCAEVT1).
- bit.OSHT2: One-Shot 트립 소스 (DCAEVT2).
2.4 DACHVALS (DAC High 값 레지스터)
- bit.DACVAL: High 비교기 DAC 기준 전압 (10비트, 예: 512=1.65V).
2.5 CTRIPHFILCTL (디지털 필터 제어 레지스터)
- bit.SAMPWIN: 샘플 윈도우 크기 (예: 8 샘플).
- bit.THRESH: 과반수 임계값 (예: 8개 중 5개).
- bit.FILINIT: 디지털 필터 초기화 (1: 초기화).
2.6 CTRIPHFILCLKCTL (디지털 필터 클럭 제어 레지스터)
- bit.CLKPRESCALE: 디지털 필터 클럭 프리스케일 (예: 4).
3. CMPSS 설정 절차
CMPSS를 ePWM과 연동하여 설정하는 단계는 다음과 같습니다:
- 시스템 초기화:
- InitSysCtrl()로 시스템 클럭 및 PLL 초기화.
- 인터럽트 비활성화 및 PIE 초기화 (DINT, InitPieCtrl, InitPieVectTable).
- CPU 인터럽트 레지스터 초기화 (IER=0x0000, IFR=0x0000).
- InitGpio()로 GPIO 기본 상태 설정.
- CMPSS 클럭 활성화:
- CpuSysRegs.PCLKCR14.bit.CMPSSx로 CMPSS 모듈 클럭 활성화.
- EALLOW와 EDIS로 보호된 레지스터 접근.
- 비교기 설정:
- COMPCTL.bit.COMPDACE로 비교기 및 DAC 활성화.
- COMPCTL.bit.COMPHSOURCE로 High 입력 소스 선택 (CMPxA).
- COMPCTL.bit.CTRIPHSEL로 트립 출력 설정 (DCAEVT1).
- DACHVALS.bit.DACVAL로 기준 전압 설정 (예: 512=1.65V).
- 디지털 필터 설정:
- CTRIPHFILCTL.bit.SAMPWIN으로 샘플 윈도우 설정 (예: 8).
- CTRIPHFILCTL.bit.THRESH로 임계값 설정 (예: 5).
- CTRIPHFILCTL.bit.FILINIT으로 필터 초기화.
- CTRIPHFILCLKCTL.bit.CLKPRESCALE로 클럭 분주 설정 (예: 4).
- 트립 존 연동:
- TZDCSEL.bit.DCAEVT1로 디지털 비교 이벤트 설정.
- TZSEL.bit.CBC1로 CMPSS 출력을 Cycle-by-Cycle 트립 소스로 선택.
- TZCTL.bit.TZA로 트립 이벤트 동작 설정 (예: TZ_FORCE_LO).
- ePWM 설정:
- TBCTL, CMPA, AQCTLA로 PWM 신호 설정 (예: 100kHz, 50% 듀티).
- TBCTL.bit.FREE_SOFT = 2로 Free Run 모드 활성화.
- 인터럽트 설정 (선택 사항):
- TZEINT.bit.CBC로 트립 존 인터럽트 활성화.
- PieVectTable.EPWM1_TZ_INT로 인터럽트 벡터 설정.
- PIE 및 CPU 인터럽트 활성화 (PIEIER2.bit.INTx1, IER |= M_INT2).
4. CMPASS 설정 고려사항
- 입력 신호: CMPSS 입력 핀(예: CMP1A)에 전류 센서 또는 전압 분배기 연결.
- DAC 기준 전압: 내부 DAC(10비트, 0~3.3V)로 기준 전압 설정.
- 트립 조건: 과전류 시 CMPSS 출력이 High일 때 트립 이벤트 발생.
- 필터링: COMPDACCTL.bit.DCFILTEN으로 입력 노이즈 감소.
- 동기화: 다중 CMPSS 모듈 사용 시 동기화 고려.
5. CMPASS 예제 코드 (Bitfield 구조)
아래는 TMS320F28377D에서 CMPASS와 ePWM을 연동한 세 가지 예제 코드입니다. 각 코드는 Code Composer Studio(CCS)와 C2000Ware 환경에서 실행 가능합니다.
5.1 예제 1: CMPASS를 이용한 과전류 보호
// File: epwm_cmpss_trip_blinky.c
// Description: TMS320F28377D에서 CMPSS와 ePWM을 연동하여 과전류 보호를 구현하고,
// GPIO31에서 500ms 주기로 LED를 깜빡이는 예제 (C2000Ware 6.0.0.0 호환)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D
#include "F28x_Project.h"
// GPIO 핀 정의
#define BLINKY_LED_GPIO 31 // LED 출력 핀 (GPIO31)
#define EPWM1A_GPIO 0 // ePWM1A 출력 핀 (GPIO0)
#define CMP1A_GPIO 12 // CMPSS1 입력 핀 (CMP1A, GPIO12)
// 함수 선언
void setupGpio(void); // GPIO 설정 함수 선언
// GPIO 설정 함수
// 역할: GPIO0(ePWM1A), GPIO31(LED), GPIO12(CMP1A)를 초기화
void setupGpio(void)
{
EALLOW; // 보호된 레지스터 접근 허용
// GPIO0: ePWM1A 출력 설정
GPIO_SetupPinMux(EPWM1A_GPIO, GPIO_MUX_CPU1, 1); // GPIO0을 ePWM1A로 설정 (멀티플렉서 설정)
GPIO_SetupPinOptions(EPWM1A_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL); // 출력 모드, 푸시풀 출력
// GPIO31: LED 출력 설정
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 초기 상태: 켜짐
// GPIO12: CMP1A 아날로그 입력 설정
GPIO_SetupPinMux(CMP1A_GPIO, GPIO_MUX_CPU1, 0); // GPIO12를 일반 GPIO로 설정 (CMP1A 아날로그 입력)
GPIO_SetupPinOptions(CMP1A_GPIO, GPIO_INPUT, GPIO_PULLUP); // 입력 모드, 내부 풀업 저항 활성화
EDIS; // 보호된 레지스터 접근 비활성화
}
// 인터럽트 서비스 루틴 (ISR): ePWM1 트립 존 이벤트 처리
__interrupt void epwm1_tz_isr(void)
{
// 트립 플래그 클리어
EPwm1Regs.TZCLR.bit.CBC = 1; // Cycle-by-Cycle 트립 플래그 클리어
EPwm1Regs.TZCLR.bit.INT = 1; // 인터럽트 플래그 클리어
PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; // PIE 그룹 2 인터럽트 확인 (Acknowledge)
}
void main(void)
{
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭, PLL, 주변장치 초기화
InitGpio(); // 모든 GPIO를 기본 상태로 초기화 (입력 모드, 풀업 비활성화)
// 인터럽트 초기화
DINT; // 글로벌 인터럽트 비활성화
InitPieCtrl(); // PIE (Peripheral Interrupt Expansion) 컨트롤러 초기화
IER = 0x0000; // CPU 인터럽트 인에이블 레지스터 초기화
IFR = 0x0000; // CPU 인터럽트 플래그 레지스터 초기화
InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화
// 인터럽트 벡터 설정
EALLOW; // 보호된 레지스터 접근 허용
PieVectTable.EPWM1_TZ_INT = &epwm1_tz_isr; // ePWM1 트립 존 인터럽트 벡터를 ISR에 연결
EDIS; // 보호된 레지스터 접근 비활성화
// GPIO 설정
setupGpio(); // 사용자 정의 GPIO 설정 함수 호출 (ePWM1A, LED, CMP1A 설정)
// 주변장치 클럭 활성화
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR14.bit.CMPSS1 = 1; // CMPSS1 모듈 클럭 활성화
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
EDIS; // 보호된 레지스터 접근 비활성화
// CMPSS1 설정: 아날로그 비교기 및 DAC 설정
EALLOW; // 보호된 레지스터 접근 허용
Cmpss1Regs.COMPCTL.bit.COMPDACE = 1; // 비교기 및 DAC 활성화
Cmpss1Regs.COMPCTL.bit.COMPHSOURCE = 0; // High 비교기 입력: CMP1A (양극 입력)
Cmpss1Regs.COMPCTL.bit.COMPHINV = 0; // High 비교기 출력 비반전 (출력 논리 반전 없음)
Cmpss1Regs.COMPCTL.bit.CTRIPHSEL = 2; // High 비교기 트립 출력: DCAEVT1로 연결
Cmpss1Regs.DACHVALS.bit.DACVAL = 512; // DAC 기준 전압 설정 (1.65V, 3.3V 기준 10비트 중간값)
// 디지털 필터 설정: High 비교기 출력의 노이즈 제거
Cmpss1Regs.CTRIPHFILCTL.bit.SAMPWIN = 8; // 샘플 윈도우 크기: 8 샘플
Cmpss1Regs.CTRIPHFILCTL.bit.THRESH = 5; // 과반수 임계값: 8개 중 5개 이상 High일 때 트립
Cmpss1Regs.CTRIPHFILCTL.bit.FILINIT = 1; // 디지털 필터 초기화
Cmpss1Regs.CTRIPHFILCLKCTL.bit.CLKPRESCALE = 4; // 필터 클럭 프리스케일: 시스템 클럭 분주
EDIS; // 보호된 레지스터 접근 비활성화
// ePWM1 트립 존 설정: CMPSS1과 연동하여 과전류 보호 구현
EALLOW; // 보호된 레지스터 접근 허용
EPwm1Regs.TZDCSEL.bit.DCAEVT1 = 1; // DCAEVT1 활성화 (CMPSS1 High 출력 트리거)
EPwm1Regs.TZSEL.bit.DCAEVT1 = 1; // DCAEVT1을 Cycle-by-Cycle 트립 소스로 선택
EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // 트립 발생 시 ePWM1A 출력을 Low로 강제
EPwm1Regs.TZEINT.bit.CBC = 1; // Cycle-by-Cycle 트립 인터럽트 활성화
PieCtrlRegs.PIEIER2.bit.INTx1 = 1; // PIE 그룹 2, EPWM1_TZ_INT 활성화
IER |= M_INT2; // CPU 인터럽트 그룹 2 활성화
EDIS; // 보호된 레지스터 접근 비활성화
// ePWM1 설정: 100kHz, 50% 듀티 PWM 신호 생성
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 타이머 동작 모드: 업 카운트
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비: 1/1 (TBCLK = SYSCLK)
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // 고속 클럭 분주비: 1/1 (TBCLK = 200MHz)
EPwm1Regs.TBPRD = 2000; // PWM 주기: 2000 TBCLK = 100kHz (200MHz/2000)
EPwm1Regs.CMPA.bit.CMPA = 1000; // 듀티 사이클: 50% (CMPA = TBPRD/2)
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 ePWM1A 출력 High
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 ePWM1A 출력 Low
EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free Run 모드: 에뮬레이션 중에도 동작 지속
EINT; // 글로벌 인터럽트 활성화
ERTM; // 실시간 디버깅 모드 활성화
// 메인 루프: LED를 500ms 주기로 깜빡임
for(;;)
{
GPIO_WritePin(BLINKY_LED_GPIO, 0); // LED 끄기
DELAY_US(1000 * 500); // 500ms 대기
GPIO_WritePin(BLINKY_LED_GPIO, 1); // LED 켜기
DELAY_US(1000 * 500); // 500ms 대기
}
}
설명:
- 기능: CMPSS1을 사용하여 GPIO12(CMP1A)에 입력된 아날로그 신호를 기준 전압(1.65V)과 비교, 과전류 발생 시 ePWM1A 출력을 차단하고 트립 존 인터럽트를 통해 LED를 토글.
- 설정:
- CMPSS1: 비교기 활성화, CMP1A 입력, DAC 기준 전압 1.65V.
- 트립 존: CMP1_OUT을 DCAEVT1로 연결, 트립 시 PWM_A Low.
- ePWM1: 100kHz, 50% 듀티, 업 카운트 모드.
- 인터럽트: 트립 존 이벤트(CBC)에서 인터럽트 발생.
- GPIO: GPIO0(ePWM1A), GPIO12(CMP1A 입력), GPIO31(LED).
- 출력: 정상 동작 시 GPIO0에 PWM 신호 출력, CMP1A 입력이 1.65V 초과 시 PWM 출력 차단 및 LED 토글.
5.2 예제 2: CMPASS와 ADC 트리거 연동
// File: epwm_cmpss_adc_trigger.c
// Description: TMS320F28377D에서 CMPSS와 ePWM을 연동하여 ADC를 트리거하고,
// 과전류 감지 및 ADC 결과에 따라 GPIO31에서 LED를 토글하는 예제
// (C2000Ware 6.0.0.0 호환, Bitfield 구조, AdcSetMode 및 F2837xD_adc.h 사용)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D
#include "F28x_Project.h"
// GPIO 핀 정의
#define BLINKY_LED_GPIO 31 // LED 출력 핀 (GPIO31)
#define EPWM1A_GPIO 0 // ePWM1A 출력 핀 (GPIO0)
#define CMP1A_GPIO 12 // CMPSS1 입력 핀 (CMP1A, GPIO12)
// 함수 선언
void setupGpio(void); // GPIO 설정 함수 선언
// GPIO 설정 함수
// 역할: GPIO0(ePWM1A), GPIO31(LED), GPIO12(CMP1A)를 초기화
void setupGpio(void)
{
EALLOW; // 보호된 레지스터 접근 허용
// GPIO0: ePWM1A 출력 설정
GPIO_SetupPinMux(EPWM1A_GPIO, GPIO_MUX_CPU1, 1); // GPIO0을 ePWM1A로 설정 (멀티플렉서 설정)
GPIO_SetupPinOptions(EPWM1A_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL); // 출력 모드, 푸시풀 출력
// GPIO31: LED 출력 설정
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 초기 상태: 켜짐
// GPIO12: CMP1A 아날로그 입력 설정
GPIO_SetupPinMux(CMP1A_GPIO, GPIO_MUX_CPU1, 0); // GPIO12를 일반 GPIO로 설정 (CMP1A 아날로그 입력)
GPIO_SetupPinOptions(CMP1A_GPIO, GPIO_INPUT, GPIO_PULLUP); // 입력 모드, 내부 풀업 저항 활성화
EDIS; // 보호된 레지스터 접근 비활성화
}
// 인터럽트 서비스 루틴 (ISR): ADC 인터럽트 처리
__interrupt void adc1_isr(void)
{
// ADC 결과 읽기 및 LED 토글
Uint16 adc_result = AdcaResultRegs.ADCRESULT0; // ADC_A 채널 A0의 변환 결과 읽기 (12비트)
GPIO_WritePin(BLINKY_LED_GPIO, !GPIO_ReadPin(BLINKY_LED_GPIO)); // GPIO31(LED) 상태 토글
// ADC 인터럽트 플래그 클리어
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // ADCINT1 플래그 클리어
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // PIE 그룹 1 인터럽트 확인 (Acknowledge)
}
void main(void)
{
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭, PLL, 주변장치 초기화
InitGpio(); // 모든 GPIO를 기본 상태로 초기화 (입력 모드, 풀업 비활성화)
// 인터럽트 초기화
DINT; // 글로벌 인터럽트 비활성화
InitPieCtrl(); // PIE (Peripheral Interrupt Expansion) 컨트롤러 초기화
IER = 0x0000; // CPU 인터럽트 인에이블 레지스터 초기화
IFR = 0x0000; // CPU 인터럽트 플래그 레지스터 초기화
InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화
// 인터럽트 벡터 설정
EALLOW; // 보호된 레지스터 접근 허용
PieVectTable.ADCA1_INT = &adc1_isr; // ADC_A 인터럽트 1 벡터를 ISR에 연결
EDIS; // 보호된 레지스터 접근 비활성화
// GPIO 설정
setupGpio(); // 사용자 정의 GPIO 설정 함수 호출 (ePWM1A, LED, CMP1A 설정)
// ADC 설정: AdcSetMode 및 수동 설정
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR13.bit.ADC_A = 1; // ADC_A 모듈 클럭 활성화
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; // ADC_A 전원 활성화
AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); // ADC_A: 12비트 해상도, 단일 입력 모드
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; // ADC 인터럽트 펄스 위치: 변환 완료 시 발생
AdcaRegs.ADCCTL2.bit.PRESCALE = 6; // ADC 클럭 분주비: SYSCLK/12 (200MHz/12 = 16.67MHz)
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; // ADCINT1 소스: SOC0 (Start of Conversion 0)
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; // ADCINT1 인터럽트 활성화
AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 0; // ADCINT1 단일 인터럽트 모드 (지속 인터럽트 비활성화)
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; // ADC 채널: A0 선택
AdcaRegs.ADCSOC0CTL.bit.ACQPS = 15; // 샘플링 윈도우: 15 SYSCLK 사이클 (90ns at 16.67MHz)
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // 트리거 소스: ePWM1 SOCA
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // PIE 그룹 1, ADCINT1 활성화
IER |= M_INT1; // CPU 인터럽트 그룹 1 활성화
EDIS; // 보호된 레지스터 접근 비활성화
// 주변장치 클럭 활성화
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR14.bit.CMPSS1 = 1; // CMPSS1 모듈 클럭 활성화
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
EDIS; // 보호된 레지스터 접근 비활성화
// CMPSS1 설정: 아날로그 비교기 및 DAC 설정
EALLOW; // 보호된 레지스터 접근 허용
Cmpss1Regs.COMPCTL.bit.COMPDACE = 1; // 비교기 및 DAC 활성화
Cmpss1Regs.COMPCTL.bit.COMPHSOURCE = 0; // High 비교기 입력: CMP1A (양극 입력)
Cmpss1Regs.COMPCTL.bit.COMPHINV = 0; // High 비교기 출력 비반전 (출력 논리 반전 없음)
Cmpss1Regs.COMPCTL.bit.CTRIPHSEL = 2; // High 비교기 트립 출력: DCAEVT1로 연결
Cmpss1Regs.DACHVALS.bit.DACVAL = 512; // DAC 기준 전압 설정 (1.65V, 3.3V 기준 10비트 중간값)
// 디지털 필터 설정: High 비교기 출력의 노이즈 제거
Cmpss1Regs.CTRIPHFILCTL.bit.SAMPWIN = 8; // 샘플 윈도우 크기: 8 샘플
Cmpss1Regs.CTRIPHFILCTL.bit.THRESH = 5; // 과반수 임계값: 8개 중 5개 이상 High일 때 트립
Cmpss1Regs.CTRIPHFILCTL.bit.FILINIT = 1; // 디지털 필터 초기화
Cmpss1Regs.CTRIPHFILCLKCTL.bit.CLKPRESCALE = 4; // 필터 클럭 프리스케일: 시스템 클럭 분주
EDIS; // 보호된 레지스터 접근 비활성화
// ePWM1 트립 존 설정: CMPSS1과 연동하여 과전류 보호 구현
EALLOW; // 보호된 레지스터 접근 허용
EPwm1Regs.TZDCSEL.bit.DCAEVT1 = 1; // DCAEVT1 활성화 (CMPSS1 High 출력 트리거)
EPwm1Regs.TZSEL.bit.DCAEVT1 = 1; // DCAEVT1을 Cycle-by-Cycle 트립 소스로 선택
EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // 트립 발생 시 ePWM1A 출력을 Low로 강제
EDIS; // 보호된 레지스터 접근 비활성화
// ePWM1 설정: 100kHz, 50% 듀티 PWM 신호 생성 및 ADC 트리거
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 타이머 동작 모드: 업 카운트
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비: 1/1 (TBCLK = SYSCLK)
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // 고속 클럭 분주비: 1/1 (TBCLK = 200MHz)
EPwm1Regs.TBPRD = 2000; // PWM 주기: 2000 TBCLK = 100kHz (200MHz/2000)
EPwm1Regs.CMPA.bit.CMPA = 1000; // 듀티 사이클: 50% (CMPA = TBPRD/2)
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 ePWM1A 출력 High
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 ePWM1A 출력 Low
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // SOCA (Start of Conversion A) 활성화
EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // SOCA 트리거: TBCTR=0일 때 발생
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // SOCA 주기: 첫 번째 이벤트에서 발생
EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free Run 모드: 에뮬레이션 중에도 동작 지속
EINT; // 글로벌 인터럽트 활성화
ERTM; // 실시간 디버깅 모드 활성화
// 메인 루프: 무한 대기 (ADC와 ePWM이 하드웨어로 동작)
for(;;);
}
설명:
- 기능: CMPSS1을 사용하여 GPIO12(CMP1A)에 입력된 아날로그 신호를 기준 전압(1.65V)과 비교, ePWM1의 SOCA 트리거를 통해 ADC 변환을 시작하고, ADC 인터럽트를 통해 결과를 읽어 LED를 토글.
- 설정:
- CMPSS1: 비교기 활성화, CMP1A 입력, DAC 기준 전압 1.65V, 디지털 필터 활성화.
- ePWM1: 100kHz, 50% 듀티, SOCA 트리거 활성화.
- ADC: 채널 A0, ePWM1 SOCA 트리거로 변환 시작.
- 인터럽트: ADCINT1 활성화.
- GPIO: GPIO0(ePWM1A), GPIO12(CMP1A 입력), GPIO31(LED).
- 출력: GPIO0에 PWM 신호 출력, CMP1A 입력에 따라 ADC 변환 후 LED 토글.
5.3 예제 3: CMPASS 기반 듀티 사이클 조정
// File: epwm_cmpss_duty_adjust.c
// Description: TMS320F28377D에서 CMPSS와 ePWM을 연동하여 입력 전압에 따라
// ePWM1A의 듀티 사이클을 조정(25% 또는 75%)하는 예제
// (C2000Ware 6.0.0.0 호환, Bitfield 구조, F2837xD_cmpss.h 사용)
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28377D
#include "F28x_Project.h"
volatile Uint16 duty = 1000; // 초기 듀티 사이클 50% (CMPA=1000, TBPRD=2000)
// GPIO 핀 정의
#define BLINKY_LED_GPIO 31 // LED 출력 핀 (GPIO31)
#define EPWM1A_GPIO 0 // ePWM1A 출력 핀 (GPIO0)
#define CMP1A_GPIO 12 // CMPSS1 입력 핀 (CMP1A, GPIO12)
// 함수 선언
void setupGpio(void); // GPIO 설정 함수 선언
// GPIO 설정 함수
// 역할: GPIO0(ePWM1A), GPIO31(LED), GPIO12(CMP1A)를 초기화
void setupGpio(void)
{
EALLOW; // 보호된 레지스터 접근 허용
// GPIO0: ePWM1A 출력 설정
GPIO_SetupPinMux(EPWM1A_GPIO, GPIO_MUX_CPU1, 1); // GPIO0을 ePWM1A로 설정 (멀티플렉서 설정)
GPIO_SetupPinOptions(EPWM1A_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL); // 출력 모드, 푸시풀 출력
// GPIO31: LED 출력 설정
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 초기 상태: 켜짐
// GPIO12: CMP1A 아날로그 입력 설정
GPIO_SetupPinMux(CMP1A_GPIO, GPIO_MUX_CPU1, 0); // GPIO12를 일반 GPIO로 설정 (CMP1A 아날로그 입력)
GPIO_SetupPinOptions(CMP1A_GPIO, GPIO_INPUT, GPIO_PULLUP); // 입력 모드, 내부 풀업 저항 활성화
EDIS; // 보호된 레지스터 접근 비활성화
}
// 인터럽트 서비스 루틴 (ISR): 트립 존 인터럽트 처리
__interrupt void tz1_isr(void)
{
// CMPSS 출력에 따라 듀티 사이클 조정
if (Cmpss1Regs.COMPSTS.bit.COMPHSTS == 1) // CMP1A 입력 > 기준 전압 (1.65V)
{
duty = 500; // 듀티 사이클 25% (CMPA=500, TBPRD=2000)
}
else
{
duty = 1500; // 듀티 사이클 75% (CMPA=1500, TBPRD=2000)
}
EPwm1Regs.CMPA.bit.CMPA = duty; // ePWM1A 듀티 사이클 업데이트
// 트립 플래그 클리어
EPwm1Regs.TZCLR.bit.CBC = 1; // Cycle-by-Cycle 트립 플래그 클리어
EPwm1Regs.TZCLR.bit.INT = 1; // 트립 인터럽트 플래그 클리어
PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; // PIE 그룹 2 인터럽트 확인 (Acknowledge)
}
void main(void)
{
// 시스템 초기화
InitSysCtrl(); // 시스템 클럭, PLL, 주변장치 초기화
InitGpio(); // 모든 GPIO를 기본 상태로 초기화 (입력 모드, 풀업 비활성화)
DINT; // 글로벌 인터럽트 비활성화
InitPieCtrl(); // PIE (Peripheral Interrupt Expansion) 컨트롤러 초기화
IER = 0x0000; // CPU 인터럽트 인에이블 레지스터 초기화
IFR = 0x0000; // CPU 인터럽트 플래그 레지스터 초기화
InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화
// 인터럽트 벡터 설정
EALLOW; // 보호된 레지스터 접근 허용
PieVectTable.EPWM1_TZ_INT = &tz1_isr; // ePWM1 트립 존 인터럽트 벡터를 ISR에 연결
EDIS; // 보호된 레지스터 접근 비활성화
// GPIO 설정
setupGpio(); // 사용자 정의 GPIO 설정 함수 호출 (ePWM1A, LED, CMP1A 설정)
// 주변장치 클럭 활성화
EALLOW; // 보호된 레지스터 접근 허용
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
CpuSysRegs.PCLKCR14.bit.CMPSS1 = 1; // CMPSS1 모듈 클럭 활성화
EDIS; // 보호된 레지스터 접근 비활성화
// CMPSS1 설정: 아날로그 비교기 및 DAC 설정
EALLOW; // 보호된 레지스터 접근 허용
Cmpss1Regs.COMPCTL.bit.COMPDACE = 1; // 비교기 및 DAC 활성화
Cmpss1Regs.COMPCTL.bit.COMPHSOURCE = 0; // High 비교기 입력: CMP1A (양극 입력)
Cmpss1Regs.COMPCTL.bit.COMPHINV = 0; // High 비교기 출력 비반전 (출력 논리 반전 없음)
Cmpss1Regs.COMPCTL.bit.CTRIPHSEL = 2; // High 비교기 트립 출력: DCAEVT1로 연결
Cmpss1Regs.DACHVALS.bit.DACVAL = 512; // DAC 기준 전압 설정 (1.65V, 3.3V 기준 10비트 중간값)
// 디지털 필터 설정: High 비교기 출력의 노이즈 제거
Cmpss1Regs.CTRIPHFILCTL.bit.SAMPWIN = 8; // 샘플 윈도우 크기: 8 샘플
Cmpss1Regs.CTRIPHFILCTL.bit.THRESH = 5; // 과반수 임계값: 8개 중 5개 이상 High일 때 트립
Cmpss1Regs.CTRIPHFILCTL.bit.FILINIT = 1; // 디지털 필터 초기화
Cmpss1Regs.CTRIPHFILCLKCTL.bit.CLKPRESCALE = 4; // 필터 클럭 프리스케일: 시스템 클럭 분주
EDIS; // 보호된 레지스터 접근 비활성화
// ePWM1 트립 존 설정: CMPSS1과 연동하여 듀티 사이클 조정
EALLOW; // 보호된 레지스터 접근 허용
EPwm1Regs.TZDCSEL.bit.DCAEVT1 = 1; // DCAEVT1 활성화 (CMPSS1 High 출력 트리거)
EPwm1Regs.TZSEL.bit.DCAEVT1 = 1; // DCAEVT1을 Cycle-by-Cycle 트립 소스로 선택
EPwm1Regs.TZEINT.bit.CBC = 1; // Cycle-by-Cycle 트립 인터럽트 활성화
PieCtrlRegs.PIEIER2.bit.INTx1 = 1; // PIE 그룹 2, EPWM1_TZ_INT 인터럽트 활성화
IER |= M_INT2; // CPU 인터럽트 그룹 2 활성화
EDIS; // 보호된 레지스터 접근 비활성화
// ePWM1 설정: 100kHz, 초기 50% 듀티 PWM 신호 생성
EALLOW; // 보호된 레지스터 접근 허용
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 타이머 동작 모드: 업 카운트
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비: 1/1 (TBCLK = SYSCLK)
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // 고속 클럭 분주비: 1/1 (TBCLK = 200MHz)
EPwm1Regs.TBPRD = 2000; // PWM 주기: 2000 TBCLK = 100kHz (200MHz/2000)
EPwm1Regs.CMPA.bit.CMPA = duty; // 초기 듀티 사이클: 50% (CMPA=1000)
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 ePWM1A 출력 High
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 ePWM1A 출력 Low
EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free Run 모드: 에뮬레이션 중에도 동작 지속
EDIS; // 보호된 레지스터 접근 비활성화
EINT; // 글로벌 인터럽트 활성화
ERTM; // 실시간 디버깅 모드 활성화
// 메인 루프: 무한 대기 (CMPSS와 ePWM이 하드웨어로 동작)
for(;;);
}
설명:
- 기능: CMPSS1을 사용하여 GPIO12(CMP1A)에 입력된 아날로그 신호를 기준 전압(1.65V)과 비교, 입력 전압에 따라 ePWM1A의 듀티 사이클을 25% 또는 75%로 동적 조정.
- 설정:
- CMPSS1: 비교기 활성화, CMP1A 입력, DAC 기준 전압 1.65V, 디지털 필터 활성화.
- ePWM1: 100kHz, 초기 50% 듀티, 업 카운트 모드.
- 인터럽트: CMPSS 출력에 따라 듀티 사이클 조정.
- GPIO: GPIO0(ePWM1A), GPIO12(CMP1A 입력), GPIO31(LED).
- 출력: GPIO0에 PWM 신호 출력, CMP1A 입력에 따라 듀티 사이클 25% 또는 75%로 전환, 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 하드웨어 준비
- PWM 출력: GPIO0(ePWM1A)에 오실로스코프 연결.
- CMPSS 입력: GPIO12(CMP1A)에 전류 센서 또는 아날로그 신호(0~3.3V) 연결.
- LED: GPIO31에 LED 연결.
- 테스트:
- 예제 1: CMP1A에 1.65V 초과 신호 입력 시 PWM 출력 차단 확인.
- 예제 2: ADC 변환 결과 및 LED 토글 확인.
- 예제 3: CMP1A 입력 변화에 따른 듀티 사이클 변화 확인.
6.4 디버깅
- CCS Expressions 창: EPwm1Regs.TBCTR, EPwm1Regs.CMPA, Cmpss1Regs.COMPSTS 확인.
- 트립 상태: EPwm1Regs.TZFLG로 트립 이벤트 점검.
- 레지스터 모니터링: Cmpss1Regs.COMPCTL, EPwm1Regs.TZCTL, AdcARegs.ADCRESULT0 확인.
7. 추가 팁
- DAC 기준 전압 조정: DACVAL 값을 변경하여 트립 임계값 조정.
- 필터링: COMPDACCTL.bit.DCFILTEN 활성화로 입력 노이즈 감소.
- C2000Ware 참고: C:\ti\c2000\C2000Ware_x_xx_xx_xx\device_support\f2837xd\examples\cpu1\cmpss.
- 문제 해결:
- PWM 출력 문제: TBCTL, AQCTLA, TZSEL 설정 확인.
- 트립 이벤트 미발생: Cmpss1Regs.COMPSTS, DCTRIPSEL 확인.
- ADC/인터럽트 실패: ETSEL, PIEIER, IER 설정 확인.
- TI 리소스: TI E2E 포럼, C2000Ware CMPSS 예제.
8. 결론
이 문서는 TMS320F28377D의 CMPASS와 ePWM을 연동하여 과전류 보호, ADC 트리거, 듀티 사이클 조정을 구현하는 방법을 Bitfield 구조 기반 예제 코드로 설명했습니다. 이 코드는 모터 제어, 전력 변환 등 다양한 애플리케이션에 활용 가능합니다.
키워드: TMS320F28377D, ePWM, CMPASS, C2000, 과전류 보호, ADC 트리거, 듀티 사이클 조정, Bitfield, Code Composer Studio, 아날로그 비교기, 디지털 비교기
'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 SDFM 사용법 : Bitfield 구조 활용 예제 코드(수정) (1) | 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 |