一、系统概述

AD2S1210是一款高精度的旋变数字转换器(RDC),用于将旋转变压器输出的模拟信号转换为数字角度和速度值。本程序基于TI DSP F28335实现与AD2S1210的串行通信(SPI接口),完成角度和速度的读取与解析。

二、硬件连接

F28335          AD2S1210
------------------------
GPIO19 (CS)  ->  CS
GPIO18 (SCLK)->  SCLK
GPIO17 (SDIN)->  SDIN
GPIO16 (SDOUT)-> SDOUT
3.3V         ->  VDD
GND          ->  GND

三、程序架构

主程序

系统初始化

GPIO配置

SPI配置

中断配置

AD2S1210初始化

设置工作模式

配置参数

主循环

读取角度/速度

数据处理

故障检测

四、核心代码实现

1. 头文件与宏定义

#include "F28335_device.h"
#include "F28335_system.h"

// AD2S1210寄存器地址
#define REG_POSITION_MSB  0x80
#define REG_POSITION_LSB  0x81
#define REG_SPEED_MSB     0x82
#define REG_SPEED_LSB     0x83
#define REG_LOS_THR       0x88
#define REG_DOS_OVR_THR   0x89
#define REG_DOS_MIS_THR   0x8A
#define REG_DOS_RST_MAX   0x8B
#define REG_DOS_CFG       0x8C
#define REG_CONFIG        0x91
#define REG_FAULT         0x92

// 控制命令
#define WRITE_CMD         0x00
#define READ_CMD          0x80

// GPIO定义
#define AD2S1210_CS       GpioDataRegs.GPBDAT.bit.GPIO48
#define SPI_CLK_FREQ      10000000  // 10MHz

2. SPI初始化

void InitSPI(void) {
    // 1. 使能SPI时钟
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;
    EDIS;
    
    // 2. 配置GPIO为SPI功能
    EALLOW;
    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1;  // SPISIMOA
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1;  // SPISOMIA
    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1;  // SPICLKA
    GpioCtrlRegs.GPBMUX2.bit.GPIO48 = 0;  // GPIO48作为CS
    GpioCtrlRegs.GPBDIR.bit.GPIO48 = 1;   // 输出模式
    EDIS;
    
    // 3. 复位SPI模块
    SpiaRegs.SPICCR.all = 0x0007;   // 复位,8位字符,禁用自测
    SpiaRegs.SPICTL.all = 0x0006;   // 主模式,禁止超时,启用发送
    SpiaRegs.SPIBRR = 0x001F;       // 波特率设置 (SYSCLKOUT/(SPIBRR+1))
    SpiaRegs.SPICCR.all = 0x0087;   // 退出复位,启用SPI
    
    // 4. 配置SPI FIFO
    SpiaRegs.SPIFFTX.all = 0xE040;  // 使能FIFO,清除发送寄存器
    SpiaRegs.SPIFFRX.all = 0x204F;  // 接收FIFO中断级别=15
    SpiaRegs.SPIFFCT.all = 0x0000;  // 无延迟
}

3. AD2S1210初始化

void AD2S1210_Init(void) {
    // 1. 设置工作模式
    AD2S1210_WriteReg(REG_CONFIG, 0x0C);  // 16位分辨率,外部时钟
    
    // 2. 配置故障阈值
    AD2S1210_WriteReg(REG_LOS_THR, 0x0F);  // 失锁阈值
    AD2S1210_WriteReg(REG_DOS_OVR_THR, 0x07);  // 过速阈值
    AD2S1210_WriteReg(REG_DOS_MIS_THR, 0x07);  // 欠速阈值
    
    // 3. 使能故障检测
    AD2S1210_WriteReg(REG_DOS_CFG, 0x0F);  // 使能所有故障检测
    
    // 4. 清除故障标志
    AD2S1210_WriteReg(REG_DOS_RST_MAX, 0x00);
    AD2S1210_WriteReg(REG_FAULT, 0x00);
}

4. SPI数据传输函数

Uint16 SPI_Transfer(Uint16 data) {
    // 等待发送缓冲区为空
    while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG);
    
    // 发送数据
    SpiaRegs.SPITXBUF = data;
    
    // 等待接收完成
    while(!SpiaRegs.SPISTS.bit.INT_FLAG);
    
    // 读取接收到的数据
    Uint16 rx_data = SpiaRegs.SPIRXBUF;
    
    return rx_data;
}

5. AD2S1210寄存器读写

void AD2S1210_WriteReg(Uint8 reg_addr, Uint8 data) {
    // 拉低CS
    AD2S1210_CS = 0;
    
    // 发送写命令和寄存器地址
    SPI_Transfer(WRITE_CMD | reg_addr);
    
    // 发送数据
    SPI_Transfer(data);
    
    // 拉高CS
    AD2S1210_CS = 1;
}

