본문 바로가기
MCU/C2000

[TMS320F28335] ePWM 사용법 : Bitfield 구조 활용 예제 코드

by linuxgo 2025. 8. 18.
반응형

1. TMS320F28335 ePWM 모듈 개요

TI의 TMS320F28335는 C2000 Delfino 시리즈의 32비트 마이크로컨트롤러로, 모터 제어, 전력 변환, LED 조명 등 고속 PWM 애플리케이션에 적합합니다. ePWM(Enhanced Pulse Width Modulation) 모듈은 고해상도 PWM 신호 생성, 타이밍 제어, 트리거 생성 기능을 제공합니다. 이 문서에서는 TMS320F28335 ePWM 모듈의 설정 방법, Bitfield 구조를 활용한 레지스터 설정, 그리고 실용적인 예제 코드를 제공하여 초보자와 숙련된 개발자 모두 쉽게 활용할 수 있도록 돕습니다.

주요 사양

  • 클럭 소스: 시스템 클럭(SYSCLK, 최대 150MHz)
  • 해상도: 150ps (고해상도 PWM 모드, HRPWM)
  • 타이머: 16비트 타임-베이스(TB) 카운터
  • 카운터 모드:
    • 업 카운트(Up-Count)
    • 다운 카운트(Down-Count)
    • 업-다운 카운트(Up-Down-Count)
  • 출력: 각 모듈당 2개 출력(PWMA, PWMB)
  • 주요 기능:
    • PWM 듀티 및 주기 제어
    • 데드밴드(Deadband) 생성
    • 이벤트 트리거(SOCA, SOCB)로 ADC 트리거
    • 트립 존(Trip Zone)으로 보호 기능
    • 고해상도 PWM(HRPWM) 지원
  • 인터럽트: TBCTR 이벤트, 트립 존, ADC 트리거
  • 동기화: 다중 ePWM 모듈 간 동기화 지원
  • 모듈 수: 최대 6개의 독립적인 ePWM 모듈(ePWM1~ePWM6)

2. ePWM Bitfield 설정 상세

TMS320F28335의 ePWM 레지스터는 Bitfield 구조로 정의되어 있으며, F2833x_epwm.h 헤더 파일을 통해 접근합니다. 주요 레지스터는 다음과 같습니다:

2.1 TBCTL (타임-베이스 제어 레지스터)

  • bit.CTRMODE: 카운터 모드 (0: 업, 1: 다운, 2: 업-다운, 3: 정지)
  • bit.PHSEN: 위상 동기화 활성화 (1: 활성화)
  • bit.PRDLD: 주기 레지스터 로드 타이밍 (0: 즉시, 1: 제로 또는 동기화 시)
  • bit.SYNCOSEL: 동기화 출력 선택 (0: EPWMxSYNC, 1: TBCTR=0 등)
  • bit.CLKDIV: 클럭 분주비 (07, 1/11/128)

2.2 CMPCTL (비교 제어 레지스터)

  • bit.LOADAMODE: CMPA 로드 타이밍 (0: TBCTR=0, 1: TBCTR=PRD)
  • bit.LOADBMODE: CMPB 로드 타이밍
  • bit.SHDWAMODE: CMPA 섀도우 모드 (0: 섀도우, 1: 즉시)
  • bit.SHDWBMODE: CMPB 섀도우 모드

2.3 AQCTLx (액션 퀄리파이어 제어 레지스터, x=A/B)

  • bit.ZRO: TBCTR=0일 때 동작 (0: 무시, 1: Low, 2: High, 3: 토글)
  • bit.PRD: TBCTR=PRD일 때 동작
  • bit.CAU: TBCTR=CMPA(증가)일 때 동작
  • bit.CAD: TBCTR=CMPA(감소)일 때 동작

2.4 DBCTL (데드밴드 제어 레지스터)

  • bit.OUT_MODE: 출력 모드 (0: 비활성화, 3: 완전 활성화)
  • bit.POLSEL: 극성 선택 (0: Active High, 2: Active Low Complementary)
  • bit.IN_MODE: 입력 소스 (0: PWMA, 1: PWMB)

