본문 바로가기
MCU/C2000

[TMS320F28388D] SCI 사용법: Driverlib API로 UART 설정 및 예제

by linuxgo 2025. 8. 8.
반응형

이 문서는 Texas Instruments의 TMS320F28388D 마이크로컨트롤러에서 SCI (Serial Communication Interface) 모듈을 Driverlib API를 사용하여 설정하고 사용하는 방법을 상세히 설명합니다. UART 기반 직렬 통신을 구현하는 데 필요한 모든 Driverlib SCI 함수를 다루며, FIFO, 인터럽트, 루프백 모드, 오토보드 록 등을 포함한 실습 가능한 예제 코드를 제공합니다. 각 코드에는 주석을 추가하여 초보자부터 숙련자까지 쉽게 이해할 수 있도록 했습니다. 이 문서는 C2000WareCode Composer Studio (CCS) 환경을 기준으로 작성되었습니다.


1. SCI 모듈 개요

TMS320F28388D의 SCI 모듈은 UART (Universal Asynchronous Receiver/Transmitter) 프로토콜을 기반으로 비동기 직렬 통신을 제공합니다. 이 모듈은 다음과 같은 기능을 지원합니다:

  • 데이터 워드 길이: 1~8비트
  • 보드레이트: 최대 115200bps 이상 (시스템 클럭에 따라 다름)
  • 패리티: None, Even, Odd
  • 스톱 비트: 1 또는 2 스톱 비트
  • FIFO: 송신/수신 FIFO로 데이터 처리 효율성 향상
  • 인터럽트: 송신, 수신, 에러 인터럽트
  • 루프백 모드: 테스트용 내부 루프백
  • 오토보드 록: 자동 보드레이트 동기화

Driverlib API는 하드웨어 레지스터를 직접 조작하지 않고, 추상화된 함수를 통해 SCI 모듈을 쉽게 설정하고 제어할 수 있도록 설계되었습니다. 


2. 사전 준비

SCI 모듈을 사용하기 위해 다음 사항을 준비하세요:

  • C2000Ware 설치: 최신 C2000Ware 패키지의 driverlib 폴더를 프로젝트에 포함.
  • 필요한 헤더 파일:
    #include "driverlib.h" // SCI 및 기타 주변 장치 API 포함
    #include "device.h"    // 디바이스별 설정 (예: DEVICE_LSPCLK_FREQ)
    
  • 개발 환경: Code Composer Studio (CCS) 권장.
  • GPIO 설정: SCI 모듈의 TX/RX 핀을 올바르게 설정 (예: SCIA는 GPIO28/TX, GPIO29/RX).
  • 시스템 클럭: SCI 보드레이트 계산에 필요한 저속 주변 장치 클럭(LSPCLK) 주파수 확인 (기본값: 50MHz).
  • 데이터시트: TMS320F28388D 데이터시트를 참조하여 핀맵 및 SCI 모듈 사양 확인.

3. Driverlib SCI 함수 목록 및 설명

아래는 driverlib/sci.h에 정의된 모든 SCI 관련 함수와 그 사용법입니다. 각 함수는 기능, 매개변수, 사용 사례를 포함하며, 예제 코드에서 활용됩니다.

3.1 SCI 모듈 제어 함수

  • SCI_enableModule(uint32_t base): SCI 모듈을 활성화하여 통신을 시작합니다.
    • 매개변수: base (SCI 모듈 주소, 예: SCIA_BASE)
    • 사용 사례: 설정 완료 후 통신 시작.
  • SCI_disableModule(uint32_t base): SCI 모듈을 비활성화하여 설정 변경을 안전하게 수행합니다.
    • 매개변수: base
    • 사용 사례: 설정 변경 전 모듈 비활성화.
  • SCI_resetChannels(uint32_t base): 송수신 채널을 리셋하여 초기 상태로 복구합니다.
    • 매개변수: base
    • 사용 사례: 오류 발생 후 채널 초기화.
  • SCI_resetReceiver(uint32_t base): 수신 채널만 리셋합니다.
    • 매개변수: base
    • 사용 사례: 수신 오류 복구.
  • SCI_resetTransmitter(uint32_t base): 송신 채널만 리셋합니다.
    • 매개변수: base
    • 사용 사례: 송신 오류 복구.

