본문 바로가기
MCU/C2000

[TMS320F28335] GPIO 사용법: Bitfield 구조 활용

by linuxgo 2025. 8. 7.
반응형

1. TMS320F28335 GPIO 개요

TMS320F28335는 Texas Instruments의 C2000 시리즈 디지털 신호 컨트롤러(DSC)로, 실시간 제어 애플리케이션(예: 모터 제어, 전력 변환)에 최적화된 마이크로컨트롤러입니다. 이 장치의 GPIO(General Purpose Input/Output)는 최대 88개의 핀을 제공하며, 외부 장치와의 디지털 인터페이스 및 신호 제어에 사용됩니다. GPIO 핀은 GPA(GPIO0~31), GPB(GPIO32~63), GPC(GPIO64~87)로 나뉘며, 각 핀은 다중화(multiplexed)되어 GPIO 외에 ePWM, SCI, SPI, CAN 등의 기능을 지원합니다.

1.1 주요 특징

  • 포트 구성: GPA(32비트), GPB(32비트), GPC(24비트).
  • 다중화: 각 핀은 최대 4개 기능으로 설정 가능 (예: GPIO0은 ePWM1A, XCLKIN 등).
  • 입출력 방향: 입력(0), 출력(1), 또는 고임피던스 상태.
  • 내부 풀업 저항: GPxPUD로 활성화(0) 또는 비활성화(1).
  • 입력 동기화: SYSCLKOUT 동기화(최대 150MHz) 또는 비동기 입력 지원.
  • 최대 토글 속도: 25MHz (SYSCLKOUT=150MHz 기준).
  • 전압 레벨: 3.3V (5V 내성 없음, 외부 레벨 시프터 필요).
  • 인터럽트: 선택된 핀에서 상승/하강 에지 인터럽트 지원.

1.2 GPIO 애플리케이션

TMS320F28335의 GPIO는 다양한 애플리케이션에서 활용됩니다: - LED 제어: 상태 표시. - 스위치 입력: 사용자 입력 처리. - 센서 인터페이스: 디지털 센서 신호 읽기. - 통신 제어: SPI, I2C, UART의 제어 신호. - 인터럽트 트리거: 외부 이벤트 감지.

2. GPIO 제어 레지스터 상세

GPIO 설정은 여러 레지스터를 통해 이루어지며, 각 레지스터는 특정 역할을 수행합니다. 아래 표는 주요 레지스터와 기능을 정리한 것입니다. 상세한 내용은 TMS320F28335 TRM를 참조하기 바랍니다.

레지스터 기능 설정 값
     
GPxMUX1/2 핀의 기능 선택 (GPIO 또는 주변 장치) 0: GPIO, 1~3: 다른 기능 (예: ePWM, SCI)
GPxDIR 입출력 방향 설정 0: 입력, 1: 출력
GPxPUD 내부 풀업 저항 설정 0: 활성화, 1: 비활성화
GPxDAT 데이터 읽기/쓰기 입력: 현재 상태 읽기, 출력: High(1)/Low(0) 설정
GPxSET/CLEAR/TOGGLE 출력 핀 상태 제어 SET: High, CLEAR: Low, TOGGLE: 반전
GPxQSEL1/2 입력 동기화/샘플링 설정 0: SYSCLKOUT, 1: 3샘플링, 2: 6샘플링, 3: 비동기
GPxINT 인터럽트 설정 (선택 핀) 상승/하강 에지 트리거

레지스터는 EALLOW로 보호 해제 후 접근하고, 설정 완료 후 EDIS로 보호 복원해야 합니다.

3. GPIO 설정 절차