2.5 ETSEL (이벤트 트리거 선택 레지스터)

  • bit.SOCAEN: SOCA 활성화 (1: 활성화)
  • bit.SOCASEL: SOCA 트리거 조건 (0: TBCTR=0, 1: TBCTR=PRD 등)
  • bit.INTEN: 인터럽트 활성화 (1: 활성화)
  • bit.INTSEL: 인터럽트 조건

2.6 HRCTL (고해상도 PWM 제어 레지스터)

  • bit.HRPE: HRPWM 활성화 (1: 활성화)
  • bit.TBPHSHR: 위상 고해상도 조정
  • bit.CMPAHR: 비교 값 고해상도 조정

3. ePWM 설정 절차

  1. 시스템 초기화:
    •    InitSysCtrl()로 시스템 클럭과 PLL 초기화
    •    인터럽트 비활성화 및 PIE 초기화 (DINT, InitPieCtrl, InitPieVectTable)
  2. ePWM 클럭 활성화:
    •    CpuSysRegs.PCLKCR1.bit.EPWMx = 1로 ePWM 모듈(x=1~6) 클럭 활성화
    •    HRPWM 사용 시 CpuSysRegs.PCLKCR0.bit.HRPWM = 1
    •    보호된 레지스터 접근을 위해 EALLOW와 EDIS 사용
  3. 타임-베이스(TB) 설정:
    •    TBCTL.bit.CTRMODE로 카운터 모드 선택
    •    TBCTL.bit.CLKDIV와 TBCTL.bit.HSPCLKDIV로 클럭 분주비 설정
    •    TBPRD로 PWM 주기 설정 (TBPRD = SYSCLK/(PWM 주파수 * CLKDIV * HSPCLKDIV))
  4. 비교(CMP) 설정:
    •    CMPA.bit.CMPA 또는 CMPB.bit.CMPB로 듀티 사이클 설정
    •    CMPCTL.bit.LOADAMODE와 CMPCTL.bit.SHDWAMODE로 로드 타이밍 설정
  5. 액션 퀄리파이어(AQ) 설정:
    •    AQCTLA 또는 AQCTLB에서 ZRO, PRD, CAU, CAD 설정
  6. 데드밴드(DB) 설정 (필요 시):
    •    DBCTL.bit.OUT_MODE로 데드밴드 활성화
    •    DBRED와 DBFED로 지연 시간 설정
  7. 이벤트 트리거(ET) 설정 (필요 시):
    •    ETSEL.bit.SOCAEN과 ETSEL.bit.SOCASEL로 ADC 트리거 설정
    •    인터럽트 사용 시 ETSEL.bit.INTEN 설정
  8. HRPWM 설정 (필요 시):
    •    HRCNFG.bit.HRLOAD와 HRCNFG.bit.EDGMODE로 HRPWM 설정
    •    CMPA.bit.CMPAHR로 고해상도 듀티 조정
  9. 모듈 실행:
    •    TBCTL.bit.FREE_SOFT = 2로 Free Run 모드 활성화

4. ePWM 설정 고려사항

  • 클럭 설정: SYSCLK(150MHz)에서 TBCLK 분주 설정
  • 주기 및 듀티: TBPRD 및 CMPA/B로 설정
  • 데드밴드: 모터 제어 시 1us 이상 권장
  • 동기화: 다중 ePWM 모듈 간 위상 조정
  • HRPWM: 150ps 해상도 활용
  • 트립 존: 과전류/과전압 보호

5. 실용적인 ePWM 예제 코드 (Bitfield 구조)

아래는 TMS320F28335 ePWM 모듈을 Bitfield 구조로 설정한 7개의 예제 코드입니다. GPIO와 ePWM 설정은 별도의 함수로 분리되었으며, 각 라인에 상세한 주석이 추가되었습니다. Code Composer Studio(CCS)와 C2000Ware 환경에서 실행 가능합니다.