3.2 SCI 설정 함수

  • SCI_setConfig(uint32_t base, uint32_t lspclkHz, uint32_t baud, uint32_t config): 보드레이트, 데이터 워드 길이, 스톱 비트, 패리티를 설정합니다.
    • 매개변수:
      • base: SCI 모듈 주소
      • lspclkHz: 저속 주변 장치 클럭 주파수
      • baud: 보드레이트 (예: 9600)
      • config: SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE 등
    • 사용 사례: 기본 통신 설정.
  • SCI_setBaudRate(uint32_t base, uint32_t lspclkHz, uint32_t baud): 보드레이트를 설정합니다.
    • 매개변수: base, lspclkHz, baud
    • 사용 사례: 동적 보드레이트 변경.
  • SCI_enableParity(uint32_t base): 패리티 검사를 활성화합니다.
    • 매개변수: base
    • 사용 사례: 데이터 무결성 보장.
  • SCI_disableParity(uint32_t base): 패리티 검사를 비활성화합니다.
    • 매개변수: base
    • 사용 사례: 패리티 비활성화.
  • SCI_setParityMode(uint32_t base, SCI_ParityMode parity): Even 또는 Odd 패리티를 설정합니다.
    • 매개변수: base, parity (SCI_PAR_EVEN 또는 SCI_PAR_ODD)
    • 사용 사례: 패리티 모드 변경.
  • SCI_setDataLength(uint32_t base, SCI_DataLength length): 데이터 워드 길이를 설정합니다.
    • 매개변수: base, length (예: SCI_DATALENGTH_8BIT)
    • 사용 사례: 데이터 길이 변경.
  • SCI_setStopBits(uint32_t base, SCI_StopBits stopBits): 스톱 비트 수를 설정합니다.
    • 매개변수: base, stopBits (SCI_STOP_ONE 또는 SCI_STOP_TWO)
    • 사용 사례: 스톱 비트 변경.

3.3 FIFO 관련 함수

  • SCI_enableFIFO(uint32_t base): FIFO를 활성화하여 다중 데이터 처리 효율성을 높입니다.
    • 매개변수: base
    • 사용 사례: 대량 데이터 송수신.
  • SCI_disableFIFO(uint32_t base): FIFO를 비활성화합니다.
    • 매개변수: base
    • 사용 사례: FIFO 사용 중지.
  • SCI_resetTxFIFO(uint32_t base): 송신 FIFO를 리셋합니다.
    • 매개변수: base
    • 사용 사례: 송신 FIFO 초기화.
  • SCI_resetRxFIFO(uint32_t base): 수신 FIFO를 리셋합니다.
    • 매개변수: base
    • 사용 사례: 수신 FIFO 초기화.
  • SCI_setFIFOInterruptLevel(uint32_t base, SCI_TxFIFOLevel txLevel, SCI_RxFIFOLevel rxLevel): FIFO 인터럽트 레벨을 설정합니다.
    • 매개변수: base, txLevel (예: SCI_FIFO_TX4), rxLevel (예: SCI_FIFO_RX4)
    • 사용 사례: FIFO 인터럽트 트리거 설정.
  • SCI_getTxFIFOStatus(uint32_t base): 송신 FIFO 상태를 반환합니다.
    • 매개변수: base
    • 반환값: 송신 FIFO 데이터 수
    • 사용 사례: 송신 FIFO 상태 확인.
  • SCI_getRxFIFOStatus(uint32_t base): 수신 FIFO 상태를 반환합니다.
    • 매개변수: base
    • 반환값: 수신 FIFO 데이터 수
    • 사용 사례: 수신 FIFO 상태 확인.

3.4 데이터 송수신 함수

  • SCI_writeCharBlocking(uint32_t base, uint16_t data): 차단 모드로 단일 문자를 송신합니다.
    • 매개변수: base, data
    • 사용 사례: 안정적인 단일 문자 송신.
  • SCI_writeCharNonBlocking(uint32_t base, uint16_t data): 비차단 모드로 단일 문자를 송신합니다.
    • 매개변수: base, data
    • 반환값: 성공 시 true, 실패 시 false
    • 사용 사례: 빠른 송신 처리.
  • SCI_writeCharArray(uint32_t base, const uint16_t *array, uint16_t length): 문자 배열을 송신합니다.
    • 매개변수: base, array, length
    • 사용 사례: 문자열 송신.
  • SCI_readCharBlocking(uint32_t base): 차단 모드로 단일 문자를 수신합니다.
    • 매개변수: base
    • 반환값: 수신된 문자
    • 사용 사례: 데이터 수신 대기.
  • SCI_readCharNonBlocking(uint32_t base): 비차단 모드로 단일 문자를 수신합니다.
    • 매개변수: base
    • 반환값: 수신된 문자 또는 SCI_INVALID_DATA
    • 사용 사례: 빠른 수신 확인.
  • SCI_readCharArray(uint32_t base, uint16_t *array, uint16_t length): 문자 배열을 수신합니다.
    • 매개변수: base, array, length
    • 사용 사례: 다중 데이터 수신.