TMS320F28335에서 GPIO를 설정하려면 다음 단계를 체계적으로 수행해야 합니다:

  1. 시스템 초기화: InitSysCtrl()로 PLL, 클럭(SYSCLKOUT=150MHz), 주변 장치 설정.
  2. 인터럽트 초기화: InitPieCtrl(), InitPieVectTable()로 인터럽트 벡터 초기화.
  3. 핀 기능 선택: GPxMUX1/2로 GPIO 기능 활성화 (0 설정).
  4. 입출력 방향: GPxDIR로 입력(0) 또는 출력(1) 설정.
  5. 풀업 저항: GPxPUD로 활성화(0, 입력용) 또는 비활성화(1, 출력용).
  6. 입력 동기화: GPxQSEL1/2로 동기화 모드 설정 (노이즈 필터링).
  7. 데이터 처리: GPxDAT, GPxSET, GPxCLEAR, GPxTOGGLE로 입출력 제어.
  8. 인터럽트 설정 (옵션): GPxINT로 인터럽트 활성화 (선택 핀).

4. 예제 코드: LED 토글 및 스위치 입력

아래는 GPIO32를 LED 출력으로, GPIO21을 스위치 입력으로 설정하여 스위치 상태에 따라 LED를 제어하는 C 코드입니다. 이 코드는 Code Composer Studio(CCS)에서 동작하며, TMDSDOCK28335 보드에서 테스트 가능합니다.

4.1 코드 설명

  • 목적: 스위치(GPIO21) 입력에 따라 LED(GPIO32)를 켜고 끔.
  • 동작: 스위치 눌림(Low) → LED 켜짐(High), 스위치 안 눌림(High) → LED 꺼짐(Low).
  • 하드웨어: GPIO32에 LED(330Ω 저항 포함), GPIO21에 스위치(그라운드 연결).
  • 디바운싱: 100ms 딜레이로 스위치 노이즈 방지.
  • 의존성: DSP28x_Project.h (C2000Ware 제공).

4.2 예제 코드

#include "DSP28x_Project.h" // TMS320F28335 헤더 파일: 레지스터 정의, 초기화 함수 포함

// 함수 프로토타입 선언
void InitGpioExample(void); // GPIO 초기화 함수

void main(void)
{
    // 시스템 제어 초기화
    // PLL, 클럭(SYSCLKOUT=150MHz), 주변 장치 활성화
    // C2000Ware의 기본 함수로 마이크로컨트롤러 동작 환경 설정
    InitSysCtrl();

    // 글로벌 인터럽트 비활성화
    // 초기화 중 예기치 않은 인터럽트 방지를 위해 DINT 사용
    DINT;

    // PIE(Peripheral Interrupt Expansion) 초기화
    // 인터럽트 벡터 테이블을 기본값으로 리셋
    InitPieCtrl();

    // 인터럽트 인에이블 레지스터(IER)와 플래그 레지스터(IFR) 초기화
    // IER=0x0000: 모든 인터럽트 비활성화
    // IFR=0x0000: 모든 인터럽트 플래그 클리어
    IER = 0x0000;
    IFR = 0x0000;

    // PIE 벡터 테이블 초기화
    // 예기치 않은 인터럽트 처리 방지
    InitPieVectTable();

    // GPIO 초기화 함수 호출
    // GPIO32(LED 출력)와 GPIO21(스위치 입력) 설정
    InitGpioExample();

    // 메인 루프: 스위치 상태에 따라 LED 제어
    while(1)
    {
        // GPIO21(스위치) 입력 상태 확인
        // 내부 풀업 저항으로 스위치 안 눌림=High(1), 눌림=Low(0)
        if(GpioDataRegs.GPADAT.bit.GPIO21 == 0)
        {
            // 스위치 눌림: GPIO32(LED)를 High로 설정 (LED 켜짐)
            // GPBSET은 다른 비트에 영향 없이 지정 비트만 1로 설정
            GpioDataRegs.GPBSET.bit.GPIO32 = 1;
        }
        else
        {
            // 스위치 안 눌림: GPIO32(LED)를 Low로 설정 (LED 꺼짐)
            // GPBCLEAR은 다른 비트에 영향 없이 지정 비트만 0으로 설정
            GpioDataRegs.GPBCLEAR.bit.GPIO32 = 1;
        }

        // 100ms 딜레이
        // 스위치 디바운싱을 위해 마이크로초 단위 지연 생성
        DELAY_US(100000);
    }
}