5.1 예제 1: 기본 PWM 생성 (업 카운트)

// File: epwm_basic_upcount.c
// Description: TMS320F28335 ePWM 기본 PWM(100kHz, 50% 듀티) 생성 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335

#include "F28x_Project.h"

// GPIO 설정 함수
void ConfigureGPIO(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0을 ePWM1A로 설정 (멀티플렉서 설정)
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
    GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
    EDIS; // 보호된 레지스터 접근 비허용
}

// ePWM1 설정 함수
void ConfigureEPWM1(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    CpuSysRegs.PCLKCR1.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
    EDIS; // 보호된 레지스터 접근 비허용

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 타임-베이스 카운터를 업 카운트 모드로 설정
    EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비 1/1 (SYSCLK = 150MHz)
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 2; // 고속 클럭 분주비 1/2 (TBCLK = 150MHz/2 = 75MHz)
    EPwm1Regs.TBPRD = 750; // 주기 레지스터 설정: 750 TBCLK = 10us (100kHz = 150MHz/2/750)
    EPwm1Regs.CMPA.bit.CMPA = 375; // 비교 레지스터 A 설정: 50% 듀티 사이클 (375/750)
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 PWM_A 출력을 High로 설정
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 PWM_A 출력을 Low로 설정
    EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드: 에뮬레이션 중에도 동작 계속
}

void main(void) {
    InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
    DINT; // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE(Peripheral Interrupt Expansion) 컨트롤러 초기화
    IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
    IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
    InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화

    ConfigureGPIO(); // GPIO 설정 함수 호출
    ConfigureEPWM1(); // ePWM1 설정 함수 호출

    for(;;); // 무한 루프: PWM 신호 지속 출력
}

설명:

  • 기능: ePWM1의 PWM_A 출력으로 100kHz, 50% 듀티 사이클 PWM 신호 생성
  • 설정: Up 카운터, 주기 750(100kHz @ 75MHz), CMPA=375(50% 듀티)
  • GPIO: GPIO0(ePWM1A), GPIO34(LED)
  • 출력: GPIO0에 PWM 신호 출력, LED ON

5.2 예제 2: 데드밴드 PWM (모터 제어용)

// File: epwm_deadband.c
// Description: TMS320F28335 ePWM 데드밴드 PWM 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335

#include "F28x_Project.h"

// GPIO 설정 함수
void ConfigureGPIO(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0을 ePWM1A로 설정
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // GPIO1을 ePWM1B로 설정
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
    GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
    EDIS; // 보호된 레지스터 접근 비허용
}

// ePWM1 설정 함수
void ConfigureEPWM1(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    CpuSysRegs.PCLKCR1.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
    EDIS; // 보호된 레지스터 접근 비허용

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP_DOWN; // 타임-베이스 카운터를 업-다운 카운트 모드로 설정
    EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비 1/1 (SYSCLK = 150MHz)
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 2; // 고속 클럭 분주비 1/2 (TBCLK = 150MHz/2 = 75MHz)
    EPwm1Regs.TBPRD = 375; // 주기 레지스터 설정: 375 TBCLK = 10us (100kHz = 150MHz/2/(2*375))
    EPwm1Regs.CMPA.bit.CMPA = 188; // 비교 레지스터 A 설정: 50% 듀티 사이클 (188/375)
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // TBCTR=CMPA(증가)일 때 PWM_A 출력을 High로 설정
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // TBCTR=CMPA(감소)일 때 PWM_A 출력을 Low로 설정

    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // 데드밴드 모듈 완전 활성화 (PWM_A와 PWM_B 모두 적용)
    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active High Complementary: PWM_B는 PWM_A의 상보 출력
    EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; // PWM_A를 데드밴드 입력 소스로 설정
    EPwm1Regs.DBRED.bit.DBRED = 75; // 상승 에지 지연 설정: 1us (75 TBCLK = 75 * 13.33ns)
    EPwm1Regs.DBFED.bit.DBFED = 75; // 하강 에지 지연 설정: 1us (75 TBCLK = 75 * 13.33ns)

    EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드: 에뮬레이션 중에도 동작 계속
}