3.5 인터럽트 관련 함수

  • SCI_enableInterrupt(uint32_t base, uint32_t intFlags): 지정된 인터럽트를 활성화합니다.
    • 매개변수: base, intFlags (예: SCI_INT_RXFF | SCI_INT_TXFF)
    • 사용 사례: 송수신 인터럽트 처리.
  • SCI_disableInterrupt(uint32_t base, uint32_t intFlags): 지정된 인터럽트를 비활성화합니다.
    • 매개변수: base, intFlags
    • 사용 사례: 인터럽트 중지.
  • SCI_clearInterruptStatus(uint32_t base, uint32_t intFlags): 인터럽트 플래그를 지웁니다.
    • 매개변수: base, intFlags
    • 사용 사례: 인터럽트 처리 후 초기화.
  • SCI_getInterruptStatus(uint32_t base): 인터럽트 상태를 반환합니다.
    • 매개변수: base
    • 반환값: 활성화된 인터럽트 플래그
    • 사용 사례: 인터럽트 원인 확인.

3.6 상태 확인 함수

  • SCI_getRxStatus(uint32_t base): 수신 상태를 반환합니다.
    • 매개변수: base
    • 반환값: SCI_RXSTATUS_READY 등
    • 사용 사례: 수신 데이터 준비 확인.
  • SCI_isTransmitterBusy(uint32_t base): 송신기 상태를 확인합니다.
    • 매개변수: base
    • 반환값: 송신 중이면 true
    • 사용 사례: 송신기 사용 여부 확인.
  • SCI_isSpaceAvailable(uint32_t base): 송신 버퍼 공간을 확인합니다.
    • 매개변수: base
    • 반환값: 공간 있으면 true
    • 사용 사례: 비차단 송신 전 확인.

3.7 루프백 및 오토보드 록 함수

  • SCI_enableLoopback(uint32_t base): 루프백 모드를 활성화합니다.
    • 매개변수: base
    • 사용 사례: 테스트용 내부 송수신.
  • SCI_disableLoopback(uint32_t base): 루프백 모드를 비활성화합니다.
    • 매개변수: base
    • 사용 사례: 정상 통신 복귀.
  • SCI_enableAutoBaud(uint32_t base): 오토보드 록을 활성화합니다.
    • 매개변수: base
    • 사용 사례: 자동 보드레이트 동기화.
  • SCI_disableAutoBaud(uint32_t base): 오토보드 록을 비활성화합니다.
    • 매개변수: base
    • 사용 사례: 수동 보드레이트 설정.

4. 예제 코드

아래는 모든 SCI 함수를 활용하는 독립적인 예제 코드들입니다. 각 예제는 특정 기능에 초점을 맞추며, 상세한 주석을 포함하여 코드의 모든 줄을 명확히 설명합니다. 

예제 1: 기본 SCI 설정 및 단일 문자 송수신

TMS320F28388D에서 기본 SCI 설정으로 단일 문자를 송수신합니다.

// 예제 1: 기본 SCI 설정 및 단일 문자 송수신 (TMS320F28388D, Driverlib API)
#include "driverlib.h" // Texas Instruments Driverlib 헤더: SCI 및 주변 장치 API
#include "device.h"    // 디바이스별 설정 (예: DEVICE_LSPCLK_FREQ)

// 함수 선언: GPIO 및 SCI 초기화
void initGPIO(void); // SCI 송수신 핀 설정
void initSCI(void);  // SCI 모듈 설정 (보드레이트, 데이터 형식)

