본문 바로가기
MCU/C2000

[TMS320F28388D] SPI 사용법: DriverLib API로 SPI 설정 및 코드

by linuxgo 2025. 8. 17.
반응형

소개

이 문서에서는 Texas Instruments의 TMS320F28388D 마이크로컨트롤러에서 SPI(Serial Peripheral Interface) 모듈을 DriverLib API를 사용하여 설정하고 사용하는 방법을 상세히 다룹니다. C2000 시리즈의 고성능 마이크로컨트롤러인 TMS320F28388D의 SPI 모듈을 활용하여 SPI 통신을 구현하는 방법을 배우고, 다양한 독립적인 예제 코드를 통해 실제 구현 방법을 익힐 수 있습니다. 각 코드에는 상세한 주석이 포함되어 있으며, Code Composer Studio(CCS) 환경에서 실행 가능합니다.

1. TMS320F28388D SPI 개요

TMS320F28388D는 Texas Instruments의 C2000 시리즈에 속하는 32비트 마이크로컨트롤러로, 최대 4개의 SPI 모듈(SPI-A, SPI-B, SPI-C, SPI-D)을 제공합니다. SPI는 마스터-슬레이브 구조의 고속 직렬 통신 프로토콜로, 센서, 디스플레이, 메모리 장치 등 다양한 주변 장치와의 통신에 적합합니다.

SPI 모듈의 주요 특징

  • 통신 속도: 시스템 클럭을 기반으로 최대 50Mbps 지원 (200MHz SYSCLK 기준).
  • 데이터 길이: 1~16비트 데이터 전송 지원.
  • 모드: 마스터 또는 슬레이브 모드 지원.
  • 클럭 폴러리티/페이즈: 4가지 SPI 모드(0~3) 지원.
  • 인터럽트: 송수신 완료 및 에러 인터럽트 지원.
  • FIFO: 16단어 송수신 FIFO 제공.
  • 고급 기능: 칩 셀렉트(CS) 관리, 루프백 테스트 모드.

DriverLib API는 하드웨어 레지스터를 직접 조작하는 대신 추abstraction된 함수를 제공하여 SPI 설정을 간소화합니다.

2. 주요 SPI DriverLib API 함수

아래는 TMS320F28388D의 SPI 모듈을 제어하기 위해 자주 사용되는 DriverLib API 함수와 그 사용 방법입니다.

2.1. SPI 기본 설정 관련 함수

  • SPI_initModule(base)
    • 설명: SPI 모듈을 초기화합니다.
    • 매개변수: base (SPI 모듈의 베이스 주소, 예: SPIA_BASE).
    • 사용 예: SPI_initModule(SPIA_BASE); // SPI-A 모듈 초기화.
  • SPI_setConfig(base, lspclk, baudRate, protocol, mode, bitCount)
    • 설명: SPI 설정(비트율, 프로토콜, 모드, 데이터 길이)을 구성합니다.
    • 매개변수:
      • base (SPI 모듈의 베이스 주소).
      • lspclk (저속 주변 클럭, Hz 단위).
      • baudRate (원하는 비트율, Hz 단위).
      • protocol (클럭 폴러리티/페이즈, 예: SPI_PROT_CLK0PHA0).
      • mode (마스터/슬레이브, 예: SPI_MODE_MASTER).
      • bitCount (데이터 비트 수, 1~16).
    • 사용 예: SPI_setConfig(SPIA_BASE, 50000000, 1000000, SPI_PROT_CLK0PHA0, SPI_MODE_MASTER, 8); // 1Mbps, 모드 0, 마스터, 8비트.
  • SPI_enableModule(base)
    • 설명: SPI 모듈을 활성화합니다.
    • 매개변수: base (SPI 모듈의 베이스 주소).
    • 사용 예: SPI_enableModule(SPIA_BASE); // SPI-A 모듈 활성화.
  • SPI_disableModule(base)
    • 설명: SPI 모듈을 비활성화합니다.
    • 매개변수: base (SPI 모듈의 베이스 주소).
    • 사용 예: SPI_disableModule(SPIA_BASE); // SPI-A 모듈 비활성화.

2.2. 데이터 송수신 관련 함수

  • SPI_writeDataNonBlocking(base, data)
    • 설명: 비차단 방식으로 데이터를 전송합니다. FIFO가 가득 차면 데이터가 무시될 수 있음.
    • 매개변수:
      • base (SPI 모듈의 베이스 주소).
      • data (전송할 데이터, 최대 16비트).
    • 사용 예: SPI_writeDataNonBlocking(SPIA_BASE, 0x55); // 8비트 데이터 0x55 전송.
  • SPI_readDataNonBlocking(base)
    • 설명: 비차단 방식으로 데이터를 수신합니다.
    • 매개변수: base (SPI 모듈의 베이스 주소).
    • 반환값: 수신된 데이터 (16비트).
    • 사용 예: uint16_t rxData = SPI_readDataNonBlocking(SPIA_BASE); // 수신 데이터 읽기.
  • SPI_transmitReceive(base, txData)
    • 설명: 데이터를 송수신합니다 (차단 방식). 송신과 동시에 수신 데이터를 반환.
    • 매개변수:
      • base (SPI 모듈의 베이스 주소).
      • txData (전송 데이터, 최대 16비트).
    • 반환값: 수신된 데이터.
    • 사용 예: uint16_t rxData = SPI_transmitReceive(SPIA_BASE, 0xAA); // 0xAA 송신 후 수신 데이터 반환.

2.3. 인터럽트 관련 함수

  • SPI_enableInterrupt(base, intFlags)
    • 설명: SPI 인터럽트를 활성화합니다.
    • 매개변수:
      • base (SPI 모듈의 베이스 주소).
      • intFlags (인터럽트 플래그, 예: SPI_INT_RX_DATA for 수신 인터럽트).
    • 사용 예: SPI_enableInterrupt(SPIA_BASE, SPI_INT_RX_DATA); // 수신 인터럽트 활성화.
  • SPI_clearInterruptStatus(base, intFlags)
    • 설명: 인터럽트 플래그를 지웁니다.
    • 매개변수:
      • base (SPI 모듈의 베이스 주소).
      • intFlags (지울 인터럽트 플래그).
    • 사용 예: SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RX_DATA); // 수신 인터럽트 플래그 지우기.
  • Interrupt_register(intNumber, handler)
    • 설명: 인터럽트 서비스 루틴(ISR)을 등록합니다.
    • 매개변수:
      • intNumber (인터럽트 번호, 예: INT_SPIA_RX).
      • handler (ISR 함수 포인터).
    • 사용 예: Interrupt_register(INT_SPIA_RX, &spiAISR); // SPI-A 수신 ISR 등록.