void main(void) {
    InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
    DINT; // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 컨트롤러 초기화
    IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
    IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
    InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화

    ConfigureGPIO(); // GPIO 설정 함수 호출
    ConfigureEPWM1(); // ePWM1 설정 함수 호출

    for(;;); // 무한 루프: PWM 신호 지속 출력
}

설명:

  • 기능: ePWM1의 PWM_A, PWM_B 출력으로 100kHz, 50% 듀티 상보 PWM 신호 생성, 1us 데드밴드 포함
  • 설정: Up-Down 카운터, 주기 375(100kHz @ 75MHz), CMPA=188(50% 듀티), 데드밴드 75 TBCLK
  • GPIO: GPIO0(ePWM1A), GPIO1(ePWM1B), GPIO34(LED)
  • 출력: GPIO0, GPIO1에 상보 PWM 신호 출력, LED ON

5.3 예제 3: ADC 트리거를 위한 SOCA 생성

// File: epwm_adc_trigger.c
// Description: TMS320F28335 ePWM ADC 트리거(SOCA) 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335

#include "F28x_Project.h"

// GPIO 설정 함수
void ConfigureGPIO(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0을 ePWM1A로 설정
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
    GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
    EDIS; // 보호된 레지스터 접근 비허용
}

// ePWM1 설정 함수
void ConfigureEPWM1(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    CpuSysRegs.PCLKCR1.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
    EDIS; // 보호된 레지스터 접근 비허용

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 타임-베이스 카운터를 업 카운트 모드로 설정
    EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비 1/1 (SYSCLK = 150MHz)
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 2; // 고속 클럭 분주비 1/2 (TBCLK = 150MHz/2 = 75MHz)
    EPwm1Regs.TBPRD = 750; // 주기 레지스터 설정: 750 TBCLK = 10us (100kHz = 150MHz/2/750)
    EPwm1Regs.CMPA.bit.CMPA = 375; // 비교 레지스터 A 설정: 50% 듀티 사이클 (375/750)
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 PWM_A 출력을 High로 설정
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 PWM_A 출력을 Low로 설정

    EPwm1Regs.ETSEL.bit.SOCAEN = 1; // SOCA(Start of Conversion A) 트리거 활성화
    EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // TBCTR=0일 때 SOCA 트리거 발생
    EPwm1Regs.ETPS.bit.SOCAPRD = 1; // 첫 번째 이벤트에서 SOCA 트리거 발생

    EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드: 에뮬레이션 중에도 동작 계속
}

void main(void) {
    InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
    DINT; // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 컨트롤러 초기화
    IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
    IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
    InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화

    ConfigureGPIO(); // GPIO 설정 함수 호출
    ConfigureEPWM1(); // ePWM1 설정 함수 호출

    for(;;); // 무한 루프: PWM 신호 및 SOCA 트리거 지속 출력
}

설명:

  • 기능: ePWM1의 PWM_A 출력으로 100kHz, 50% 듀티 PWM 신호 생성 및 SOCA 트리거
  • 설정: Up 카운터, 주기 750(100kHz @ 75MHz), CMPA=375(50% 듀티), SOCA 활성화
  • GPIO: GPIO0(ePWM1A), GPIO34(LED)
  • 출력: GPIO0에 PWM 신호 출력, SOCA 트리거 발생, LED ON

5.4 예제 4: HRPWM (고해상도 PWM)

// File: epwm_hrpwm.c
// Description: TMS320F28335 ePWM HRPWM 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335

#include "F28x_Project.h"

// GPIO 설정 함수
void ConfigureGPIO(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0을 ePWM1A로 설정
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
    GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
    EDIS; // 보호된 레지스터 접근 비허용
}