void main(void) {
    // 시스템 초기화: 클럭, PLL, 주변 장치 설정 (TMS320F28388D 필수)
    Device_init();
    
    // 인터럽트 컨트롤러 초기화: 인터럽트 처리 준비
    Interrupt_initModule();
    
    // 인터럽트 벡터 테이블 초기화: 인터럽트 핸들러 매핑
    Interrupt_initVectorTable();
    
    // GPIO 초기화: SCI TX/RX 핀 설정 (GPIO28/TX, GPIO29/RX)
    initGPIO();
    
    // SCI 초기화: 9600bps, 8비트 데이터, 1 스톱 비트, 패리티 없음
    initSCI();
    
    // 글로벌 인터럽트 활성화: CPU 인터럽트 처리 가능
    EINT;
    
    // 실시간 인터럽트 활성화: 실시간 모드 지원
    ERTM;
    
    // 송신할 단일 문자 정의: 'A' 문자
    char sendChar = 'A';
    
    // 송신 버퍼 공간 확인: 비차단 송신 전 필수
    if (SCI_isSpaceAvailable(SCIA_BASE)) {
        // 단일 문자 송신 (차단 모드): 송신 버퍼가 비어질 때까지 대기
        SCI_writeCharBlocking(SCIA_BASE, (uint16_t)sendChar);
    }
    
    // 송신기 상태 확인: 송신 완료 대기
    while (SCI_isTransmitterBusy(SCIA_BASE)) {
        // 송신 중이면 루프에서 대기
    }
    
    // 수신 데이터 저장 변수
    uint16_t receivedChar;
    
    // 무한 루프: 수신 데이터 처리
    while(1) {
        // 수신 상태 확인: 데이터 준비 여부 확인
        if (SCI_getRxStatus(SCIA_BASE) & SCI_RXSTATUS_READY) {
            // 단일 문자 수신 (차단 모드): 데이터 수신까지 대기
            receivedChar = SCI_readCharBlocking(SCIA_BASE);
            
            // 수신된 문자 에코백: 수신 데이터를 다시 송신
            SCI_writeCharBlocking(SCIA_BASE, receivedChar);
        }
    }
}

// GPIO 초기화 함수: SCI 송수신 핀 설정
void initGPIO(void) {
    // SCIA TX 핀 설정: GPIO28을 SCIA 송신 핀으로 구성
    GPIO_setPinConfig(GPIO_28_SCIA_TX);
    
    // SCIA RX 핀 설정: GPIO29를 SCIA 수신 핀으로 구성
    GPIO_setPinConfig(GPIO_29_SCIA_RX);
    
    // TX 핀 방향 설정: GPIO28을 출력 모드로 설정
    GPIO_setDirectionMode(28, GPIO_DIR_MODE_OUT);
    
    // RX 핀 방향 설정: GPIO29를 입력 모드로 설정
    GPIO_setDirectionMode(29, GPIO_DIR_MODE_IN);
    
    // TX 핀 패드 설정: 표준 출력 모드 (풀업/풀다운 없음)
    GPIO_setPadConfig(28, GPIO_PIN_TYPE_STD);
    
    // RX 핀 패드 설정: 풀업 저항 활성화로 노이즈 방지
    GPIO_setPadConfig(29, GPIO_PIN_TYPE_PULLUP);
    
    // RX 핀 입력 자격: 비동기 입력으로 샘플링 지연 제거
    GPIO_setQualificationMode(29, GPIO_QUAL_ASYNC);
}

// SCI 초기화 함수: 기본 SCI 설정
void initSCI(void) {
    // SCI 모듈 비활성화: 설정 변경 전 안전하게 비활성화
    SCI_disableModule(SCIA_BASE);
    
    // 송수신 채널 리셋: SCI 모듈의 송수신 상태 초기화
    SCI_resetChannels(SCIA_BASE);
    
    // SCI 설정: 9600bps, 8비트 데이터, 1 스톱 비트, 패리티 없음
    SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 9600, 
                  (SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE));
    
    // SCI 모듈 활성화: 설정 완료 후 통신 시작
    SCI_enableModule(SCIA_BASE);
}

예제 2: FIFO 및 문자열 송수신

FIFO를 활성화하여 문자열을 송수신하는 방법을 보여줍니다.

// 예제 2: FIFO 및 문자열 송수신 (TMS320F28388D, Driverlib API)
#include "driverlib.h" // Driverlib 헤더: SCI 및 주변 장치 API
#include "device.h"    // 디바이스별 설정

// 함수 선언
void initGPIO(void); // SCI 송수신 핀 설정
void initSCI(void);  // SCI 및 FIFO 설정

void main(void) {
    // 시스템 초기화: 클럭, PLL, 주변 장치 설정
    Device_init();
    
    // 인터럽트 컨트롤러 초기화
    Interrupt_initModule();
    
    // 인터럽트 벡터 테이블 초기화
    Interrupt_initVectorTable();
    
    // GPIO 초기화: SCI TX/RX 핀 설정
    initGPIO();
    
    // SCI 초기화: FIFO 활성화 및 설정
    initSCI();
    
    // 글로벌 인터럽트 활성화
    EINT;
    
    // 실시간 인터럽트 활성화
    ERTM;
    
    // 송신 문자열 정의: FIFO를 통해 송신
    char message[] = "Hello, SCI with FIFO!\n";
    
    // 문자열 송신: 문자 배열을 송신 FIFO에 기록
    SCI_writeCharArray(SCIA_BASE, (uint16_t*)message, sizeof(message));
    
    // 송신 FIFO 상태 확인: 송신 완료 대기
    while (SCI_getTxFIFOStatus(SCIA_BASE) > 0) {
        // 송신 FIFO에 데이터가 남아 있으면 대기
    }
    
    // 수신 데이터 저장 배열: 최대 32바이트
    uint16_t receivedData[32];
    
    // 수신 데이터 인덱스
    uint16_t index = 0;
    
    // 무한 루프: 수신 데이터 처리
    while(1) {
        // 수신 FIFO 상태 확인: 데이터가 있는지 확인
        if (SCI_getRxFIFOStatus(SCIA_BASE) > 0) {
            // 단일 문자 수신: FIFO에서 한 문자 읽기
            SCI_readCharArray(SCIA_BASE, &receivedData[index], 1);
            
            // 인덱스 증가
            index++;
            
            // 버퍼 오버플로우 방지: 배열 크기 초과 시 초기화
            if (index >= 32) {
                index = 0;
                
                // 수신 데이터 에코백: 수신된 데이터를 다시 송신
                SCI_writeCharArray(SCIA_BASE, receivedData, 32);
            }
        }
    }
}