Uint8 AD2S1210_ReadReg(Uint8 reg_addr) {
    Uint8 result;
    
    // 拉低CS
    AD2S1210_CS = 0;
    
    // 发送读命令和寄存器地址
    SPI_Transfer(READ_CMD | reg_addr);
    
    // 读取数据
    result = SPI_Transfer(0xFF);
    
    // 拉高CS
    AD2S1210_CS = 1;
    
    return result;
}

6. 角度和速度读取

typedef struct {
    float angle;     // 角度值 (0-360度)
    float speed;     // 速度值 (RPM)
    Uint16 raw_angle; // 原始角度值
    Int16 raw_speed;  // 原始速度值
} AD2S1210_Data;

AD2S1210_Data AD2S1210_ReadData(void) {
    AD2S1210_Data data;
    
    // 读取角度高8位
    Uint8 angle_msb = AD2S1210_ReadReg(REG_POSITION_MSB);
    
    // 读取角度低8位
    Uint8 angle_lsb = AD2S1210_ReadReg(REG_POSITION_LSB);
    
    // 组合为16位角度值
    data.raw_angle = (angle_msb << 8) | angle_lsb;
    
    // 转换为角度 (0-360度)
    data.angle = (data.raw_angle / 65536.0) * 360.0;
    
    // 读取速度高8位
    Uint8 speed_msb = AD2S1210_ReadReg(REG_SPEED_MSB);
    
    // 读取速度低8位
    Uint8 speed_lsb = AD2S1210_ReadReg(REG_SPEED_LSB);
    
    // 组合为16位有符号速度值
    data.raw_speed = (Int16)((speed_msb << 8) | speed_lsb);
    
    // 转换为RPM (根据数据手册公式)
    // 假设激励频率为10kHz,分辨率16位
    data.speed = (data.raw_speed * 60.0) / 65536.0;
    
    return data;
}

7. 故障检测

void AD2S1210_CheckFaults(void) {
    Uint8 fault_reg = AD2S1210_ReadReg(REG_FAULT);
    
    if(fault_reg & 0x01) {
        // 失锁故障 (LOS)
        Fault_Handler(FAULT_LOS);
    }
    if(fault_reg & 0x02) {
        // 过速故障 (DOS OVR)
        Fault_Handler(FAULT_DOS_OVR);
    }
    if(fault_reg & 0x04) {
        // 欠速故障 (DOS MIS)
        Fault_Handler(FAULT_DOS_MIS);
    }
    if(fault_reg & 0x08) {
        // 信号幅度不足 (DOS SIN)
        Fault_Handler(FAULT_DOS_SIN);
    }
    if(fault_reg & 0x10) {
        // 信号幅度不足 (DOS COS)
        Fault_Handler(FAULT_DOS_COS);
    }
    if(fault_reg & 0x20) {
        // 配置错误 (CONFIG ERROR)
        Fault_Handler(FAULT_CONFIG_ERROR);
    }
}

8. 主程序

void main(void) {
    // 系统初始化
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();
    
    // 外设初始化
    InitSPI();
    InitGpio();
    
    // AD2S1210初始化
    AD2S1210_Init();
    
    // 主循环
    while(1) {
        // 读取角度和速度
        AD2S1210_Data sensor_data = AD2S1210_ReadData();
        
        // 处理数据 (例如更新显示或控制算法)
        ProcessSensorData(&sensor_data);
        
        // 检测故障
        AD2S1210_CheckFaults();
        
        // 延时
        DELAY_US(1000);  // 1ms
    }
}

五、关键参数配置

1. SPI时序配置

参数说明
时钟极性(CPOL)0空闲时低电平
时钟相位(CPHA)0数据在第一个边沿采样
波特率10 MHz根据系统时钟计算
数据位8位每次传输8位数据
传输模式主模式F28335作为主设备

2. AD2S1210工作模式

参数说明
分辨率16位角度和速度均为16位
激励频率10 kHz旋变激励信号频率
故障检测使能所有故障检测使能
输出模式串行使用SPI接口输出数据

六、故障处理机制

typedef enum {
    FAULT_NONE = 0,
    FAULT_LOS,        // 失锁故障
    FAULT_DOS_OVR,    // 过速故障
    FAULT_DOS_MIS,    // 欠速故障
    FAULT_DOS_SIN,    // 正弦信号幅度不足
    FAULT_DOS_COS,    // 余弦信号幅度不足
    FAULT_CONFIG_ERROR // 配置错误
} FaultType;

void Fault_Handler(FaultType fault) {
    switch(fault) {
        case FAULT_LOS:
            // 处理失锁故障
            // 1. 检查旋变连接
            // 2. 增加激励信号幅度
            // 3. 记录故障日志
            break;
            
        case FAULT_DOS_OVR:
            // 处理过速故障
            // 1. 检查机械负载
            // 2. 降低系统速度
            break;
            
        // 其他故障处理...
            
        default:
            // 未知故障
            break;
    }
    
    // 更新故障状态寄存器
    UpdateFaultStatus(fault);
}