// ePWM1 설정 함수
void ConfigureEPWM1(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    CpuSysRegs.PCLKCR1.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
    CpuSysRegs.PCLKCR0.bit.HRPWM = 1; // HRPWM 모듈 클럭 활성화
    EDIS; // 보호된 레지스터 접근 비허용

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 타임-베이스 카운터를 업 카운트 모드로 설정
    EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비 1/1 (SYSCLK = 150MHz)
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 2; // 고속 클럭 분주비 1/2 (TBCLK = 150MHz/2 = 75MHz)
    EPwm1Regs.TBPRD = 750; // 주기 레지스터 설정: 750 TBCLK = 10us (100kHz = 150MHz/2/750)
    EPwm1Regs.CMPA.bit.CMPA = 375; // 비교 레지스터 A 설정: 50% 듀티 사이클 (375/750)
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 PWM_A 출력을 High로 설정
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 PWM_A 출력을 Low로 설정

    EPwm1Regs.HRCNFG.bit.HRLOAD = 0; // CMPAHR 로드 타이밍: TBCTR=0에서 로드
    EPwm1Regs.HRCNFG.bit.CTLMODE = 0; // CMPAHR 제어 모드: 듀티 제어
    EPwm1Regs.HRCNFG.bit.EDGMODE = 2; // HRPWM 에지 모드: 상승/하강 에지 모두 조정
    EPwm1Regs.CMPA.bit.CMPAHR = 0x0100; // 고해상도 비교 레지스터: 약 1.5ns 추가 듀티 (150ps 단위)

    EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드: 에뮬레이션 중에도 동작 계속
}

void main(void) {
    InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
    DINT; // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 컨트롤러 초기화
    IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
    IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
    InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화

    ConfigureGPIO(); // GPIO 설정 함수 호출
    ConfigureEPWM1(); // ePWM1 설정 함수 호출

    for(;;); // 무한 루프: HRPWM 신호 지속 출력
}

설명:

  • 기능: ePWM1의 PWM_A 출력으로 100kHz, 50% 듀티 PWM 신호 생성, HRPWM으로 고해상도 조정
  • 설정: Up 카운터, 주기 750(100kHz @ 75MHz), CMPA=375(50% 듀티), CMPAHR=0x0100(1.5ns)
  • GPIO: GPIO0(ePWM1A), GPIO34(LED)
  • 출력: GPIO0에 고해상도 PWM 신호 출력, LED ON

5.5 예제 5: 트립 존(Trip Zone) 보호 기능

// File: epwm_trip_zone.c
// Description: TMS320F28335 ePWM 트립 존 보호 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335

#include "F28x_Project.h"

// GPIO 설정 함수
void ConfigureGPIO(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0을 ePWM1A로 설정
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
    GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0; // GPIO2를 일반 입력으로 설정 (Trip Zone 입력)
    GpioCtrlRegs.GPADIR.bit.GPIO2 = 0; // GPIO2를 입력 방향으로 설정
    EDIS; // 보호된 레지스터 접근 비허용
}

// ePWM1 설정 함수
void ConfigureEPWM1(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    CpuSysRegs.PCLKCR1.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
    EDIS; // 보호된 레지스터 접근 비허용

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 타임-베이스 카운터를 업 카운트 모드로 설정
    EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비 1/1 (SYSCLK = 150MHz)
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 2; // 고속 클럭 분주비 1/2 (TBCLK = 150MHz/2 = 75MHz)
    EPwm1Regs.TBPRD = 750; // 주기 레지스터 설정: 750 TBCLK = 10us (100kHz = 150MHz/2/750)
    EPwm1Regs.CMPA.bit.CMPA = 375; // 비교 레지스터 A 설정: 50% 듀티 사이클 (375/750)
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 PWM_A 출력을 High로 설정
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 PWM_A 출력을 Low로 설정

    EPwm1Regs.TZSEL.bit.CBC1 = 1; // TZ1 (GPIO2)에서 Cycle-by-Cycle 트립 이벤트 활성화
    EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // 트립 이벤트 발생 시 PWM_A를 Low로 강제 설정
    EPwm1Regs.TZEINT.bit.CBC = 1; // Cycle-by-Cycle 트립 인터럽트 활성화

    EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드: 에뮬레이션 중에도 동작 계속
}