// GPIO 초기화 함수
void initGPIO(void) {
    // SCIA TX 핀 설정: GPIO28
    GPIO_setPinConfig(GPIO_28_SCIA_TX);
    
    // SCIA RX 핀 설정: GPIO29
    GPIO_setPinConfig(GPIO_29_SCIA_RX);
    
    // TX 핀 방향: 출력
    GPIO_setDirectionMode(28, GPIO_DIR_MODE_OUT);
    
    // RX 핀 방향: 입력
    GPIO_setDirectionMode(29, GPIO_DIR_MODE_IN);
    
    // TX 핀 패드: 표준 출력
    GPIO_setPadConfig(28, GPIO_PIN_TYPE_STD);
    
    // RX 핀 패드: 풀업 저항 활성화
    GPIO_setPadConfig(29, GPIO_PIN_TYPE_PULLUP);
    
    // RX 핀 입력 자격: 비동기 입력
    GPIO_setQualificationMode(29, GPIO_QUAL_ASYNC);
}

// SCI 초기화 함수: FIFO 포함
void initSCI(void) {
    // SCI 모듈 비활성화: 설정 변경 전 비활성화
    SCI_disableModule(SCIA_BASE);
    
    // 송신 채널 리셋: 송신 상태 초기화
    SCI_resetTransmitter(SCIA_BASE);
    
    // 수신 채널 리셋: 수신 상태 초기화
    SCI_resetReceiver(SCIA_BASE);
    
    // SCI 설정: 115200bps, 8비트 데이터, 1 스톱 비트, 패리티 없음
    SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 115200, 
                  (SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE));
    
    // FIFO 활성화: 송수신 FIFO 사용
    SCI_enableFIFO(SCIA_BASE);
    
    // FIFO 인터럽트 레벨 설정: 송신/수신 4바이트 트리거
    SCI_setFIFOInterruptLevel(SCIA_BASE, SCI_FIFO_TX4, SCI_FIFO_RX4);
    
    // 송신 FIFO 리셋: 초기화
    SCI_resetTxFIFO(SCIA_BASE);
    
    // 수신 FIFO 리셋: 초기화
    SCI_resetRxFIFO(SCIA_BASE);
    
    // SCI 모듈 활성화: 통신 시작
    SCI_enableModule(SCIA_BASE);
}

예제 3: 인터럽트 및 패리티 설정

인터럽트패리티를 사용하여 데이터를 처리합니다.

// 예제 3: 인터럽트 및 패리티 설정 (TMS320F28388D, Driverlib API)
#include "driverlib.h" // Driverlib 헤더
#include "device.h"    // 디바이스별 설정

// 함수 선언
void initGPIO(void);          // GPIO 설정
void initSCI(void);           // SCI 및 패리티 설정
void initSCIInterrupts(void); // SCI 인터럽트 설정
__interrupt void sciRxISR(void); // 수신 인터럽트 서비스 루틴
__interrupt void sciTxISR(void); // 송신 인터럽트 서비스 루틴

// 전역 변수: 수신 데이터 저장
volatile uint16_t receivedData[16];

// 전역 변수: 수신 데이터 인덱스
volatile uint16_t rxIndex = 0;

