基于TMS320F28335与AD2S1210的SPI通信实现方案

一、硬件连接配置

TMS320F28335引脚 AD2S1210引脚 功能说明
GPIO54 (SPISIMO) SCLK 串行时钟(主出从入)
GPIO55 (SPISOMI) SDI 串行数据输入(主入从出)
GPIO56 (SPICLK) CS 片选信号(低电平有效)
GPIO57 (SPISTE) SAMPLE 采样控制信号
GPIO58 (SPISIMOA) A0/A1 模式选择引脚

关键连接说明

  1. SPISTE引脚需连接AD2S1210的SAMPLE引脚,用于控制数据采样时序

  2. CS引脚需外接上拉电阻(10kΩ)确保空闲状态为高电平

  3. 电源引脚需添加0.1μF去耦电容


二、SPI时序配置要点

  1. 时钟参数

    • 空闲状态:CPOL=0(时钟低电平)

    • 数据传输:CPHA=1(下降沿采样)

    • 波特率:≤25MHz(由LSPCLK=37.5MHz决定)

  2. 关键时序约束

    // 初始化SPI配置(基于DSP28335寄存器)
    SpiaRegs.SPICCR.all = 0x0007;    // 16位数据,无相位延迟
    SpiaRegs.SPICTL.all = 0x0006;    // 主模式,上升沿发送,下降沿接收
    SpiaRegs.SPIBRR = 0x0003;        // 波特率=37.5MHz/(3+1)=9.375MHz
    
  3. 典型读时序

    CS↓ → SCLK↑ → 传输控制字 → SCLK↓ → ... → SCLK↑ → 数据读取
    

三、核心代码实现

1. SPI初始化

void Init_SPI(void) {
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;  // 使能SPI时钟
    InitSpiaGpio();                         // 配置GPIO54-57为SPI功能

    SpiaRegs.SPICCR.bit.SPISWRESET = 0;     // SPI复位
    SpiaRegs.SPICCR.all = 0x0007;           // 16位数据,无相位延迟
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;   // 主模式
    SpiaRegs.SPICTL.bit.TALK = 1;           // 使能发送
    SpiaRegs.SPIBRR = 0x0003;               // 设置波特率
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;     // 释放复位
    EDIS;
}

2. AD2S1210读写函数

#define AD2S1210_CS_CLR()  GpioDataRegs.GPBCLEAR.bit.GPIO56 = 1
#define AD2S1210_CS_SET()  GpioDataRegs.GPBCLEAR.bit.GPIO56 = 0

// 写入控制字
void AD2S1210_WriteReg(Uint16 addr, Uint16 data) {
    AD2S1210_CS_CLR();
    SpiaRegs.SPITXBUF = (addr << 8) | 0x80;  // 控制字高位为1表示写操作
    while(SpiaRegs.SPIFFRX.bit.RXFFST < 2);  // 等待传输完成
    SpiaRegs.SPITXBUF = data;
    while(SpiaRegs.SPIFFRX.bit.RXFFST < 1);  // 等待ACK
    AD2S1210_CS_SET();
}

// 读取位置数据
Uint16 AD2S1210_ReadPos() {
    AD2S1210_CS_CLR();
    SpiaRegs.SPITXBUF = 0x80;  // 读位置寄存器
    while(SpiaRegs.SPIFFRX.bit.RXFFST < 2);  // 丢弃旧数据
    SpiaRegs.SPITXBUF = 0x00;  // 发送空数据触发读取
    while(SpiaRegs.SPIFFRX.bit.RXFFST < 2);  // 等待数据
    Uint16 pos = SpiaRegs.SPIRXBUF >> 4;     // 右对齐处理
    AD2S1210_CS_SET();
    return pos;
}

四、典型应用流程

  1. 硬件初始化

    InitSysCtrl();      // 系统时钟配置
    InitPieCtrl();      // 中断控制器初始化
    Init_SPI();         // SPI模块初始化
    AD2S1210_Reset();   // 执行硬件复位
    
  2. AD2S1210初始化

    AD2S1210_WriteReg(0x92, 0x01);  // 设置EXC频率为10kHz
    AD2S1210_WriteReg(0x8C, 0x80);  // 启用增量式编码器仿真
    
  3. 数据采集循环

    while(1) {
        Uint16 angle = AD2S1210_ReadPos();  // 读取位置值
        float theta = (angle / 4096.0f) * 360.0f;  // 转换为角度
        // 执行电机控制算法...
    }
    

参考代码 TMS320F28335串行读取AD2S1210数据 www.youwenfan.com/contentcnr/69291.html

五、常见问题解决

问题现象 可能原因 解决方案
数据最高位丢失 SPI时钟相位错误 检查CPHA设置(应为1)
通信超时 片选信号未正确控制 确认CS引脚电平变化时序
数据波动大 激励信号幅值异常 检查EXC+/-差分信号峰峰值
偶发通信失败 SPI缓冲区溢出 启用SPI FIFO模式

六、优化建议

  1. 时钟优化

    // 提高SPI时钟频率(需硬件支持)
    SpiaRegs.SPIBRR = 0x0000;  // 波特率=37.5MHz/(0+1)=37.5MHz
    
  2. 滤波处理

    // 添加移动平均滤波
    #define FILTER_SIZE 5
    static Uint16 angle_buf[FILTER_SIZE] = {0};
    static Uint8 index = 0;
    
    angle_buf[index++] = AD2S1210_ReadPos();
    if(index >= FILTER_SIZE) index = 0;
    Uint16 filtered = 0;
    for(Uint8 i=0; i<FILTER_SIZE; i++) filtered += angle_buf[i];
    filtered /= FILTER_SIZE;
    
  3. 中断模式

    // 配置SPI接收中断
    SpiaRegs.SPIFFRX.bit.RXFFIL = 1;  // 设置中断深度
    SpiaRegs.SPIFFRX.bit.RXFFIENA = 1; // 使能接收中断
    PieVectTable.SPIRXINTA = &SpiRxIsr; // 注册中断服务函数
    

七、调试工具建议

  1. 逻辑分析仪配置

    • 触发条件:CS下降沿

    • 捕获长度:≥24个时钟周期

    • 关键信号:CS、SCLK、SDO

  2. 示波器测量点

    CH1: SCLK (500ns/div)
    CH2: SDI (500ns/div)
    CH3: CS (1μs/div)
    

八、参考资料

  1. AD2S1210数据手册(ADI官网)

  2. TMS320F28335数据手册(TI官网)

  3. 《电机控制中的旋变解码技术》(李连志著)

posted @ 2026-03-06 10:30  小前端攻城狮  阅读(2)  评论(0)    收藏  举报