// GPIO 초기화 함수
void InitGpioExample(void)
{
    // EALLOW: 보호된 레지스터 접근 허용
    // GPIO 제어 레지스터는 보호되어 있으므로 쓰기 전 EALLOW 필수
    EALLOW;

    // GPIO32 설정 (LED, 출력)
    // GPBMUX1.bit.GPIO32 = 0: GPIO 기능 활성화 (다른 기능 비활성화)
    GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0;
    // GPBDIR.bit.GPIO32 = 1: 출력 설정 (0=입력, 1=출력)
    GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1;
    // GPBPUD.bit.GPIO32 = 1: 내부 풀업 저항 비활성화 (출력 핀은 불필요)
    GpioCtrlRegs.GPBPUD.bit.GPIO32 = 1;

    // GPIO21 설정 (스위치, 입력)
    // GPAMUX2.bit.GPIO21 = 0: GPIO 기능 활성화
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0;
    // GPADIR.bit.GPIO21 = 0: 입력 설정
    GpioCtrlRegs.GPADIR.bit.GPIO21 = 0;
    // GPAPUD.bit.GPIO21 = 0: 내부 풀업 저항 활성화
    // 스위치가 그라운드 연결 시 안정적 High/Low 유지
    GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0;
    // GPAQSEL2.bit.GPIO21 = 2: 6샘플링 동기화
    // SYSCLKOUT에 동기화된 입력을 6번 샘플링하여 노이즈 필터링
    GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 2;

    // EDIS: 보호된 레지스터 접근 비활성화
    EDIS;
}

5. GPIO 인터럽트 설정

GPIO 인터럽트를 사용하면 외부 이벤트(예: 스위치 눌림)를 즉시 감지할 수 있습니다. TMS320F28335는 특정 핀(GPIO0~7, GPIO16~23 등)에서 인터럽트를 지원하며, GPxINT 레지스터로 설정합니다.

5.1 인터럽트 설정 절차

  1. 인터럽트 핀 선택: 인터럽트를 지원하는 핀 확인 (데이터시트 참조).
  2. 인터럽트 활성화: GpioIntRegs.GPIOXINTnSEL로 핀 선택.
  3. 트리거 설정: GpioIntRegs.GPIOXnCFG로 상승/하강 에지 설정.
  4. PIE 설정: PieCtrlRegsPieVectTable로 인터럽트 벡터 매핑.
  5. 인터럽트 핸들러: ISR(Interrupt Service Routine) 정의.

5.2 인터럽트 예제 코드

아래는 GPIO21의 하강 에지(스위치 눌림)에서 인터럽트를 발생시켜 LED(GPIO32)를 토글하는 코드입니다.

#include "DSP28x_Project.h"

// 함수 프로토타입
void InitGpioExample(void);
interrupt void gpio_isr(void); // 인터럽트 서비스 루틴

void main(void)
{
    InitSysCtrl(); // 시스템 초기화
    DINT; // 인터럽트 비활성화

    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();

    // 인터럽트 벡터 테이블에 ISR 연결
    EALLOW;
    PieVectTable.XINT1 = &gpio_isr;
    EDIS;

    InitGpioExample(); // GPIO 초기화

    // 인터럽트 활성화
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // PIE 활성화
    IER |= M_INT1; // XINT1 인터럽트 활성화
    EINT; // 글로벌 인터럽트 활성화

    while(1); // 무한 루프
}

void InitGpioExample(void)
{
    EALLOW;

    // GPIO32 (LED, 출력)
    GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0; // GPIO 기능
    GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1; // 출력
    GpioCtrlRegs.GPBPUD.bit.GPIO32 = 1; // 풀업 비활성화

    // GPIO21 (스위치, 입력, 인터럽트)
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0; // GPIO 기능
    GpioCtrlRegs.GPADIR.bit.GPIO21 = 0; // 입력
    GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0; // 풀업 활성화
    GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 2; // 6샘플링 동기화

    // 인터럽트 설정 (XINT1에 GPIO21 매핑)
    GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 21; // GPIO21 선택
    GpioIntRegs.GPIOXnCFG.bit.XINT1POL = 0; // 하강 에지 트리거

    EDIS;
}