void main(void) {
    // 시스템 초기화: 클럭, PLL, 주변 장치 설정
    Device_init();
    
    // 인터럽트 컨트롤러 초기화
    Interrupt_initModule();
    
    // 인터럽트 벡터 테이블 초기화
    Interrupt_initVectorTable();
    
    // GPIO 초기화
    initGPIO();
    
    // SCI 초기화: 패리티 및 인터럽트 설정
    initSCI();
    
    // SCI 인터럽트 초기화
    initSCIInterrupts();
    
    // 글로벌 인터럽트 활성화
    EINT;
    
    // 실시간 인터럽트 활성화
    ERTM;
    
    // 송신 문자열 정의
    char message[] = "Interrupt-based SCI!\n";
    
    // 문자열 송신: 인터럽트를 통해 처리
    SCI_writeCharArray(SCIA_BASE, (uint16_t*)message, sizeof(message));
    
    // 무한 루프: 인터럽트로 데이터 처리
    while(1) {
        // 인터럽트 서비스 루틴에서 모든 작업 처리
    }
}

// GPIO 초기화 함수
void initGPIO(void) {
    // SCIA TX 핀 설정: GPIO28
    GPIO_setPinConfig(GPIO_28_SCIA_TX);
    
    // SCIA RX 핀 설정: GPIO29
    GPIO_setPinConfig(GPIO_29_SCIA_RX);
    
    // TX 핀 방향: 출력
    GPIO_setDirectionMode(28, GPIO_DIR_MODE_OUT);
    
    // RX 핀 방향: 입력
    GPIO_setDirectionMode(29, GPIO_DIR_MODE_IN);
    
    // TX 핀 패드: 표준
    GPIO_setPadConfig(28, GPIO_PIN_TYPE_STD);
    
    // RX 핀 패드: 풀업 저항
    GPIO_setPadConfig(29, GPIO_PIN_TYPE_PULLUP);
    
    // RX 핀 입력 자격: 비동기
    GPIO_setQualificationMode(29, GPIO_QUAL_ASYNC);
}

// SCI 초기화 함수: 패리티 및 FIFO 설정
void initSCI(void) {
    // SCI 모듈 비활성화: 설정 변경 전 비활성화
    SCI_disableModule(SCIA_BASE);
    
    // 송수신 채널 리셋: 초기 상태 복구
    SCI_resetChannels(SCIA_BASE);
    
    // SCI 설정: 9600bps, 7비트 데이터, 2 스톱 비트, Even 패리티
    SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 9600, 
                  (SCI_CONFIG_WLEN_7 | SCI_CONFIG_STOP_TWO | SCI_CONFIG_PAR_EVEN));
    
    // 패리티 활성화: 데이터 무결성 보장
    SCI_enableParity(SCIA_BASE);
    
    // 패리티 모드 설정: Even 패리티
    SCI_setParityMode(SCIA_BASE, SCI_PAR_EVEN);
    
    // FIFO 활성화: 다중 데이터 처리
    SCI_enableFIFO(SCIA_BASE);
    
    // FIFO 인터럽트 레벨 설정: 4바이트 트리거
    SCI_setFIFOInterruptLevel(SCIA_BASE, SCI_FIFO_TX4, SCI_FIFO_RX4);
    
    // 송신 FIFO 리셋
    SCI_resetTxFIFO(SCIA_BASE);
    
    // 수신 FIFO 리셋
    SCI_resetRxFIFO(SCIA_BASE);
    
    // SCI 모듈 활성화
    SCI_enableModule(SCIA_BASE);
}

// SCI 인터럽트 초기화 함수
void initSCIInterrupts(void) {
    // 송신/수신 인터럽트 활성화: FIFO 인터럽트 사용
    SCI_enableInterrupt(SCIA_BASE, (SCI_INT_RXFF | SCI_INT_TXFF));
    
    // 수신 인터럽트 벡터 등록
    Interrupt_register(INT_SCIA_RX, &sciRxISR);
    
    // 송신 인터럽트 벡터 등록
    Interrupt_register(INT_SCIA_TX, &sciTxISR);
    
    // 수신 인터럽트 활성화
    Interrupt_enable(INT_SCIA_RX);
    
    // 송신 인터럽트 활성화
    Interrupt_enable(INT_SCIA_TX);
}

// 수신 인터럽트 서비스 루틴
__interrupt void sciRxISR(void) {
    // 인터럽트 상태 확인: 수신 FIFO 인터럽트 발생 여부
    if (SCI_getInterruptStatus(SCIA_BASE) & SCI_INT_RXFF) {
        // 비차단 모드로 데이터 수신
        receivedData[rxIndex] = SCI_readCharNonBlocking(SCIA_BASE);
        
        // 인덱스 증가
        rxIndex++;
        
        // 버퍼 오버플로우 방지
        if (rxIndex >= 16) {
            rxIndex = 0;
            
            // 수신 데이터 에코백
            SCI_writeCharArray(SCIA_BASE, (uint16_t*)receivedData, 16);
        }
    }
    
    // 수신 인터럽트 플래그 지우기
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF);
    
    // 인터럽트 그룹 확인: 그룹 9
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