参考代码 基于DSP F28335的AD2S1210的串行通信程序 www.youwenfan.com/contentcsv/51768.html

七、优化措施

1. 数据读取优化

// 批量读取角度和速度
void AD2S1210_ReadAllData(AD2S1210_Data* data) {
    // 拉低CS
    AD2S1210_CS = 0;
    
    // 发送读角度MSB命令
    SPI_Transfer(READ_CMD | REG_POSITION_MSB);
    data->raw_angle = SPI_Transfer(0xFF) << 8;
    
    // 发送读角度LSB命令
    SPI_Transfer(READ_CMD | REG_POSITION_LSB);
    data->raw_angle |= SPI_Transfer(0xFF);
    
    // 发送读速度MSB命令
    SPI_Transfer(READ_CMD | REG_SPEED_MSB);
    data->raw_speed = SPI_Transfer(0xFF) << 8;
    
    // 发送读速度LSB命令
    SPI_Transfer(READ_CMD | REG_SPEED_LSB);
    data->raw_speed |= SPI_Transfer(0xFF);
    
    // 拉高CS
    AD2S1210_CS = 1;
    
    // 转换为实际值
    data->angle = (data->raw_angle / 65536.0) * 360.0;
    data->speed = (data->raw_speed * 60.0) / 65536.0;
}

2. DMA传输实现

// 使用DMA进行SPI数据传输
void AD2S1210_DMA_Read(Uint8* tx_buf, Uint8* rx_buf, Uint16 len) {
    // 配置DMA通道
    DmaRegs.CH1.MODE.bit.CH1CONTINUOUS = 0;  // 单次传输
    DmaRegs.CH1.MODE.bit.CH1TRANSFERMODE = 1; // 16位传输
    DmaRegs.CH1.BURST_SIZE.all = 0;          // 单字突发
    DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32)tx_buf;
    DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32)tx_buf;
    DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32)&SpiaRegs.SPITXBUF;
    DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32)&SpiaRegs.SPITXBUF;
    DmaRegs.CH1.SRC_WRAP_SIZE = 0xFFFF;      // 无环绕
    DmaRegs.CH1.DST_WRAP_SIZE = 0xFFFF;
    DmaRegs.CH1.TRANSFER_SIZE = len;         // 传输长度
    
    // 启动DMA传输
    DmaRegs.CH1.CONTROL.bit.RUN = 1;
    
    // 等待传输完成
    while(DmaRegs.CH1.CONTROL.bit.OVRFLG == 0);
}

八、调试与测试方法

1. 测试点设置

测试点信号预期结果
TP1SCLK10MHz方波,占空比50%
TP2SDIN数据波形符合SPI协议
TP3SDOUT数据波形符合SPI协议
TP4CS低电平有效,脉冲宽度>100ns
TP5ANGLE_OUT0-5V模拟信号,随角度变化
TP6SPEED_OUT0-5V模拟信号,随速度变化

2. 测试用例

void Test_AD2S1210(void) {
    // 1. 寄存器读写测试
    AD2S1210_WriteReg(REG_CONFIG, 0x0C);
    Uint8 config = AD2S1210_ReadReg(REG_CONFIG);
    if(config != 0x0C) {
        // 错误处理
    }
    
    // 2. 角度读取测试
    AD2S1210_Data data = AD2S1210_ReadData();
    if(data.raw_angle < 0 || data.raw_angle > 65535) {
        // 错误处理
    }
    
    // 3. 速度读取测试
    if(data.raw_speed < -32768 || data.raw_speed > 32767) {
        // 错误处理
    }
    
    // 4. 故障注入测试
    // 断开旋变信号,检查故障标志
    // 超速旋转,检查过速故障
}

九、常见问题解决方案

问题现象可能原因解决方案
无数据输出电源问题检查VDD电压(3.3V±5%)
接线错误检查SPI接线是否正确
CS信号未拉低确认CS控制逻辑
数据不稳定时钟抖动增加时钟缓冲器,优化PCB布局
电源噪声增加去耦电容(0.1μF+10μF)
接地不良检查接地回路
角度跳变旋变安装松动检查机械安装
激励信号幅度不足调整激励信号幅度
速度读数异常滤波器配置不当调整AD2S1210的滤波器设置
机械振动增加机械阻尼
频繁报告故障阈值设置不合理根据实际工况调整故障阈值

十、总结

本程序实现了基于DSP F28335与AD2S1210旋变数字转换器的串行通信,主要功能包括:

  1. SPI接口的初始化与配置

  2. AD2S1210寄存器读写操作

  3. 角度和速度数据的读取与转换

  4. 故障检测与处理机制

  5. 性能优化措施(批量读取、DMA传输)

Logo

免费领 150 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