3. SPI 설정 및 동작 원리

  1. 시스템 초기화: 시스템 클럭과 GPIO 초기화(Device_init(), Device_initGPIO()), 인터럽트 모듈 초기화.
  2. SPI 모듈 설정: 클럭 활성화, 비트율, 모드, 데이터 길이 설정.
  3. 인터럽트 설정(선택): 인터럽트 활성화 및 ISR 등록.
  4. SPI 활성화: SPI 모듈 활성화 및 송수신 시작.

4. SPI 예제 코드

아래는 독립적인 SPI 예제 코드로, C2000Ware의 DriverLib를 기반으로 작성되었습니다. GPIO 설정은 별도의 initGPIO() 함수로 분리되어 있으며, 모든 코드는 CCS에서 바로 실행 가능합니다. 비트율 계산, SPI 모드, 칩 셀렉트(CS) 관리는 코드와 주석에 명시적으로 포함됩니다.

4.1. 예제 1: 기본 SPI 마스터 송신

SPI-A를 사용하여 1Mbps로 8비트 데이터를 마스터 모드로 전송합니다.

#include "driverlib.h"
#include "device.h"

// 디버깅용 상태 변수: SPI 모듈의 현재 상태를 추적
volatile uint32_t spiStatus = 0; // 0: 초기화 완료, 1: SPI 동작 중, 0xFFFF: 오류

// 칩 셀렉트 핀 정의 (외부 GPIO 사용)
#define CS_PIN 19 // GPIO19를 칩 셀렉트로 사용 (STE 핀과 동일)