interrupt void gpio_isr(void)
{
    // GPIO32 토글
    GpioDataRegs.GPBTOGGLE.bit.GPIO32 = 1;
    // 인터럽트 플래그 클리어
    GpioIntRegs.GPIOXINT1CLR.bit.XINT1 = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // PIE ACK 클리어
}

6. 다중 GPIO 제어

여러 GPIO 핀을 동시에 제어하려면 비트 필드 레지스터를 활용합니다. 예를 들어, GPIO32~35를 LED 출력으로 설정하고, GPIO20~23을 스위치 입력으로 설정할 수 있습니다.

6.1 다중 GPIO 예제 코드

#include "DSP28x_Project.h"

void InitMultiGpio(void);

void main(void)
{
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();

    InitMultiGpio();

    while(1)
    {
        // GPIO20~23 입력 읽기
        Uint32 inputs = GpioDataRegs.GPADAT.all & 0x00F00000; // GPIO20~23 비트 마스크
        // GPIO32~35 출력 (입력에 따라 반전)
        GpioDataRegs.GPBDAT.all = (inputs >> 20); // 비트 시프트 후 출력
        DELAY_US(100000);
    }
}

void InitMultiGpio(void)
{
    EALLOW;

    // GPIO32~35 (LED, 출력)
    GpioCtrlRegs.GPBMUX1.all &= ~0x000000FF; // GPIO 기능 (GPIO32~35)
    GpioCtrlRegs.GPBDIR.all |= 0x0000000F; // 출력 설정
    GpioCtrlRegs.GPBPUD.all |= 0x0000000F; // 풀업 비활성화

    // GPIO20~23 (스위치, 입력)
    GpioCtrlRegs.GPAMUX2.all &= ~0x0000FF00; // GPIO 기능
    GpioCtrlRegs.GPADIR.all &= ~0x00F00000; // 입력 설정
    GpioCtrlRegs.GPAPUD.all &= ~0x00F00000; // 풀업 활성화
    GpioCtrlRegs.GPAQSEL2.all |= 0x00AA0000; // 6샘플링 동기화

    EDIS;
}

7. 성능 최적화 및 디버깅

7.1 성능 최적화

  • RAM 실행: 플래시 메모리에서 실행 시 지연(50~150ns) 발생 가능. 고속 토글 시 코드와 데이터를 RAM으로 이동 (C2000Ware의 F28335.cmd 링커 파일 수정).
  • 레지스터 직접 접근: GPxSET, GPxCLEAR 사용으로 효율적 출력 제어.
  • 클럭 최적화: SYSCLKOUT(150MHz) 활용으로 최대 25MHz 토글 가능.

7.2 디버깅 팁

  • 레지스터 확인: CCS의 레지스터 뷰로 GPxMUX, GPxDAT 값 확인.
  • 오실로스코프: GPIO 출력 신호의 타이밍 및 노이즈 점검.
  • 노이즈 필터링: GPxQSEL로 6샘플링 설정 또는 외부 RC 필터 추가.

8. 실제 애플리케이션 예시

  • 모터 제어: GPIO로 엔코더 신호 읽기, 제어 신호 출력.
  • 통신 인터페이스: SPI/I2C의 칩 선택(CS) 핀 제어.
  • 상태 모니터링: 다중 센서 입력 처리.

9. 참고 자료

  • TMS320F28335 데이터시트
  • SPRU812: GPIO 기술 참조 매뉴얼
  • C2000Ware: 예제 코드 및 라이브러리
  • TI E2E 포럼

이 문서는 TMS320F28335 GPIO의 설정, 예제 코드, 인터럽트, 최적화를 포괄적으로 다루어 보았습니다.

반응형