이 문서는 Texas Instruments의 TMS320F28388D 마이크로컨트롤러에서 SCI (Serial Communication Interface) 모듈을 Driverlib API를 사용하여 설정하고 사용하는 방법을 상세히 설명합니다. UART 기반 직렬 통신을 구현하는 데 필요한 모든 Driverlib SCI 함수를 다루며, FIFO, 인터럽트, 루프백 모드, 오토보드 록 등을 포함한 실습 가능한 예제 코드를 제공합니다. 각 코드에는 주석을 추가하여 초보자부터 숙련자까지 쉽게 이해할 수 있도록 했습니다. 이 문서는 C2000Ware와 Code 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
'MCU > C2000' 카테고리의 다른 글
[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 |
[TMS320F28388D] CPU 타이머 사용법 : Driverlib API로 CPU 타이머 설정과 예제 (0) | 2025.08.08 |
[TMS320F28388D] 프로젝트 설정 및 기본 프로그램 작성 절차 (0) | 2025.08.08 |
[TMS320F28335 ]ePWM SPWM 생성 (0) | 2025.08.07 |
[TMS320F28335] ePWM 하프 브리지 상보 출력 설정 (0) | 2025.08.07 |
[TMS320F28335] SCI 사용법: Bitfield 구조 활용 (0) | 2025.08.07 |