void main(void) {
    InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
    DINT; // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 컨트롤러 초기화
    IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
    IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
    InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화

    ConfigureGPIO(); // GPIO 설정 함수 호출
    ConfigureEPWM1(); // ePWM1 설정 함수 호출

    for(;;); // 무한 루프: PWM 신호 및 트립 존 동작 지속
}

설명:

  • 기능: ePWM1의 PWM_A 출력으로 100kHz, 50% 듀티 PWM 신호 생성, GPIO2(TZ1)에서 트립 존 이벤트 발생 시 출력 차단
  • 설정: Up 카운터, 주기 750(100kHz @ 75MHz), CMPA=375(50% 듀티), TZ1 트립 활성화
  • GPIO: GPIO0(ePWM1A), GPIO2(TZ1), GPIO34(LED)
  • 출력: GPIO0에 PWM 신호 출력, 트립 이벤트 시 출력 Low, LED ON

5.6 예제 6: 다중 ePWM 동기화

// File: epwm_synchronization.c
// Description: TMS320F28335 ePWM 다중 모듈 동기화 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335

#include "F28x_Project.h"

// GPIO 설정 함수
void ConfigureGPIO(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0을 ePWM1A로 설정
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // GPIO2를 ePWM2A로 설정
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
    GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
    EDIS; // 보호된 레지스터 접근 비허용
}

// ePWM1 설정 함수 (Master)
void ConfigureEPWM1(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    CpuSysRegs.PCLKCR1.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
    EDIS; // 보호된 레지스터 접근 비허용

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 타임-베이스 카운터를 업 카운트 모드로 설정
    EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비 1/1 (SYSCLK = 150MHz)
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 2; // 고속 클럭 분주비 1/2 (TBCLK = 150MHz/2 = 75MHz)
    EPwm1Regs.TBPRD = 750; // 주기 레지스터 설정: 750 TBCLK = 10us (100kHz = 150MHz/2/750)
    EPwm1Regs.CMPA.bit.CMPA = 375; // 비교 레지스터 A 설정: 50% 듀티 사이클 (375/750)
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 PWM_A 출력을 High로 설정
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 PWM_A 출력을 Low로 설정
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_OUT; // 동기화 출력: EPWM1SYNC 신호 생성

    EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드: 에뮬레이션 중에도 동작 계속
}

// ePWM2 설정 함수 (Slave)
void ConfigureEPWM2(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    CpuSysRegs.PCLKCR1.bit.EPWM2 = 1; // ePWM2 모듈 클럭 활성화
    EDIS; // 보호된 레지스터 접근 비허용

    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 타임-베이스 카운터를 업 카운트 모드로 설정
    EPwm2Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비 1/1 (SYSCLK = 150MHz)
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 2; // 고속 클럭 분주비 1/2 (TBCLK = 150MHz/2 = 75MHz)
    EPwm2Regs.TBPRD = 750; // 주기 레지스터 설정: 750 TBCLK = 10us (100kHz)
    EPwm2Regs.CMPA.bit.CMPA = 375; // 비교 레지스터 A 설정: 50% 듀티 사이클 (375/750)
    EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 PWM_A 출력을 High로 설정
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 PWM_A 출력을 Low로 설정
    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // 위상 동기화 활성화: EPWM1SYNC 신호에 동기화
    EPwm2Regs.TBPHS.bit.TBPHS = 188; // 위상 지연 설정: 25% 주기 지연 (188/750 = 2.5us)

    EPwm2Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드: 에뮬레이션 중에도 동작 계속
}