// 송신 인터럽트 서비스 루틴
__interrupt void sciTxISR(void) {
    // 송신 인터럽트 플래그 지우기
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXFF);
    
    // 인터럽트 그룹 확인
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

예제 4: 루프백 및 오토보드 록 테스트

루프백 모드오토보드 록을 사용하여 SCI 모듈을 테스트합니다.

// 예제 4: 루프백 및 오토보드 록 테스트 (TMS320F28388D, Driverlib API)
#include "driverlib.h" // Driverlib 헤더
#include "device.h"    // 디바이스별 설정

// 함수 선언
void initGPIO(void); // GPIO 설정
void initSCI(void);  // SCI 및 루프백 설정

void main(void) {
    // 시스템 초기화: 클럭, PLL, 주변 장치 설정
    Device_init();
    
    // 인터럽트 컨트롤러 초기화
    Interrupt_initModule();
    
    // 인터럽트 벡터 테이블 초기화
    Interrupt_initVectorTable();
    
    // GPIO 초기화
    initGPIO();
    
    // SCI 초기화: 루프백 및 오토보드 록 설정
    initSCI();
    
    // 글로벌 인터럽트 활성화
    EINT;
    
    // 실시간 인터럽트 활성화
    ERTM;
    
    // 테스트 문자열 정의
    char testMessage[] = "Loopback Test\n";
    
    // 문자열 송신: 루프백 모드로 내부 수신
    SCI_writeCharArray(SCIA_BASE, (uint16_t*)testMessage, sizeof(testMessage));
    
    // 수신 데이터 저장 변수
    uint16_t receivedChar;
    
    // 무한 루프: 수신 데이터 처리
    while(1) {
        // 수신 상태 확인: 데이터 준비 여부
        if (SCI_getRxStatus(SCIA_BASE) & SCI_RXSTATUS_READY) {
            // 비차단 모드로 데이터 수신
            receivedChar = SCI_readCharNonBlocking(SCIA_BASE);
            
            // 루프백이므로 송신 데이터와 동일해야 함
            SCI_writeCharBlocking(SCIA_BASE, receivedChar);
        }
    }
}

// GPIO 초기화 함수
void initGPIO(void) {
    // SCIA TX 핀 설정: GPIO28
    GPIO_setPinConfig(GPIO_28_SCIA_TX);
    
    // SCIA RX 핀 설정: GPIO29
    GPIO_setPinConfig(GPIO_29_SCIA_RX);
    
    // TX 핀 방향: 출력
    GPIO_setDirectionMode(28, GPIO_DIR_MODE_OUT);
    
    // RX 핀 방향: 입력
    GPIO_setDirectionMode(29, GPIO_DIR_MODE_IN);
    
    // TX 핀 패드: 표준
    GPIO_setPadConfig(28, GPIO_PIN_TYPE_STD);
    
    // RX 핀 패드: 풀업 저항
    GPIO_setPadConfig(29, GPIO_PIN_TYPE_PULLUP);
    
    // RX 핀 입력 자격: 비동기
    GPIO_setQualificationMode(29, GPIO_QUAL_ASYNC);
}

// SCI 초기화 함수: 루프백 및 오토보드 록
void initSCI(void) {
    // SCI 모듈 비활성화
    SCI_disableModule(SCIA_BASE);
    
    // 송수신 채널 리셋
    SCI_resetChannels(SCIA_BASE);
    
    // SCI 설정: 9600bps, 8비트 데이터, 1 스톱 비트, 패리티 없음
    SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 9600, 
                  (SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE));
    
    // 루프백 모드 활성화: 송신 데이터를 내부적으로 수신
    SCI_enableLoopback(SCIA_BASE);
    
    // 오토보드 록 활성화: 자동 보드레이트 동기화
    SCI_enableAutoBaud(SCIA_BASE);
    
    // SCI 모듈 활성화
    SCI_enableModule(SCIA_BASE);
}

예제 5: 보드레이트 동적 변경 및 상태 확인

보드레이트를 동적으로 변경하고 상태 확인 함수를 활용합니다.

// 예제 5: 보드레이트 동적 변경 및 상태 확인 (TMS320F28388D, Driverlib API)
#include "driverlib.h" // Driverlib 헤더
#include "device.h"    // 디바이스별 설정

// 함수 선언
void initGPIO(void); // GPIO 설정
void initSCI(void);  // SCI 설정

