基于TMS320F28335的SPI接口读取SD卡文件数据

基于TMS320F28335的SPI接口读取SD卡文件数据


一、硬件连接配置

TMS320F28335        SD卡模块
-------------------------
SPISTE (GPIO34) → CS  
SPISIMO (GPIO32) → SCLK  
SPICLKO (GPIO33) → MOSI  
SPISOMI (GPIO31) → MISO  
GND → GND  
3.3V → VDD

关键配置说明

  1. 使用SPI-A模块,配置为4线主模式
  2. SPI时钟初始频率设置为1MHz(初始化阶段)
  3. 数据格式:MSB优先,时钟极性CPOL=0,相位CPHA=0
  4. 启用硬件CRC校验(需根据SD卡版本选择)

二、SPI驱动初始化

#include "DSP28x_Project.h"

#define SPI_BASE_ADDR 0x00007000  // SPI-A基地址
#define SD_CS_ASSERT()  GpioDataRegs.GPACLEAR.bit.GPIO34 = 1
#define SD_CS_DEASSERT() GpioDataRegs.GPASET.bit.GPIO34 = 1

void SPI_Init() {
    // 1. 使能SPI时钟
    EALLOW;
    SysCtrlRegs.PCLKCR3.bit.SPIAENCLK = 1;
    EDIS;

    // 2. 配置SPI模式
    SpiaRegs.SPICCR.all = 0x0007;      // 16位字符长度,时钟停止时保持高电平
    SpiaRegs.SPICTL.all = 0x0006;      // 主模式,使能时钟,中断禁用
    SpiaRegs.SPIBRR = 0x000F;          // 分频系数=16 (100MHz/16=6.25MHz)
    SpiaRegs.SPICR2.bit.CLK_PHASE = 0; // CPOL=0, CPHA=0
    SpiaRegs.SPICR1.bit.SPI_INT_ENA = 0;

    // 3. 引脚配置
    EALLOW;
    GpioCtrlRegs.GPADIR.bit.GPIO34 = 1;  // CS设为输出
    GpioCtrlRegs.GPADIR.bit.GPIO32 = 1;  // SCLK设为输出
    GpioCtrlRegs.GPADIR.bit.GPIO33 = 1;  // MOSI设为输出
    GpioCtrlRegs.GPAINPUTEN.bit.GPIO31 = 0; // MISO设为输入
    EDIS;
}

三、SD卡初始化流程

#define CMD0  0x40  // GO_IDLE_STATE
#define CMD8  0x48  // SEND_IF_COND
#define ACMD41 0x60 // SEND_OP_COND (with CMD55 prefix)
#define CMD16 0x50  // SET_BLOCKLEN

Uint16 SD_Init() {
    Uint16 r1;
    
    // 1. 硬件复位
    SD_CS_ASSERT();
    SPI_WriteCmd(CMD0, 0, 0x95);  // 发送CMD0,CRC=0x95
    while(SpiaRegs.SPISTS.bit.RXFULL == 0); // 等待接收完成
    r1 = SpiaRegs.SPIRXBUF >> 8;  // 读取R1响应
    
    // 2. 发送ACMD41(带CMD55前缀)
    SD_CS_DEASSERT();
    DELAY_US(1000);  // 等待卡上电
    
    for(int i=0; i<1000; i++) {
        SD_CS_ASSERT();
        SPI_WriteCmd(CMD55, 0, 0x65);  // CMD55前缀
        r1 = SpiaRegs.SPIRXBUF >> 8;
        
        if(r1 == 0x01) {  // 支持应用命令
            SPI_WriteCmd(ACMD41, 0x40000000, 0xE5);  // HCS=1
            r1 = SpiaRegs.SPIRXBUF >> 8;
            if(r1 == 0x00) break;  // 初始化完成
        }
        SD_CS_DEASSERT();
        DELAY_MS(1);
    }
    
    // 3. 设置块大小为512字节
    SD_CS_ASSERT();
    SPI_WriteCmd(CMD16, 512, 0x15);  // CRC=0x15
    r1 = SpiaRegs.SPIRXBUF >> 8;
    
    SD_CS_DEASSERT();
    return (r1 == 0x00) ? 1 : 0;
}

四、文件系统解析与数据读取

#include "fatfs.h"  // 需集成FatFs文件系统库

FATFS fs;           // 文件系统对象
FIL fil;          // 文件对象
UINT bytesRead;     // 实际读取字节数

void Read_SD_File(char *filename) {
    FRESULT fr;
    
    // 1. 挂载文件系统
    fr = f_mount(&fs, "", 1);
    if(fr != FR_OK) {
        printf("文件系统挂载失败: 0x%02X\n", fr);
        return;
    }
    
    // 2. 打开文件
    fr = f_open(&fil, filename, FA_READ);
    if(fr != FR_OK) {
        printf("文件打开失败: 0x%02X\n", fr);
        f_mount(NULL, "", 0);
        return;
    }
    
    // 3. 读取数据
    char buffer[512];
    while(1) {
        fr = f_read(&fil, buffer, sizeof(buffer), &bytesRead);
        if(fr != FR_OK || bytesRead == 0) break;
        
        // 处理数据(示例:通过UART输出)
        UART_WriteBuffer(buffer, bytesRead);
    }
    
    // 4. 关闭文件并卸载
    f_close(&fil);
    f_mount(NULL, "", 0);
}

五、SPI数据传输实现

void SPI_WriteCmd(Uint16 cmd, Uint32 arg, Uint8 crc) {
    SD_CS_ASSERT();
    
    // 发送命令头
    SpiaRegs.SPITXBUF = 0x40 | (cmd & 0x3F);  // 起始位+命令索引
    while(SpiaRegs.SPISTS.bit.TXEMPTY == 0);  // 等待发送完成
    
    // 发送参数(4字节)
    SpiaRegs.SPITXBUF = (arg >> 24) & 0xFF;
    SpiaRegs.SPITXBUF = (arg >> 16) & 0xFF;
    SpiaRegs.SPITXBUF = (arg >> 8) & 0xFF;
    SpiaRegs.SPITXBUF = arg & 0xFF;
    
    // 发送CRC
    SpiaRegs.SPITXBUF = crc;
    while(SpiaRegs.SPISTS.bit.TXEMPTY == 0);
    
    // 等待响应(最大8次重试)
    for(int i=0; i<10; i++) {
        if(SpiaRegs.SPISTS.bit.RXFULL) {
            r1 = SpiaRegs.SPIRXBUF >> 8;
            if((r1 & 0x80) == 0) break;  // 响应有效
        }
    }
    
    SD_CS_DEASSERT();
}

参考代码 利用TMS320F28335的SPI口读取SD卡中的文件数据 www.youwenfan.com/contentcsr/56772.html

六、参考资料与工具

  1. 必备文档

    • TMS320F28335数据手册(SPRS667)
    • SD卡物理层规范(SD 3.01)
    • FatFs文件系统源码(FatFs_0.14c)
  2. 调试工具

    • 逻辑分析仪:Saleae Logic Pro 8
    • 协议分析仪:Total Phase Aardvark
    • 性能分析:CCS Profiler

专注于matlab/simulink,电子电路,编程