void main(void) {
    InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
    DINT; // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 컨트롤러 초기화
    IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
    IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
    InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화

    ConfigureGPIO(); // GPIO 설정 함수 호출
    ConfigureEPWM1(); // ePWM1 설정 함수 호출 (Master)
    ConfigureEPWM2(); // ePWM2 설정 함수 호출 (Slave)

    for(;;); // 무한 루프: 동기화된 PWM 신호 지속 출력
}

설명:

  • 기능: ePWM1, ePWM2의 PWM_A 출력으로 100kHz, 50% 듀티 PWM 신호 생성, ePWM2는 ePWM1에 동기화 및 25% 위상 차이
  • 설정: Up 카운터, 주기 750(100kHz @ 75MHz), CMPA=375(50% 듀티), ePWM2 위상 지연 188
  • GPIO: GPIO0(ePWM1A), GPIO2(ePWM2A), GPIO34(LED)
  • 출력: GPIO0, GPIO2에 동기화된 PWM 신호 출력, LED ON

5.7 예제 7: PWM 인터럽트 기반 듀티 제어

// File: epwm_interrupt_duty.c
// Description: TMS320F28335 ePWM 인터럽트 기반 듀티 제어 예제
// Compiler: Code Composer Studio (TI C2000 Compiler)
// Target: TMS320F28335

#include "F28x_Project.h"

volatile Uint16 duty = 375; // 초기 듀티 50% (375/750 = 5us High 시간)

// 인터럽트 서비스 루틴: ePWM1 인터럽트 처리
__interrupt void epwm1_isr(void)
{
    duty = (duty == 375) ? 188 : 563; // 듀티 사이클을 25% (188/750) 또는 75% (563/750)로 전환
    EPwm1Regs.CMPA.bit.CMPA = duty; // 새로운 듀티 사이클 값을 CMPA 레지스터에 설정

    EPwm1Regs.ETCLR.bit.INT = 1; // ePWM1 인터럽트 플래그 클리어
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; // PIE 그룹 3 인터럽트 ACK (인터럽트 재발생 허용)
}

// GPIO 설정 함수
void ConfigureGPIO(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0을 ePWM1A로 설정
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO34를 출력으로 설정 (LED용)
    GpioDataRegs.GPBSET.bit.GPIO34 = 1; // GPIO34를 High로 설정하여 LED 켬
    EDIS; // 보호된 레지스터 접근 비허용
}

// ePWM1 설정 함수
void ConfigureEPWM1(void) {
    EALLOW; // 보호된 레지스터 접근 허용
    CpuSysRegs.PCLKCR1.bit.EPWM1 = 1; // ePWM1 모듈 클럭 활성화
    EDIS; // 보호된 레지스터 접근 비허용

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 타임-베이스 카운터를 업 카운트 모드로 설정
    EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주비 1/1 (SYSCLK = 150MHz)
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 2; // 고속 클럭 분주비 1/2 (TBCLK = 150MHz/2 = 75MHz)
    EPwm1Regs.TBPRD = 750; // 주기 레지스터 설정: 750 TBCLK = 10us (100kHz = 150MHz/2/750)
    EPwm1Regs.CMPA.bit.CMPA = duty; // 비교 레지스터 A 설정: 초기 50% 듀티 사이클
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // TBCTR=0일 때 PWM_A 출력을 High로 설정
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // TBCTR=CMPA일 때 PWM_A 출력을 Low로 설정

    EPwm1Regs.ETSEL.bit.INTEN = 1; // ePWM1 인터럽트 활성화
    EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // TBCTR=0일 때 인터럽트 발생
    EPwm1Regs.ETPS.bit.INTPRD = 1; // 첫 번째 이벤트에서 인터럽트 발생
    EPwm1Regs.ETCLR.bit.INT = 1; // 초기 인터럽트 플래그 클리어

    EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Free run 모드: 에뮬레이션 중에도 동작 계속
}