// GPIO 초기화 함수: SPI 통신 및 디버깅용 LED 핀 설정
void initGPIO(void)
{
    // SPI-A SIMO 핀 설정 (GPIO16)
    GPIO_setPinConfig(GPIO_16_SPIA_SIMO);       // GPIO16을 SPI-A SIMO(마스터 출력)로 설정
    GPIO_setDirectionMode(16, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(16, GPIO_PULL_UP);        // 풀업 저항 활성화 (외부 회로에 따라 조정 가능)

    // SPI-A SOMI 핀 설정 (GPIO17)
    GPIO_setPinConfig(GPIO_17_SPIA_SOMI);       // GPIO17을 SPI-A SOMI(마스터 입력)로 설정
    GPIO_setDirectionMode(17, GPIO_DIR_MODE_IN); // 입력 모드로 설정
    GPIO_setPadConfig(17, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A CLK 핀 설정 (GPIO18)
    GPIO_setPinConfig(GPIO_18_SPIA_CLK);        // GPIO18을 SPI-A 클럭 핀으로 설정
    GPIO_setDirectionMode(18, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(18, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A STE 핀 설정 (GPIO19, 칩 셀렉트)
    GPIO_setPinConfig(GPIO_19_SPIA_STE);        // GPIO19를 SPI-A STE(칩 셀렉트)로 설정
    GPIO_setDirectionMode(19, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(19, GPIO_PULL_UP);        // 풀업 저항 활성화
    GPIO_writePin(CS_PIN, 1);                   // CS 핀 초기 상태 HIGH (비활성화)
    
    // 디버깅용 LED 설정 (GPIO34, 예: LAUNCHXL-F28379D 기준)
    GPIO_setPinConfig(GPIO_34_GPIO34);          // GPIO34를 일반 GPIO로 설정
    GPIO_setDirectionMode(34, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(34, GPIO_PULL_UP);        // 풀업 저항 활성화
    GPIO_writePin(34, 0);                       // 초기 LED 상태 OFF
}

// SPI-A 초기화 함수: SPI 모듈 설정 및 활성화
void initSPI(void)
{
    // SPI-A 클럭 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIA); // SPI-A 모듈에 시스템 클럭 공급

    // SPI 모듈 초기화
    SPI_disableModule(SPIA_BASE);                   // 설정 전 모듈 비활성화
    SPI_initModule(SPIA_BASE);                     // SPI-A 모듈 기본 초기화 (레지스터 리셋)

    // 비트율 계산: 비트율 = LSPCLK / (BRP + 1)
    // 예: LSPCLK = 50MHz, 목표 비트율 = 1Mbps
    // BRP = (50MHz / 1Mbps) - 1 = 49
    uint32_t lspclk = DEVICE_LSPCLK_FREQ;           // 저속 주변 클럭 (50MHz 가정)
    uint32_t baudRate = 1000000;                    // 목표 비트율: 1Mbps
    uint16_t brp = (lspclk / baudRate) - 1;         // BRP 계산 (49)

    // SPI 설정: 비트율, 모드, 마스터/슬레이브, 데이터 길이
    SPI_setConfig(SPIA_BASE, lspclk, baudRate,      // 비트율 1Mbps
                  SPI_PROT_CLK0PHA0,                // SPI 모드 0 (CPOL=0, CPHA=0, 슬레이브 데이터시트 확인)
                  SPI_MODE_MASTER,                  // 마스터 모드
                  8);                               // 8비트 데이터 길이

    // 송수신 FIFO 활성화
    SPI_enableFIFO(SPIA_BASE);                     // 16단어 FIFO를 활성화하여 데이터 버퍼링

    // SPI 모듈 활성화
    SPI_enableModule(SPIA_BASE);                   // SPI-A 모듈 동작 시작

    // 상태 업데이트
    spiStatus = 1;                                 // SPI 동작 중 상태로 설정
}

void main(void)
{
    // 시스템 초기화: PLL, Watchdog, 주변 장치 클럭 설정
    Device_init();                                  // 시스템 클럭, Watchdog, 주변 장치 초기화

    // GPIO 기본 초기화
    Device_initGPIO();                              // GPIO 모듈 초기화 (기본 설정)

    // SPI 관련 GPIO 설정
    initGPIO();                                     // SPI 핀 및 디버깅용 LED 설정

    // 인터럽트 모듈 초기화
    Interrupt_initModule();                         // 인터럽트 컨트롤러 초기화
    Interrupt_initVectorTable();                    // 인터럽트 벡터 테이블 초기화

    // 시스템 클럭 검증
    uint32_t sysClockHz = SysCtl_getClock(DEVICE_OSCSRC_FREQ); // 시스템 클럭 주파수 확인
    if (sysClockHz != 200000000)                    // 클럭이 200MHz가 아닌 경우 오류 처리
    {
        spiStatus = 0xFFFF;                         // 오류 상태 설정
        GPIO_writePin(34, 0);                       // LED OFF로 오류 표시
        ESTOP0;                                     // 디버깅용 정지 (CCS에서 확인 가능)
    }

    // SPI-A 초기화
    initSPI();                                      // SPI-A 모듈 초기화 및 설정

    // 초기화 오류 확인
    if (spiStatus != 1)                             // 초기화 실패 시 오류 처리
    {
        spiStatus = 0xFFFF;                         // 오류 상태 설정
        GPIO_writePin(34, 0);                       // LED OFF로 오류 표시
        ESTOP0;                                     // 디버깅용 정지
    }

    // 글로벌 인터럽트 활성화
    EINT;                                           // CPU 인터럽트 활성화

    // Watchdog 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_WD);  // Watchdog 모듈에 클럭 공급
    SysCtl_serviceWatchdog();                       // Watchdog 서비스 시작 (타이머 리셋)

    // 테스트 데이터 준비
    uint16_t txData = 0x55AA;                       // 송신 데이터 (16비트, 하위 8비트 사용)

    // 메인 루프: SPI 데이터 전송
    for(;;)
    {
        // 칩 셀렉트 활성화 (LOW)
        GPIO_writePin(CS_PIN, 0);                   // CS 핀을 LOW로 설정하여 슬레이브 선택

        // SPI 데이터 전송 (비차단 방식)
        SPI_writeDataNonBlocking(SPIA_BASE, txData); // 8비트 데이터 전송 (FIFO에 저장)

        // 칩 셀렉트 비활성화 (HIGH)
        GPIO_writePin(CS_PIN, 1);                   // CS 핀을 HIGH로 설정하여 슬레이브 해제

        // 디버깅용: 상태 표시
        GPIO_writePin(34, (spiStatus == 1) ? 1 : 0); // 정상 동작 시 LED ON
        DEVICE_DELAY_US(1000000);                   // 1초 대기 (CPU 부하 감소)
    }
}

설명:

  • 기능: SPI-A를 통해 1Mbps로 8비트 데이터를 마스터 모드로 전송, 칩 셀렉트 관리.
  • 설정: 비트율 1Mbps (BRP=49), 모드 0(CPOL=0, CPHA=0), 마스터 모드, 8비트 데이터.
  • GPIO: GPIO16(SIMO), GPIO17(SOMI), GPIO18(CLK), GPIO19(STE, CS), GPIO34(LED).
  • 칩 셀렉트: GPIO19(STE)를 수동으로 제어하여 슬레이브 선택/해제.
  • 출력: SPI 데이터 주기적 전송, 정상 동작 시 LED ON.

4.2. 예제 2: SPI 수신 및 인터럽트

SPI-A를 사용하여 데이터를 수신하고 인터럽트를 통해 처리합니다.

#include "driverlib.h"
#include "device.h"

// 디버깅용 상태 변수: SPI 모듈의 현재 상태를 추적
volatile uint32_t spiStatus = 0; // 0: 초기화 완료, 1: SPI 동작 중, 0xFFFF: 오류

// 수신 데이터 저장 버퍼
volatile uint16_t rxData = 0;   // 수신된 데이터를 저장
volatile uint16_t rxFlag = 0;   // 수신 완료 플래그 (인터럽트 발생 시 설정)

// 칩 셀렉트 핀 정의
#define CS_PIN 19 // GPIO19를 칩 셀렉트로 사용 (STE 핀과 동일)

// GPIO 초기화 함수: SPI 통신 및 디버깅용 LED 핀 설정
void initGPIO(void)
{
    // SPI-A SIMO 핀 설정 (GPIO16)
    GPIO_setPinConfig(GPIO_16_SPIA_SIMO);       // GPIO16을 SPI-A SIMO(마스터 출력)로 설정
    GPIO_setDirectionMode(16, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(16, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A SOMI 핀 설정 (GPIO17)
    GPIO_setPinConfig(GPIO_17_SPIA_SOMI);       // GPIO17을 SPI-A SOMI(마스터 입력)로 설정
    GPIO_setDirectionMode(17, GPIO_DIR_MODE_IN); // 입력 모드로 설정
    GPIO_setPadConfig(17, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A CLK 핀 설정 (GPIO18)
    GPIO_setPinConfig(GPIO_18_SPIA_CLK);        // GPIO18을 SPI-A 클럭 핀으로 설정
    GPIO_setDirectionMode(18, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(18, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A STE 핀 설정 (GPIO19)
    GPIO_setPinConfig(GPIO_19_SPIA_STE);        // GPIO19를 SPI-A STE(칩 셀렉트)로 설정
    GPIO_setDirectionMode(19, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(19, GPIO_PULL_UP);        // 풀업 저항 활성화
    GPIO_writePin(CS_PIN, 1);                   // CS 핀 초기 상태 HIGH (비활성화)

    // 디버깅용 LED 설정 (GPIO34)
    GPIO_setPinConfig(GPIO_34_GPIO34);          // GPIO34를 일반 GPIO로 설정
    GPIO_setDirectionMode(34, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(34, GPIO_PULL_UP);        // 풀업 저항 활성화
    GPIO_writePin(34, 0);                       // 초기 LED 상태 OFF
}

// SPI 인터럽트 서비스 루틴: 데이터 수신 시 호출
__interrupt void spiAISR(void)
{
    // 데이터 수신
    rxData = SPI_readDataNonBlocking(SPIA_BASE); // FIFO에서 수신 데이터 읽기
    rxFlag = 1;                                 // 수신 플래그 설정 (수신 완료 표시)

    // 인터럽트 플래그 지우기
    SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RX_DATA); // 수신 인터럽트 플래그 클리어
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);        // PIE 그룹 6 인터럽트 ACK
}

// SPI-A 초기화 함수: SPI 모듈 설정 및 인터럽트 활성화
void initSPI(void)
{
    // SPI-A 클럭 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIA); // SPI-A 모듈에 클럭 공급

    // SPI 모듈 초기화
    SPI_disableModule(SPIA_BASE);                   // 설정 전 모듈 비활성화
    SPI_initModule(SPIA_BASE);                     // SPI-A 모듈 기본 초기화

    // 비트율 계산: 비트율 = LSPCLK / (BRP + 1)
    // 예: LSPCLK = 50MHz, 목표 비트율 = 1Mbps
    // BRP = (50MHz / 1Mbps) - 1 = 49
    uint32_t lspclk = DEVICE_LSPCLK_FREQ;           // 저속 주변 클럭 (50MHz 가정)
    uint32_t baudRate = 1000000;                    // 목표 비트율: 1Mbps
    uint16_t brp = (lspclk / baudRate) - 1;         // BRP 계산 (49)

    // SPI 설정
    SPI_setConfig(SPIA_BASE, lspclk, baudRate,      // 비트율 1Mbps
                  SPI_PROT_CLK0PHA0,                // SPI 모드 0 (CPOL=0, CPHA=0, 슬레이브 데이터시트 확인)
                  SPI_MODE_MASTER,                  // 마스터 모드
                  8);                               // 8비트 데이터 길이

    // FIFO 활성화
    SPI_enableFIFO(SPIA_BASE);                     // 송수신 FIFO 활성화

    // 인터럽트 활성화
    SPI_enableInterrupt(SPIA_BASE, SPI_INT_RX_DATA); // 수신 완료 인터럽트 활성화

    // SPI 모듈 활성화
    SPI_enableModule(SPIA_BASE);                   // SPI-A 모듈 동작 시작

    // 상태 업데이트
    spiStatus = 1;                                 // SPI 동작 중 상태로 설정
}

void main(void)
{
    // 시스템 초기화
    Device_init();                                  // PLL, Watchdog, 주변 장치 클럭 설정

    // GPIO 기본 초기화
    Device_initGPIO();                              // GPIO 모듈 초기화

    // SPI 관련 GPIO 설정
    initGPIO();                                     // SPI 핀 및 디버깅용 LED 설정

    // 인터럽트 모듈 초기화
    Interrupt_initModule();                         // 인터럽트 컨트롤러 초기화
    Interrupt_initVectorTable();                    // 인터럽트 벡터 테이블 초기화

    // SPI 인터럽트 ISR 등록
    Interrupt_register(INT_SPIA_RX, &spiAISR);      // SPI-A 수신 인터럽트 서비스 루틴 등록

    // 시스템 클럭 검증
    uint32_t sysClockHz = SysCtl_getClock(DEVICE_OSCSRC_FREQ); // 시스템 클럭 주파수 확인
    if (sysClockHz != 200000000)                    // 클럭이 200MHz가 아닌 경우 오류 처리
    {
        spiStatus = 0xFFFF;                         // 오류 상태 설정
        GPIO_writePin(34, 0);                       // LED OFF로 오류 표시
        ESTOP0;                                     // 디버깅용 정지
    }

    // SPI-A 초기화
    initSPI();                                      // SPI-A 모듈 초기화 및 설정

    // 초기화 오류 확인
    if (spiStatus != 1)                             // 초기화 실패 시 오류 처리
    {
        spiStatus = 0xFFFF;                         // 오류 상태 설정
        GPIO_writePin(34, 0);                       // LED OFF로 오류 표시
        ESTOP0;                                     // 디버깅용 정지
    }

    // 글로벌 인터럽트 활성화
    EINT;                                           // CPU 인터럽트 활성화

    // Watchdog 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_WD);  // Watchdog 클럭 활성화
    SysCtl_serviceWatchdog();                       // Watchdog 서비스 시작

    // 메인 루프: 상태 모니터링
    for(;;)
    {
        // 디버깅용: 상태 표시
        GPIO_writePin(34, (spiStatus == 1 && rxFlag == 1) ? 1 : 0); // 데이터 수신 시 LED ON
        DEVICE_DELAY_US(1000000);                   // 1초 대기 (CPU 부하 감소)
    }
}

설명:

  • 기능: SPI-A를 통해 8비트 데이터 수신, 인터럽트로 처리.
  • 설정: 비트율 1Mbps (BRP=49), 모드 0(CPOL=0, CPHA=0), 마스터 모드, 8비트 데이터, 수신 인터럽트 활성화.
  • GPIO: GPIO16(SIMO), GPIO17(SOMI), GPIO18(CLK), GPIO19(STE, CS), GPIO34(LED).
  • 칩 셀렉트: GPIO19(STE)를 수동으로 제어 (수신에서는 외부 마스터가 CS 제어).
  • 출력: 데이터 수신 시 rxFlag 설정, LED ON.

4.3. 예제 3: SPI 송수신 및 에러 처리

SPI-A를 사용하여 송수신을 동시에 수행하고 에러를 감지합니다.

#include "driverlib.h"
#include "device.h"

// 디버깅용 상태 변수: SPI 모듈의 현재 상태를 추적
volatile uint32_t spiStatus = 0; // 0: 초기화 완료, 1: SPI 동작 중, 0xFFFF: 오류
volatile uint32_t errorCount = 0; // SPI 에러 발생 횟수 카운트

// 송수신 데이터
uint16_t txData = 0xAA55;       // 송신 데이터 (16비트, 하위 8비트 사용)
volatile uint16_t rxData = 0;   // 수신된 데이터를 저장
volatile uint16_t rxFlag = 0;   // 수신 완료 플래그

// 칩 셀렉트 핀 정의
#define CS_PIN 19 // GPIO19를 칩 셀렉트로 사용 (STE 핀과 동일)

// GPIO 초기화 함수: SPI 통신 및 디버깅용 LED 핀 설정
void initGPIO(void)
{
    // SPI-A SIMO 핀 설정 (GPIO16)
    GPIO_setPinConfig(GPIO_16_SPIA_SIMO);       // GPIO16을 SPI-A SIMO(마스터 출력)로 설정
    GPIO_setDirectionMode(16, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(16, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A SOMI 핀 설정 (GPIO17)
    GPIO_setPinConfig(GPIO_17_SPIA_SOMI);       // GPIO17을 SPI-A SOMI(마스터 입력)로 설정
    GPIO_setDirectionMode(17, GPIO_DIR_MODE_IN); // 입력 모드로 설정
    GPIO_setPadConfig(17, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A CLK 핀 설정 (GPIO18)
    GPIO_setPinConfig(GPIO_18_SPIA_CLK);        // GPIO18을 SPI-A 클럭 핀으로 설정
    GPIO_setDirectionMode(18, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(18, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A STE 핀 설정 (GPIO19)
    GPIO_setPinConfig(GPIO_19_SPIA_STE);        // GPIO19를 SPI-A STE(칩 셀렉트)로 설정
    GPIO_setDirectionMode(19, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(19, GPIO_PULL_UP);        // 풀업 저항 활성화
    GPIO_writePin(CS_PIN, 1);                   // CS 핀 초기 상태 HIGH (비활성화)

    // 디버깅용 LED 설정 (GPIO34)
    GPIO_setPinConfig(GPIO_34_GPIO34);          // GPIO34를 일반 GPIO로 설정
    GPIO_setDirectionMode(34, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(34, GPIO_PULL_UP);        // 풀업 저항 활성화
    GPIO_writePin(34, 0);                       // 초기 LED 상태 OFF
}

// SPI 에러 인터럽트 서비스 루틴: 에러 발생 시 호출
__interrupt void spiAErrorISR(void)
{
    // 에러 카운터 증가
    errorCount++;                               // 에러 발생 시 카운터 증가 (디버깅용)

    // 인터럽트 플래그 지우기
    SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RX_OVERRUN); // 수신 오버런 인터럽트 플래그 클리어
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);           // PIE 그룹 6 인터럽트 ACK

    // 상태 업데이트
    spiStatus = 0xFFFF;                         // 오류 상태 설정
}

// SPI 수신 인터럽트 서비스 루틴: 데이터 수신 시 호출
__interrupt void spiAISR(void)
{
    // 데이터 수신
    rxData = SPI_readDataNonBlocking(SPIA_BASE); // FIFO에서 수신 데이터 읽기
    rxFlag = 1;                                 // 수신 플래그 설정

    // 인터럽트 플래그 지우기
    SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RX_DATA); // 수신 인터럽트 플래그 클리어
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);        // PIE 그룹 6 인터럽트 ACK
}

// SPI-A 초기화 함수: SPI 모듈 설정 및 인터럽트 활성화
void initSPI(void)
{
    // SPI-A 클럭 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIA); // SPI-A 모듈에 클럭 공급

    // SPI 모듈 초기화
    SPI_disableModule(SPIA_BASE);                   // 설정 전 모듈 비활성화
    SPI_initModule(SPIA_BASE);                     // SPI-A 모듈 기본 초기화

    // 비트율 계산: 비트율 = LSPCLK / (BRP + 1)
    // 예: LSPCLK = 50MHz, 목표 비트율 = 1Mbps
    // BRP = (50MHz / 1Mbps) - 1 = 49
    uint32_t lspclk = DEVICE_LSPCLK_FREQ;           // 저속 주변 클럭 (50MHz 가정)
    uint32_t baudRate = 1000000;                    // 목표 비트율: 1Mbps
    uint16_t brp = (lspclk / baudRate) - 1;         // BRP 계산 (49)

    // SPI 설정
    SPI_setConfig(SPIA_BASE, lspclk, baudRate,      // 비트율 1Mbps
                  SPI_PROT_CLK0PHA0,                // SPI 모드 0 (CPOL=0, CPHA=0, 슬레이브 데이터시트 확인)
                  SPI_MODE_MASTER,                  // 마스터 모드
                  8);                               // 8비트 데이터 길이

    // FIFO 활성화
    SPI_enableFIFO(SPIA_BASE);                     // 송수신 FIFO 활성화

    // 인터럽트 활성화
    SPI_enableInterrupt(SPIA_BASE, SPI_INT_RX_DATA | SPI_INT_RX_OVERRUN); // 수신 및 오버런 인터럽트

    // SPI 모듈 활성화
    SPI_enableModule(SPIA_BASE);                   // SPI-A 모듈 동작 시작

    // 상태 업데이트
    spiStatus = 1;                                 // SPI 동작 중 상태로 설정
}

void main(void)
{
    // 시스템 초기화
    Device_init();                                  // PLL, Watchdog, 주변 장치 클럭 설정

    // GPIO 기본 초기화
    Device_initGPIO();                              // GPIO 모듈 초기화

    // SPI 관련 GPIO 설정
    initGPIO();                                     // SPI 핀 및 디버깅용 LED 설정

    // 인터럽트 모듈 초기화
    Interrupt_initModule();                         // 인터럽트 컨트롤러 초기화
    Interrupt_initVectorTable();                    // 인터럽트 벡터 테이블 초기화

    // SPI 인터럽트 ISR 등록
    Interrupt_register(INT_SPIA_RX, &spiAISR);      // 수신 인터럽트 서비스 루틴 등록
    Interrupt_register(INT_SPIA_TX, &spiAErrorISR); // 에러 인터럽트 서비스 루틴 등록

    // 시스템 클럭 검증
    uint32_t sysClockHz = SysCtl_getClock(DEVICE_OSCSRC_FREQ); // 시스템 클럭 주파수 확인
    if (sysClockHz != 200000000)                    // 클럭이 200MHz가 아닌 경우 오류 처리
    {
        spiStatus = 0xFFFF;                         // 오류 상태 설정
        GPIO_writePin(34, 0);                       // LED OFF로 오류 표시
        ESTOP0;                                     // 디버깅용 정지
    }

    // SPI-A 초기화
    initSPI();                                      // SPI-A 모듈 초기화 및 설정

    // 초기화 오류 확인
    if (spiStatus != 1)                             // 초기화 실패 시 오류 처리
    {
        spiStatus = 0xFFFF;                         // 오류 상태 설정
        GPIO_writePin(34, 0);                       // LED OFF로 오류 표시
        ESTOP0;                                     // 디버깅용 정지
    }

    // 글로벌 인터럽트 활성화
    EINT;                                           // CPU 인터럽트 활성화

    // Watchdog 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_WD);  // Watchdog 클럭 활성화
    SysCtl_serviceWatchdog();                       // Watchdog 서비스 시작

    // 메인 루프: SPI 데이터 송수신
    for(;;)
    {
        // 칩 셀렉트 활성화 (LOW)
        GPIO_writePin(CS_PIN, 0);                   // CS 핀을 LOW로 설정하여 슬레이브 선택

        // SPI 데이터 전송
        SPI_writeDataNonBlocking(SPIA_BASE, txData); // 8비트 데이터 전송

        // 칩 셀렉트 비활성화 (HIGH)
        GPIO_writePin(CS_PIN, 1);                   // CS 핀을 HIGH로 설정하여 슬레이브 해제

        // 디버깅용: 상태 표시
        GPIO_writePin(34, (spiStatus == 1 && errorCount == 0) ? 1 : 0); // 정상 동작 시 LED ON
        DEVICE_DELAY_US(1000000);                   // 1초 대기
    }
}

설명:

  • 기능: SPI-A로 송수신 동시 수행, 에러 인터럽트 처리.
  • 설정: 비트율 1Mbps (BRP=49), 모드 0(CPOL=0, CPHA=0), 마스터 모드, 8비트 데이터, 수신 및 오버런 인터럽트 활성화.
  • GPIO: GPIO16(SIMO), GPIO17(SOMI), GPIO18(CLK), GPIO19(STE, CS), GPIO34(LED).
  • 칩 셀렉트: GPIO19(STE)를 수동으로 제어하여 슬레이브 선택/해제.
  • 출력: 데이터 송수신, 에러 발생 시 LED OFF.

4.4. 예제 4: SPI 슬레이브 모드

SPI-A를 슬레이브 모드로 설정하여 데이터를 수신합니다.

#include "driverlib.h"
#include "device.h"

// 디버깅용 상태 변수: SPI 모듈의 현재 상태를 추적
volatile uint32_t spiStatus = 0; // 0: 초기화 완료, 1: SPI 동작 중, 0xFFFF: 오류

// 수신 데이터 저장 버퍼
volatile uint16_t rxData = 0;   // 수신된 데이터를 저장
volatile uint16_t rxFlag = 0;   // 수신 완료 플래그

// GPIO 초기화 함수: SPI 통신 및 디버깅용 LED 핀 설정
void initGPIO(void)
{
    // SPI-A SIMO 핀 설정 (GPIO16, 슬레이브에서는 입력)
    GPIO_setPinConfig(GPIO_16_SPIA_SIMO);       // GPIO16을 SPI-A SIMO로 설정
    GPIO_setDirectionMode(16, GPIO_DIR_MODE_IN); // 입력 모드로 설정 (슬레이브)
    GPIO_setPadConfig(16, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A SOMI 핀 설정 (GPIO17)
    GPIO_setPinConfig(GPIO_17_SPIA_SOMI);       // GPIO17을 SPI-A SOMI(슬레이브 출력)로 설정
    GPIO_setDirectionMode(17, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(17, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A CLK 핀 설정 (GPIO18, 슬레이브에서는 입력)
    GPIO_setPinConfig(GPIO_18_SPIA_CLK);        // GPIO18을 SPI-A 클럭 핀으로 설정
    GPIO_setDirectionMode(18, GPIO_DIR_MODE_IN); // 입력 모드로 설정 (슬레이브)
    GPIO_setPadConfig(18, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A STE 핀 설정 (GPIO19, 슬레이브에서는 입력)
    GPIO_setPinConfig(GPIO_19_SPIA_STE);        // GPIO19를 SPI-A STE(칩 셀렉트)로 설정
    GPIO_setDirectionMode(19, GPIO_DIR_MODE_IN); // 입력 모드로 설정 (슬레이브, 외부 마스터가 제어)
    GPIO_setPadConfig(19, GPIO_PULL_UP);        // 풀업 저항 활성화

    // 디버깅용 LED 설정 (GPIO34)
    GPIO_setPinConfig(GPIO_34_GPIO34);          // GPIO34를 일반 GPIO로 설정
    GPIO_setDirectionMode(34, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(34, GPIO_PULL_UP);        // 풀업 저항 활성화
    GPIO_writePin(34, 0);                       // 초기 LED 상태 OFF
}

// SPI 인터럽트 서비스 루틴: 데이터 수신 시 호출
__interrupt void spiAISR(void)
{
    // 데이터 수신
    rxData = SPI_readDataNonBlocking(SPIA_BASE); // FIFO에서 수신 데이터 읽기
    rxFlag = 1;                                 // 수신 플래그 설정

    // 인터럽트 플래그 지우기
    SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RX_DATA); // 수신 인터럽트 플래그 클리어
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);        // PIE 그룹 6 인터럽트 ACK
}

// SPI-A 초기화 함수: SPI 모듈을 슬레이브 모드로 설정
void initSPI(void)
{
    // SPI-A 클럭 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIA); // SPI-A 모듈에 클럭 공급

    // SPI 모듈 초기화
    SPI_disableModule(SPIA_BASE);                   // 설정 전 모듈 비활성화
    SPI_initModule(SPIA_BASE);                     // SPI-A 모듈 기본 초기화

    // 비트율 설정 (슬레이브 모드에서는 외부 마스터가 결정)
    // 참조용: 비트율 = LSPCLK / (BRP + 1), 예: 1Mbps 기준
    uint32_t lspclk = DEVICE_LSPCLK_FREQ;           // 저속 주변 클럭 (50MHz 가정)
    uint32_t baudRate = 1000000;                    // 참조 비트율: 1Mbps (마스터 기준)
    uint16_t brp = (lspclk / baudRate) - 1;         // BRP 계산 (49, 참조용)

    // SPI 설정
    SPI_setConfig(SPIA_BASE, lspclk, baudRate,      // 비트율 (마스터 기준, 참조용)
                  SPI_PROT_CLK0PHA0,                // SPI 모드 0 (CPOL=0, CPHA=0, 마스터 데이터시트 확인)
                  SPI_MODE_SLAVE,                   // 슬레이브 모드
                  8);                               // 8비트 데이터 길이

    // FIFO 활성화
    SPI_enableFIFO(SPIA_BASE);                     // 송수신 FIFO 활성화

    // 인터럽트 활성화
    SPI_enableInterrupt(SPIA_BASE, SPI_INT_RX_DATA); // 수신 완료 인터럽트 활성화

    // SPI 모듈 활성화
    SPI_enableModule(SPIA_BASE);                   // SPI-A 모듈 동작 시작

    // 상태 업데이트
    spiStatus = 1;                                 // SPI 동작 중 상태로 설정
}

void main(void)
{
    // 시스템 초기화
    Device_init();                                  // PLL, Watchdog, 주변 장치 클럭 설정

    // GPIO 기본 초기화
    Device_initGPIO();                              // GPIO 모듈 초기화

    // SPI 관련 GPIO 설정
    initGPIO();                                     // SPI 핀 및 디버깅용 LED 설정

    // 인터럽트 모듈 초기화
    Interrupt_initModule();                         // 인터럽트 컨트롤러 초기화
    Interrupt_initVectorTable();                    // 인터럽트 벡터 테이블 초기화

    // SPI 인터럽트 ISR 등록
    Interrupt_register(INT_SPIA_RX, &spiAISR);      // 수신 인터럽트 서비스 루틴 등록

    // 시스템 클럭 검증
    uint32_t sysClockHz = SysCtl_getClock(DEVICE_OSCSRC_FREQ); // 시스템 클럭 주파수 확인
    if (sysClockHz != 200000000)                    // 클럭이 200MHz가 아닌 경우 오류 처리
    {
        spiStatus = 0xFFFF;                         // 오류 상태 설정
        GPIO_writePin(34, 0);                       // LED OFF로 오류 표시
        ESTOP0;                                     // 디버깅용 정지
    }

    // SPI-A 초기화
    initSPI();                                      // SPI-A 모듈 초기화 및 설정

    // 초기화 오류 확인
    if (spiStatus != 1)                             // 초기화 실패 시 오류 처리
    {
        spiStatus = 0xFFFF;                         // 오류 상태 설정
        GPIO_writePin(34, 0);                       // LED OFF로 오류 표시
        ESTOP0;                                     // 디버깅용 정지
    }

    // 글로벌 인터럽트 활성화
    EINT;                                           // CPU 인터럽트 활성화

    // Watchdog 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_WD);  // Watchdog 클럭 활성화
    SysCtl_serviceWatchdog();                       // Watchdog 서비스 시작

    // 메인 루프: 상태 모니터링
    for(;;)
    {
        // 디버깅용: 상태 표시
        GPIO_writePin(34, (spiStatus == 1 && rxFlag == 1) ? 1 : 0); // 데이터 수신 시 LED ON
        DEVICE_DELAY_US(1000000);                   // 1초 대기
    }
}

설명:

  • 기능: SPI-A를 슬레이브 모드로 설정하여 8비트 데이터 수신.
  • 설정: 모드 0(CPOL=0, CPHA=0, 마스터 데이터시트 확인), 슬레이브 모드, 8비트 데이터, 수신 인터럽트 활성화.
  • GPIO: GPIO16(SIMO, 입력), GPIO17(SOMI), GPIO18(CLK, 입력), GPIO19(STE, 입력), GPIO34(LED).
  • 칩 셀렉트: GPIO19(STE)는 외부 마스터가 제어.
  • 출력: 데이터 수신 시 rxFlag 설정, LED ON.
  • 용도: 외부 마스터 장치(예: 다른 MCU)와 통신.

4.5. 예제 5: 다중 데이터 송수신

SPI-A를 사용하여 여러 데이터를 연속적으로 송수신합니다.

#include "driverlib.h"
#include "device.h"

// 디버깅용 상태 변수: SPI 모듈의 현재 상태를 추적
volatile uint32_t spiStatus = 0; // 0: 초기화 완료, 1: SPI 동작 중, 0xFFFF: 오류

// 송수신 데이터 배열
uint16_t txData[4] = {0x1111, 0x2222, 0x3333, 0x4444}; // 송신 데이터 배열 (16비트, 하위 8비트 사용)
uint16_t rxData[4] = {0};                               // 수신 데이터 저장 배열
volatile uint16_t rxFlag = 0;                           // 수신 완료 플래그 (모든 데이터 수신 시 설정)

// 칩 셀렉트 핀 정의
#define CS_PIN 19 // GPIO19를 칩 셀렉트로 사용 (STE 핀과 동일)

// GPIO 초기화 함수: SPI 통신 및 디버깅용 LED 핀 설정
void initGPIO(void)
{
    // SPI-A SIMO 핀 설정 (GPIO16)
    GPIO_setPinConfig(GPIO_16_SPIA_SIMO);       // GPIO16을 SPI-A SIMO(마스터 출력)로 설정
    GPIO_setDirectionMode(16, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(16, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A SOMI 핀 설정 (GPIO17)
    GPIO_setPinConfig(GPIO_17_SPIA_SOMI);       // GPIO17을 SPI-A SOMI(마스터 입력)로 설정
    GPIO_setDirectionMode(17, GPIO_DIR_MODE_IN); // 입력 모드로 설정
    GPIO_setPadConfig(17, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A CLK 핀 설정 (GPIO18)
    GPIO_setPinConfig(GPIO_18_SPIA_CLK);        // GPIO18을 SPI-A 클럭 핀으로 설정
    GPIO_setDirectionMode(18, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(18, GPIO_PULL_UP);        // 풀업 저항 활성화

    // SPI-A STE 핀 설정 (GPIO19)
    GPIO_setPinConfig(GPIO_19_SPIA_STE);        // GPIO19를 SPI-A STE(칩 셀렉트)로 설정
    GPIO_setDirectionMode(19, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(19, GPIO_PULL_UP);        // 풀업 저항 활성화
    GPIO_writePin(CS_PIN, 1);                   // CS 핀 초기 상태 HIGH (비활성화)

    // 디버깅용 LED 설정 (GPIO34)
    GPIO_setPinConfig(GPIO_34_GPIO34);          // GPIO34를 일반 GPIO로 설정
    GPIO_setDirectionMode(34, GPIO_DIR_MODE_OUT); // 출력 모드로 설정
    GPIO_setPadConfig(34, GPIO_PULL_UP);        // 풀업 저항 활성화
    GPIO_writePin(34, 0);                       // 초기 LED 상태 OFF
}

// SPI 인터럽트 서비스 루틴: 다중 데이터 수신 처리
__interrupt void spiAISR(void)
{
    static uint16_t index = 0;                  // 현재 수신 데이터의 인덱스

    // 데이터 수신
    rxData[index] = SPI_readDataNonBlocking(SPIA_BASE); // FIFO에서 수신 데이터 저장
    index++;                                           // 인덱스 증가

    if (index >= 4)                            // 4개 데이터 모두 수신 완료
    {
        rxFlag = 1;                            // 수신 플래그 설정
        index = 0;                             // 인덱스 초기화 (다음 전송 대비)
    }

    // 인터럽트 플래그 지우기
    SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RX_DATA); // 수신 인터럽트 플래그 클리어
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);        // PIE 그룹 6 인터럽트 ACK
}

// SPI-A 초기화 함수: SPI 모듈 설정 및 인터럽트 활성화
void initSPI(void)
{
    // SPI-A 클럭 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIA); // SPI-A 모듈에 클럭 공급

    // SPI 모듈 초기화
    SPI_disableModule(SPIA_BASE);                   // 설정 전 모듈 비활성화
    SPI_initModule(SPIA_BASE);                     // SPI-A 모듈 기본 초기화

    // 비트율 계산: 비트율 = LSPCLK / (BRP + 1)
    // 예: LSPCLK = 50MHz, 목표 비트율 = 1Mbps
    // BRP = (50MHz / 1Mbps) - 1 = 49
    uint32_t lspclk = DEVICE_LSPCLK_FREQ;           // 저속 주변 클럭 (50MHz 가정)
    uint32_t baudRate = 1000000;                    // 목표 비트율: 1Mbps
    uint16_t brp = (lspclk / baudRate) - 1;         // BRP 계산 (49)

    // SPI 설정
    SPI_setConfig(SPIA_BASE, lspclk, baudRate,      // 비트율 1Mbps
                  SPI_PROT_CLK0PHA0,                // SPI 모드 0 (CPOL=0, CPHA=0, 슬레이브 데이터시트 확인)
                  SPI_MODE_MASTER,                  // 마스터 모드
                  8);                               // 8비트 데이터 길이

    // FIFO 활성화
    SPI_enableFIFO(SPIA_BASE);                     // 송수신 FIFO 활성화

    // 인터럽트 활성화
    SPI_enableInterrupt(SPIA_BASE, SPI_INT_RX_DATA); // 수신 완료 인터럽트 활성화

    // SPI 모듈 활성화
    SPI_enableModule(SPIA_BASE);                   // SPI-A 모듈 동작 시작

    // 상태 업데이트
    spiStatus = 1;                                 // SPI 동작 중 상태로 설정
}

void main(void)
{
    // 시스템 초기화
    Device_init();                                  // PLL, Watchdog, 주변 장치 클럭 설정

    // GPIO 기본 초기화
    Device_initGPIO();                              // GPIO 모듈 초기화

    // SPI 관련 GPIO 설정
    initGPIO();                                     // SPI 핀 및 디버깅용 LED 설정

    // 인터럽트 모듈 초기화
    Interrupt_initModule();                         // 인터럽트 컨트롤러 초기화
    Interrupt_initVectorTable();                    // 인터럽트 벡터 테이블 초기화

    // SPI 인터럽트 ISR 등록
    Interrupt_register(INT_SPIA_RX, &spiAISR);      // 수신 인터럽트 서비스 루틴 등록

    // 시스템 클럭 검증
    uint32_t sysClockHz = SysCtl_getClock(DEVICE_OSCSRC_FREQ); // 시스템 클럭 주파수 확인
    if (sysClockHz != 200000000)                    // 클럭이 200MHz가 아닌 경우 오류 처리
    {
        spiStatus = 0xFFFF;                         // 오류 상태 설정
        GPIO_writePin(34, 0);                       // LED OFF로 오류 표시
        ESTOP0;                                     // 디버깅용 정지
    }

    // SPI-A 초기화
    initSPI();                                      // SPI-A 모듈 초기화 및 설정

    // 초기화 오류 확인
    if (spiStatus != 1)                             // 초기화 실패 시 오류 처리
    {
        spiStatus = 0xFFFF;                         // 오류 상태 설정
        GPIO_writePin(34, 0);                       // LED OFF로 오류 표시
        ESTOP0;                                     // 디버깅용 정지
    }

    // 글로벌 인터럽트 활성화
    EINT;                                           // CPU 인터럽트 활성화

    // Watchdog 활성화
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_WD);  // Watchdog 클럭 활성화
    SysCtl_serviceWatchdog();                       // Watchdog 서비스 시작

    // 메인 루프: 다중 데이터 송수신
    for(;;)
    {
        // 칩 셀렉트 활성화 (LOW)
        GPIO_writePin(CS_PIN, 0);                   // CS 핀을 LOW로 설정하여 슬레이브 선택

        // 연속 데이터 전송
        for (uint16_t i = 0; i < 4; i++)
        {
            SPI_writeDataNonBlocking(SPIA_BASE, txData[i]); // 8비트 데이터 전송 (FIFO에 저장)
            DEVICE_DELAY_US(100);                       // 전송 간 짧은 대기 (FIFO 처리 시간 확보)
        }

        // 칩 셀렉트 비활성화 (HIGH)
        GPIO_writePin(CS_PIN, 1);                   // CS 핀을 HIGH로 설정하여 슬레이브 해제

        // 디버깅용: 상태 표시
        GPIO_writePin(34, (spiStatus == 1 && rxFlag == 1) ? 1 : 0); // 데이터 수신 시 LED ON
        DEVICE_DELAY_US(1000000);                   // 1초 대기
    }
}

설명:

  • 기능: SPI-A로 다중 데이터(4개)를 연속적으로 송수신.
  • 설정: 비트율 1Mbps (BRP=49), 모드 0(CPOL=0, CPHA=0), 마스터 모드, 8비트 데이터, 수신 인터럽트 활성화.
  • GPIO: GPIO16(SIMO), GPIO17(SOMI), GPIO18(CLK), GPIO19(STE, CS), GPIO34(LED).
  • 칩 셀렉트: GPIO19(STE)를 수동으로 제어하여 슬레이브 선택/해제.
  • 출력: 4개 데이터 송수신, 수신 완료 시 LED ON.
  • 용도: 다중 데이터 전송이 필요한 애플리케이션(예: 센서 데이터 수집).

5. 추가 고려 사항

  • 비트율 계산: 비트율은 LSPCLK / (BRP + 1)로 계산. 예: 50MHz LSPCLK, 1Mbps → BRP=49. 코드에서 명시적으로 계산하여 설정.
  • SPI 모드: 클럭 폴러리티(CPOL)와 페이즈(CPHA)에 따라 4가지 모드(0~3) 선택. 예제에서는 모드 0 사용, 슬레이브 장치의 데이터시트 확인 필요.
  • 칩 셀렉트(CS): STE 핀(GPIO19)을 수동으로 제어하거나 별도의 GPIO로 관리 가능. 마스터 모드에서 CS 핀을 LOW로 설정하여 슬레이브 선택, HIGH로 설정하여 해제.
  • GPIO 설정: 고속 신호를 위해 풀업/풀다운 저항 조정 필요.
  • C2000Ware: 예제 코드는 C2000Ware의 DriverLib 기반. C:\ti\c2000에 설치.
  • 디버깅: 오실로스코프 또는 로직 분석기로 SPI 신호 확인 권장.

키워드: TMS320F28388D, SPI, DriverLib, C2000, Serial Peripheral Interface, Code Composer Studio, 마스터 모드, 슬레이브 모드, 인터럽트, 에러 처리, FIFO, 다중 데이터 송수신, 비트율 계산, 칩 셀렉트

반응형