void main(void) {
    // 시스템 초기화: 클럭, PLL, 주변 장치 설정
    Device_init();
    
    // 인터럽트 컨트롤러 초기화
    Interrupt_initModule();
    
    // 인터럽트 벡터 테이블 초기화
    Interrupt_initVectorTable();
    
    // GPIO 초기화
    initGPIO();
    
    // SCI 초기화
    initSCI();
    
    // 글로벌 인터럽트 활성화
    EINT;
    
    // 실시간 인터럽트 활성화
    ERTM;
    
    // 초기 보드레이트 문자열
    char message[] = "Initial Baud: 9600\n";
    
    // 문자열 송신
    SCI_writeCharArray(SCIA_BASE, (uint16_t*)message, sizeof(message));
    
    // 보드레이트 변경: 115200bps로 동적 변경
    SCI_setBaudRate(SCIA_BASE, DEVICE_LSPCLK_FREQ, 115200);
    
    // 변경된 보드레이트 문자열
    char newMessage[] = "New Baud: 115200\n";
    
    // 문자열 송신
    SCI_writeCharArray(SCIA_BASE, (uint16_t*)newMessage, sizeof(newMessage));
    
    // 수신 데이터 저장 변수
    uint16_t receivedChar;
    
    // 무한 루프: 수신 데이터 처리
    while(1) {
        // 수신 상태 확인
        if (SCI_getRxStatus(SCIA_BASE) & SCI_RXSTATUS_READY) {
            // 비차단 모드로 데이터 수신
            receivedChar = SCI_readCharNonBlocking(SCIA_BASE);
            
            // 송신기 상태 확인: 송신 중이 아니면 전송
            if (!SCI_isTransmitterBusy(SCIA_BASE)) {
                SCI_writeCharBlocking(SCIA_BASE, receivedChar);
            }
        }
    }
}

// GPIO 초기화 함수
void initGPIO(void) {
    // SCIA TX 핀 설정: GPIO28
    GPIO_setPinConfig(GPIO_28_SCIA_TX);
    
    // SCIA RX 핀 설정: GPIO29
    GPIO_setPinConfig(GPIO_29_SCIA_RX);
    
    // TX 핀 방향: 출력
    GPIO_setDirectionMode(28, GPIO_DIR_MODE_OUT);
    
    // RX 핀 방향: 입력
    GPIO_setDirectionMode(29, GPIO_DIR_MODE_IN);
    
    // TX 핀 패드: 표준
    GPIO_setPadConfig(28, GPIO_PIN_TYPE_STD);
    
    // RX 핀 패드: 풀업 저항
    GPIO_setPadConfig(29, GPIO_PIN_TYPE_PULLUP);
    
    // RX 핀 입력 자격: 비동기
    GPIO_setQualificationMode(29, GPIO_QUAL_ASYNC);
}

// SCI 초기화 함수
void initSCI(void) {
    // SCI 모듈 비활성화
    SCI_disableModule(SCIA_BASE);
    
    // 송수신 채널 리셋
    SCI_resetChannels(SCIA_BASE);
    
    // 초기 SCI 설정: 9600bps, 8비트 데이터, 1 스톱 비트, 패리티 없음
    SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 9600, 
                  (SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE));
    
    // SCI 모듈 활성화
    SCI_enableModule(SCIA_BASE);
}

5. 디버깅 팁

  • 보드레이트 불일치: 송신/수신 장치의 보드레이트가 동일한지 확인 (SCI_setBaudRate 사용).
  • GPIO 핀 확인: TMS320F28388D 데이터시트에서 핀맵 확인 (예: GPIO28/TX, GPIO29/RX).
  • FIFO 상태 확인: SCI_getTxFIFOStatus, SCI_getRxFIFOStatus로 FIFO 상태 점검.
  • 인터럽트 문제: Interrupt_register, Interrupt_enable 호출 확인.
  • 루프백 테스트: 하드웨어 연결 문제 시 SCI_enableLoopback으로 테스트.
  • 오토보드 록: SCI_enableAutoBaud 사용 시 호환 장치 확인.
  • 디버거 사용: Code Composer Studio로 레지스터 값 확인.

6. 추가 참고 자료

  • C2000Ware: C2000Ware_x_xx_xx_xx\driverlib\f2838x\examples\c28x\sci에서 예제 코드 확인.
  • TI 문서: F2837xS Peripheral Driver Library User’s Guide, TMS320F28388D Technical Reference Manual.
  • Driverlib 소스: driverlib/sci.c, driverlib/sci.h에서 API 정의 확인.

키워드: TMS320F28388D SCI, Driverlib API, UART 설정, C2000 SCI 예제, FIFO 설정, 인터럽트 처리, 루프백 테스트, 오토보드 록, Code Composer Studio, C2000Ware

 

반응형