void main(void) {
    InitSysCtrl(); // 시스템 클럭(150MHz)과 PLL 초기화
    DINT; // 모든 인터럽트 비활성화
    InitPieCtrl(); // PIE 컨트롤러 초기화
    IER = 0x0000; // CPU 인터럽트 레지스터 비활성화
    IFR = 0x0000; // 인터럽트 플래그 레지스터 클리어
    InitPieVectTable(); // PIE 인터럽트 벡터 테이블 초기화

    EALLOW; // 보호된 레지스터 접근 허용
    PieVectTable.EPWM1_INT = &epwm1_isr; // ePWM1 인터럽트 벡터를 ISR 함수에 연결
    EDIS; // 보호된 레지스터 접근 비허용

    ConfigureGPIO(); // GPIO 설정 함수 호출
    ConfigureEPWM1(); // ePWM1 설정 함수 호출

    PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // PIE 그룹 3에서 ePWM1 인터럽트 활성화
    IER |= M_INT3; // CPU 인터럽트 그룹 3 활성화

    EINT; // 글로벌 인터럽트 활성화
    ERTM; // 실시간 모드 활성화: 디버깅 시 인터럽트 실시간 처리

    for(;;); // 무한 루프: PWM 신호 및 인터럽트 동작 지속
}

설명:

  • 기능: ePWM1의 PWM_A 출력으로 100kHz PWM 신호 생성, 인터럽트를 통해 듀티 사이클 25%와 75% 간 전환
  • 설정: Up 카운터, 주기 750(100kHz @ 75MHz), CMPA=188/563(25%/75% 듀티), 인터럽트 활성화
  • GPIO: GPIO0(ePWM1A), GPIO34(LED)
  • 출력: GPIO0에 PWM 신호 출력, 듀티 동적 변경, LED ON

6. 사용 방법

6.1 환경 설정

  • C2000Ware 설치: C:\ti\c2000\C2000Ware_x_xx_xx_xx
  • CCS 프로젝트: TMS320F28335 타겟으로 프로젝트 생성, F28x_Project.h 포함
  • 링커 파일: device_support\f2833x 폴더에서 링커 파일 추가

6.2 코드 실행

  • 각 예제를 별도의 .c 파일로 저장하거나, main.c에 복사
  • 다른 예제 코드 주석 처리

6.3 하드웨어 준비

  • PWM 출력: ePWM1A, ePWM1B 핀에 오실로스코프 또는 부하 연결
  • 데드밴드: H-브리지 회로 사용 시 데드타임 확인
  • HRPWM: 고정밀 오실로스코프 사용
  • LED: GPIO34에 LED 연결
  • 트립 존: GPIO2에 트립 신호 입력 연결

6.4 디버깅

  • CCS Expressions 창에서 EPwm1Regs.TBCTR, EPwm1Regs.CMPA 확인
  • EPwm1Regs.ETFLG로 이벤트 트리거 상태 점검
  • EPwm1Regs.TZFLG로 트립 존 동작 확인

7. 추가 팁

  • 캘리브레이션: HRPWM 사용 시 Device_cal() 호출
  • 노이즈 감소: PWM 출력에 저역통과 필터 사용
  • C2000Ware 참고: C:\ti\c2000\C2000Ware_x_xx_xx_xx\device_support\f2833x\examples\cpu1\epwm
  • 문제 해결:
    • PWM 출력 없음: TBCTL.bit.CTRMODE, AQCTLA 설정 확인
    • ADC 트리거 실패: ETSEL.bit.SOCAEN, ETPS.bit.SOCAPRD 확인
    • 트립 존 실패: TZSEL, TZCTL 설정 확인
  • TI 리소스: TI E2E 포럼, C2000Ware 예제

8. 결론

이 문서는 TMS320F28335 ePWM 모듈의 설정 방법과 Bitfield 구조를 활용한 예제 코드를 제공하여 다양한 애플리케이션에 적용 가능하도록 구성했습니다. 

키워드: TMS320F28335, ePWM, C2000, PWM, 마이크로컨트롤러, Code Composer Studio, ADC 트리거, 데드밴드, 상보 PWM, HRPWM, 트립 존, 동기화, 페이즈 시프트, Up-Down 카운터

반응형