STM32 + ADS1256 24位高精度ADC驱动测试程序

一、ADS1256 关键特性

参数 规格
分辨率 24位(有效位约19-21位)
采样率 最高 30kSPS(可编程:2.5~30k)
输入通道 8路单端 / 4路差分
输入范围 ±5V(参考电压5V时)
增益 1~64倍可编程
接口 SPI(最大 4MHz)
功耗 38mW(正常模式)

二、硬件连接(STM32F103C8T6 + ADS1256)

2.1 引脚连接表

复制代码
ADS1256         STM32F103C8T6
─────────────────────────────
VDD     →       5V
DGND    →       GND
VREF+   →       5V(精密参考源)
VREF-   →       GND
AVDD    →       5V
AGND    →       GND
CS      →       PA4(SPI1_NSS)
SCLK    →       PA5(SPI1_SCK)
DIN     →       PA7(SPI1_MOSI)
DOUT    →       PA6(SPI1_MISO)
DRDY    →       PB0(外部中断)
RESET   →       PB1(GPIO输出)
SYNC    →       PB2(GPIO输出)

2.2 参考电压电路

复制代码
推荐:REF5025(2.5V精密基准)或 TL431
VREF = 5.0V(ADS1256满量程 ±5V)

三、驱动代码

3.1 ADS1256 头文件 (ads1256.h)

c 复制代码
/**
  * @file ads1256.h
  * @brief ADS1256 24位ADC驱动头文件
  */
#ifndef __ADS1256_H
#define __ADS1256_H

#include "stm32f10x.h"
#include <stdbool.h>

/* ADS1256 命令定义 */
#define ADS1256_CMD_WAKEUP    0x00    // 退出待机模式
#define ADS1256_CMD_RDATA     0x01    // 读取数据
#define ADS1256_CMD_RDATAC    0x03    // 连续读取数据
#define ADS1256_CMD_SDATAC    0x0F    // 停止连续读取
#define ADS1256_CMD_RREG      0x10    // 读寄存器(0x10 + reg)
#define ADS1256_CMD_WREG      0x50    // 写寄存器(0x50 + reg)
#define ADS1256_CMD_SELFCAL   0xF0    // 自校准
#define ADS1256_CMD_SELFOCAL  0xF1    // 系统偏移校准
#define ADS1256_CMD_SELFGCAL  0xF2    // 系统增益校准
#define ADS1256_CMD_SYSOCAL   0xF3    // 系统偏移校准
#define ADS1256_CMD_SYSGCAL   0xF4    // 系统增益校准
#define ADS1256_CMD_SYNC      0xFC    // 同步
#define ADS1256_CMD_STANDBY   0xFD    // 待机
#define ADS1256_CMD_RESET     0xFE    // 复位

/* 寄存器地址 */
#define ADS1256_REG_STATUS    0x00    // 状态寄存器
#define ADS1256_REG_MUX       0x01    // 输入多路复用器
#define ADS1256_REG_ADCON     0x02    // ADC控制寄存器
#define ADS1256_REG_DRATE     0x03    // 数据速率寄存器
#define ADS1256_REG_IO        0x04    // GPIO控制寄存器
#define ADS1256_REG_OFC0      0x05    // 偏移校准 0
#define ADS1256_REG_OFC1      0x06    // 偏移校准 1
#define ADS1256_REG_OFC2      0x07    // 偏移校准 2
#define ADS1256_REG_FSC0      0x08    // 满量程校准 0
#define ADS1256_REG_FSC1      0x09    // 满量程校准 1
#define ADS1256_REG_FSC2      0x0A    // 满量程校准 2

/* 输入通道选择 */
typedef enum {
    ADS1256_AIN0 = 0x00,
    ADS1256_AIN1 = 0x01,
    ADS1256_AIN2 = 0x02,
    ADS1256_AIN3 = 0x03,
    ADS1256_AIN4 = 0x04,
    ADS1256_AIN5 = 0x05,
    ADS1256_AIN6 = 0x06,
    ADS1256_AIN7 = 0x07,
    ADS1256_AINCOM = 0x08
} ADS1256_Channel;

/* 增益设置 */
typedef enum {
    ADS1256_GAIN_1 = 0x00,
    ADS1256_GAIN_2 = 0x01,
    ADS1256_GAIN_4 = 0x02,
    ADS1256_GAIN_8 = 0x03,
    ADS1256_GAIN_16 = 0x04,
    ADS1256_GAIN_32 = 0x05,
    ADS1256_GAIN_64 = 0x06
} ADS1256_Gain;

/* 数据速率 */
typedef enum {
    ADS1256_RATE_30000 = 0xF0,   // 30k SPS
    ADS1256_RATE_15000 = 0xE0,   // 15k SPS
    ADS1256_RATE_7500  = 0xD0,   // 7.5k SPS
    ADS1256_RATE_3750  = 0xC0,   // 3.75k SPS
    ADS1256_RATE_2000  = 0xB0,   // 2k SPS
    ADS1256_RATE_1000  = 0xA1,   // 1k SPS
    ADS1256_RATE_500   = 0x92,   // 500 SPS
    ADS1256_RATE_100   = 0x82,   // 100 SPS
    ADS1256_RATE_60    = 0x72,   // 60 SPS
    ADS1256_RATE_50    = 0x63,   // 50 SPS
    ADS1256_RATE_30    = 0x53,   // 30 SPS
    ADS1256_RATE_25    = 0x43,   // 25 SPS
    ADS1256_RATE_15    = 0x33,   // 15 SPS
    ADS1256_RATE_10    = 0x23,   // 10 SPS
    ADS1256_RATE_5     = 0x13,   // 5 SPS
    ADS1256_RATE_2_5   = 0x03    // 2.5 SPS
} ADS1256_DataRate;

/* 工作状态 */
typedef enum {
    ADS1256_OK = 0,
    ADS1256_ERROR,
    ADS1256_TIMEOUT,
    ADS1256_CALIBRATION_FAILED
} ADS1256_Status;

/* 设备句柄 */
typedef struct {
    SPI_TypeDef* spi;
    GPIO_TypeDef* cs_port;
    uint16_t cs_pin;
    GPIO_TypeDef* drdy_port;
    uint16_t drdy_pin;
    GPIO_TypeDef* reset_port;
    uint16_t reset_pin;
    GPIO_TypeDef* sync_port;
    uint16_t sync_pin;
    
    ADS1256_Gain gain;
    ADS1256_DataRate data_rate;
    bool continuous_mode;
    uint8_t buffer[3];
    float voltage[8];            // 8通道电压值
    int32_t raw_data[8];         // 原始数据
    uint32_t sample_count;
    uint32_t error_count;
} ADS1256_Handle;

/* 函数声明 */
void ADS1256_Init(ADS1256_Handle* handle);
void ADS1256_Reset(ADS1256_Handle* handle);
void ADS1256_WaitDRDY(ADS1256_Handle* handle, uint32_t timeout_ms);
void ADS1256_WriteReg(ADS1256_Handle* handle, uint8_t reg, uint8_t value);
uint8_t ADS1256_ReadReg(ADS1256_Handle* handle, uint8_t reg);
void ADS1256_WriteCmd(ADS1256_Handle* handle, uint8_t cmd);
void ADS1256_SetChannel(ADS1256_Handle* handle, ADS1256_Channel positive, ADS1256_Channel negative);
void ADS1256_SetGain(ADS1256_Handle* handle, ADS1256_Gain gain);
void ADS1256_SetDataRate(ADS1256_Handle* handle, ADS1256_DataRate rate);
int32_t ADS1256_ReadData(ADS1256_Handle* handle);
float ADS1256_ReadVoltage(ADS1256_Handle* handle, ADS1256_Channel channel);
void ADS1256_StartContinuous(ADS1256_Handle* handle);
void ADS1256_StopContinuous(ADS1256_Handle* handle);
void ADS1256_SelfCalibrate(ADS1256_Handle* handle);
void ADS1256_SystemCalibrate(ADS1256_Handle* handle);
void ADS1256_ScanChannels(ADS1256_Handle* handle);
float ADS1256_GetVoltage(ADS1256_Handle* handle, uint8_t channel);
void ADS1256_Test(ADS1256_Handle* handle);

#endif /* __ADS1256_H */

3.2 ADS1256 驱动实现 (ads1256.c)

c 复制代码
/**
  * @file ads1256.c
  * @brief ADS1256 24位ADC驱动实现
  */
#include "ads1256.h"
#include "delay.h"
#include <math.h>

/* 私有函数 */
static void ADS1256_CS_Low(ADS1256_Handle* handle);
static void ADS1256_CS_High(ADS1256_Handle* handle);
static uint8_t ADS1256_SPI_Transfer(ADS1256_Handle* handle, uint8_t data);
static void ADS1256_DelayUs(uint32_t us);

/* 初始化ADS1256 */
void ADS1256_Init(ADS1256_Handle* handle)
{
    /* 1. 硬件复位 */
    ADS1256_Reset(handle);
    Delay_Ms(100);
    
    /* 2. 等待DRDY变低 */
    ADS1256_WaitDRDY(handle, 1000);
    
    /* 3. 停止连续读取模式 */
    ADS1256_WriteCmd(handle, ADS1256_CMD_SDATAC);
    Delay_Ms(10);
    
    /* 4. 配置状态寄存器 */
    // 禁用缓冲器,禁用自动校准,数据顺序MSB
    ADS1256_WriteReg(handle, ADS1256_REG_STATUS, 0x00);
    
    /* 5. 配置输入多路复用器(默认AIN0-AINCOM) */
    ADS1256_WriteReg(handle, ADS1256_REG_MUX, 
                    (ADS1256_AIN0 << 4) | ADS1256_AINCOM);
    
    /* 6. 配置ADC控制寄存器 */
    // 时钟输出禁用,传感器检测电流禁用,增益设置
    uint8_t adcon = (handle->gain << 0);  // 增益位 [2:0]
    ADS1256_WriteReg(handle, ADS1256_REG_ADCON, adcon);
    
    /* 7. 配置数据速率 */
    ADS1256_WriteReg(handle, ADS1256_REG_DRATE, handle->data_rate);
    
    /* 8. 自校准 */
    ADS1256_SelfCalibrate(handle);
    
    /* 9. 初始化电压数组 */
    for (int i = 0; i < 8; i++) {
        handle->voltage[i] = 0.0f;
        handle->raw_data[i] = 0;
    }
    handle->sample_count = 0;
    handle->error_count = 0;
    
    printf("ADS1256 Initialized: Gain=%d, Rate=0x%02X\r\n", 
           handle->gain, handle->data_rate);
}

/* 硬件复位 */
void ADS1256_Reset(ADS1256_Handle* handle)
{
    GPIO_ResetBits(handle->reset_port, handle->reset_pin);
    Delay_Ms(10);
    GPIO_SetBits(handle->reset_port, handle->reset_pin);
    Delay_Ms(10);
}

/* 等待DRDY信号变低 */
void ADS1256_WaitDRDY(ADS1256_Handle* handle, uint32_t timeout_ms)
{
    uint32_t start = HAL_GetTick();
    
    while (GPIO_ReadInputDataBit(handle->drdy_port, handle->drdy_pin) == SET) {
        if ((HAL_GetTick() - start) > timeout_ms) {
            handle->error_count++;
            printf("ADS1256 DRDY Timeout!\r\n");
            return;
        }
    }
}

/* 写寄存器 */
void ADS1256_WriteReg(ADS1256_Handle* handle, uint8_t reg, uint8_t value)
{
    ADS1256_CS_Low(handle);
    
    // 发送写寄存器命令(0x50 + reg)
    ADS1256_SPI_Transfer(handle, ADS1256_CMD_WREG | reg);
    // 发送写入字节数(1-1=0)
    ADS1256_SPI_Transfer(handle, 0x00);
    // 写入数据
    ADS1256_SPI_Transfer(handle, value);
    
    ADS1256_CS_High(handle);
    Delay_Ms(1);
}

/* 读寄存器 */
uint8_t ADS1256_ReadReg(ADS1256_Handle* handle, uint8_t reg)
{
    uint8_t value;
    
    ADS1256_CS_Low(handle);
    
    // 发送读寄存器命令(0x10 + reg)
    ADS1256_SPI_Transfer(handle, ADS1256_CMD_RREG | reg);
    // 发送读取字节数(1-1=0)
    ADS1256_SPI_Transfer(handle, 0x00);
    // 读取数据
    value = ADS1256_SPI_Transfer(handle, 0x00);
    
    ADS1256_CS_High(handle);
    Delay_Ms(1);
    
    return value;
}

/* 发送命令 */
void ADS1256_WriteCmd(ADS1256_Handle* handle, uint8_t cmd)
{
    ADS1256_CS_Low(handle);
    ADS1256_SPI_Transfer(handle, cmd);
    ADS1256_CS_High(handle);
    Delay_Ms(1);
}

/* 设置输入通道 */
void ADS1256_SetChannel(ADS1256_Handle* handle, ADS1256_Channel positive, ADS1256_Channel negative)
{
    uint8_t mux = (positive << 4) | negative;
    ADS1256_WriteReg(handle, ADS1256_REG_MUX, mux);
    Delay_Ms(1);
}

/* 设置增益 */
void ADS1256_SetGain(ADS1256_Handle* handle, ADS1256_Gain gain)
{
    uint8_t adcon = ADS1256_ReadReg(handle, ADS1256_REG_ADCON);
    adcon = (adcon & 0xF8) | (gain & 0x07);  // 保留高5位,修改低3位
    ADS1256_WriteReg(handle, ADS1256_REG_ADCON, adcon);
    handle->gain = gain;
}

/* 设置数据速率 */
void ADS1256_SetDataRate(ADS1256_Handle* handle, ADS1256_DataRate rate)
{
    ADS1256_WriteReg(handle, ADS1256_REG_DRATE, rate);
    handle->data_rate = rate;
}

/* 读取24位数据 */
int32_t ADS1256_ReadData(ADS1256_Handle* handle)
{
    int32_t value = 0;
    
    ADS1256_CS_Low(handle);
    
    // 发送读取数据命令
    ADS1256_SPI_Transfer(handle, ADS1256_CMD_RDATA);
    Delay_Ms(1);  // t6等待时间
    
    // 读取24位数据(MSB first)
    value = ADS1256_SPI_Transfer(handle, 0x00);
    value <<= 8;
    value |= ADS1256_SPI_Transfer(handle, 0x00);
    value <<= 8;
    value |= ADS1256_SPI_Transfer(handle, 0x00);
    
    ADS1256_CS_High(handle);
    
    // 符号扩展(24位补码转32位)
    if (value & 0x800000) {
        value |= 0xFF000000;
    }
    
    return value;
}

/* 读取指定通道电压 */
float ADS1256_ReadVoltage(ADS1256_Handle* handle, ADS1256_Channel channel)
{
    int32_t raw;
    float voltage;
    
    // 设置通道
    ADS1256_SetChannel(handle, channel, ADS1256_AINCOM);
    
    // 发送同步命令
    ADS1256_WriteCmd(handle, ADS1256_CMD_SYNC);
    ADS1256_WriteCmd(handle, ADS1256_CMD_WAKEUP);
    
    // 等待转换完成
    ADS1256_WaitDRDY(handle, 100);
    
    // 读取数据
    raw = ADS1256_ReadData(handle);
    
    // 转换为电压值
    // 计算公式:V = (Raw / 2^23) * VREF / Gain
    float vref = 5.0f;  // 参考电压5V
    float gain = 1.0f;
    
    switch (handle->gain) {
        case ADS1256_GAIN_1:  gain = 1.0f; break;
        case ADS1256_GAIN_2:  gain = 2.0f; break;
        case ADS1256_GAIN_4:  gain = 4.0f; break;
        case ADS1256_GAIN_8:  gain = 8.0f; break;
        case ADS1256_GAIN_16: gain = 16.0f; break;
        case ADS1256_GAIN_32: gain = 32.0f; break;
        case ADS1256_GAIN_64: gain = 64.0f; break;
    }
    
    voltage = ((float)raw / 8388608.0f) * (vref / gain);
    
    return voltage;
}

/* 自校准 */
void ADS1256_SelfCalibrate(ADS1256_Handle* handle)
{
    printf("ADS1256 Self Calibrating...\r\n");
    
    ADS1256_WriteCmd(handle, ADS1256_CMD_SELFCAL);
    ADS1256_WaitDRDY(handle, 500);
    
    // 检查校准状态
    uint8_t status = ADS1256_ReadReg(handle, ADS1256_REG_STATUS);
    if (status & 0x04) {  // CALIBRATION ERROR位
        printf("ADS1256 Calibration Failed!\r\n");
        handle->error_count++;
    } else {
        printf("ADS1256 Calibration OK\r\n");
    }
}

/* 扫描所有通道 */
void ADS1256_ScanChannels(ADS1256_Handle* handle)
{
    for (int i = 0; i < 8; i++) {
        handle->voltage[i] = ADS1256_ReadVoltage(handle, (ADS1256_Channel)i);
        handle->raw_data[i] = ADS1256_ReadData(handle);
        Delay_Ms(10);
    }
    handle->sample_count++;
}

/* 获取通道电压 */
float ADS1256_GetVoltage(ADS1256_Handle* handle, uint8_t channel)
{
    if (channel < 8) {
        return handle->voltage[channel];
    }
    return 0.0f;
}

/* 测试函数 */
void ADS1256_Test(ADS1256_Handle* handle)
{
    printf("\r\n========== ADS1256 Test ==========\r\n");
    
    // 1. 读取ID寄存器
    uint8_t id = ADS1256_ReadReg(handle, ADS1256_REG_STATUS);
    printf("Status Register: 0x%02X\r\n", id);
    
    // 2. 读取数据速率寄存器
    uint8_t rate = ADS1256_ReadReg(handle, ADS1256_REG_DRATE);
    printf("Data Rate Register: 0x%02X\r\n", rate);
    
    // 3. 扫描所有通道
    printf("\r\nScanning Channels:\r\n");
    ADS1256_ScanChannels(handle);
    
    for (int i = 0; i < 8; i++) {
        printf("AIN%d: Raw=0x%08lX, Voltage=%.6fV\r\n", 
               i, handle->raw_data[i], handle->voltage[i]);
    }
    
    // 4. 连续采样测试
    printf("\r\nContinuous Sampling Test (10 samples):\r\n");
    for (int i = 0; i < 10; i++) {
        float v = ADS1256_ReadVoltage(handle, ADS1256_AIN0);
        printf("Sample %d: %.6fV\r\n", i+1, v);
        Delay_Ms(500);
    }
    
    printf("========== Test Complete ==========\r\n");
}

/* 私有函数:CS拉低 */
static void ADS1256_CS_Low(ADS1256_Handle* handle)
{
    GPIO_ResetBits(handle->cs_port, handle->cs_pin);
}

/* 私有函数:CS拉高 */
static void ADS1256_CS_High(ADS1256_Handle* handle)
{
    GPIO_SetBits(handle->cs_port, handle->cs_pin);
}

/* 私有函数:SPI传输 */
static uint8_t ADS1256_SPI_Transfer(ADS1256_Handle* handle, uint8_t data)
{
    // 等待发送缓冲区空
    while (SPI_I2S_GetFlagStatus(handle->spi, SPI_I2S_FLAG_TXE) == RESET);
    
    // 发送数据
    SPI_I2S_SendData(handle->spi, data);
    
    // 等待接收完成
    while (SPI_I2S_GetFlagStatus(handle->spi, SPI_I2S_FLAG_RXNE) == RESET);
    
    // 返回接收的数据
    return SPI_I2S_ReceiveData(handle->spi);
}

/* 私有函数:微秒延时 */
static void ADS1256_DelayUs(uint32_t us)
{
    // 根据系统时钟调整
    for (uint32_t i = 0; i < us * 8; i++) {
        __NOP();
    }
}

3.3 主程序测试 (main.c)

c 复制代码
/**
  * @file main.c
  * @brief ADS1256 测试主程序
  */
#include "stm32f10x.h"
#include "ads1256.h"
#include "delay.h"
#include "usart.h"
#include "spi.h"
#include "gpio.h"

/* 全局变量 */
ADS1256_Handle ads1256;

/* 初始化系统 */
void System_Init(void)
{
    /* 1. 系统时钟初始化 */
    SystemInit();
    Delay_Init();
    
    /* 2. 串口初始化 */
    USART_Init_115200();
    printf("System Init OK\r\n");
    
    /* 3. SPI初始化 */
    SPI1_Init();  // 配置为 2MHz, CPOL=0, CPHA=1
    
    /* 4. GPIO初始化 */
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // CS引脚 (PA4)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA, GPIO_Pin_4);  // CS默认高
    
    // DRDY引脚 (PB0) - 外部中断
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    // RESET引脚 (PB1)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB, GPIO_Pin_1);  // RESET默认高
    
    // SYNC引脚 (PB2)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB, GPIO_Pin_2);  // SYNC默认高
}

/* 初始化ADS1256 */
void ADS1256_Init_Device(void)
{
    /* 配置ADS1256句柄 */
    ads1256.spi = SPI1;
    ads1256.cs_port = GPIOA;
    ads1256.cs_pin = GPIO_Pin_4;
    ads1256.drdy_port = GPIOB;
    ads1256.drdy_pin = GPIO_Pin_0;
    ads1256.reset_port = GPIOB;
    ads1256.reset_pin = GPIO_Pin_1;
    ads1256.sync_port = GPIOB;
    ads1256.sync_pin = GPIO_Pin_2;
    
    /* 配置参数 */
    ads1256.gain = ADS1256_GAIN_1;      // 增益1倍
    ads1256.data_rate = ADS1256_RATE_100; // 100 SPS
    ads1256.continuous_mode = false;
    
    /* 初始化ADS1256 */
    ADS1256_Init(&ads1256);
}

/* 主函数 */
int main(void)
{
    /* 系统初始化 */
    System_Init();
    
    /* 初始化ADS1256 */
    ADS1256_Init_Device();
    
    /* 运行测试 */
    ADS1256_Test(&ads1256);
    
    printf("\r\nEntering Main Loop...\r\n");
    
    while (1)
    {
        /* 1. 扫描所有通道 */
        ADS1256_ScanChannels(&ads1256);
        
        /* 2. 打印电压值 */
        printf("Voltages: ");
        for (int i = 0; i < 8; i++) {
            printf("AIN%d=%.4fV ", i, ads1256.voltage[i]);
        }
        printf("\r\n");
        
        /* 3. 计算统计信息 */
        float avg_voltage = 0;
        for (int i = 0; i < 8; i++) {
            avg_voltage += ads1256.voltage[i];
        }
        avg_voltage /= 8;
        
        printf("Average: %.4fV, Samples: %lu, Errors: %lu\r\n", 
               avg_voltage, ads1256.sample_count, ads1256.error_count);
        
        /* 4. 检测异常电压 */
        for (int i = 0; i < 8; i++) {
            if (fabs(ads1256.voltage[i]) > 5.0f) {
                printf("WARNING: AIN%d voltage out of range: %.4fV\r\n", 
                       i, ads1256.voltage[i]);
            }
        }
        
        printf("----------------------------------------\r\n");
        
        /* 5. 延时 */
        Delay_Ms(1000);
    }
}

3.4 SPI配置 (spi.c)

c 复制代码
/**
  * @file spi.c
  * @brief SPI驱动配置
  */
#include "spi.h"

void SPI1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef SPI_InitStructure;
    
    /* 1. 使能时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);
    
    /* 2. 配置GPIO */
    // PA5: SCK, PA6: MISO, PA7: MOSI
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    /* 3. 配置SPI */
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;      // CPOL=0
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;    // CPHA=1
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;       // 软件控制CS
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; // 36MHz/32=1.125MHz
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    
    SPI_Init(SPI1, &SPI_InitStructure);
    
    /* 4. 使能SPI */
    SPI_Cmd(SPI1, ENABLE);
}

四、Keil工程配置

4.1 工程设置

复制代码
Target:
  - Device: STM32F103C8T6
  - Clock: 8MHz HSE → 72MHz PLL
  
C/C++:
  - Define: USE_STDPERIPH_DRIVER
  - Include Paths: 
    .\
    ..\Libraries\CMSIS\Include
    ..\Libraries\STM32F10x_StdPeriph_Driver\inc
    ..\User

4.2 编译优化

复制代码
Optimization Level: -O1
One ELF Section per Function: ✓

参考代码 STM32+ADS1256A/D转换器的驱动测试程序 www.youwenfan.com/contentcsu/56376.html

五、测试与调试

5.1 测试方法

  1. 硬件检查

    bash 复制代码
    # 1. 测量VREF电压(应为5.0V±0.1%)
    # 2. 测量DVDD电压(应为3.3V)
    # 3. 检查晶振是否起振(7.68MHz)
  2. 软件测试

    bash 复制代码
    # 1. 运行ADS1256_Test()
    # 2. 观察串口输出
    # 3. 用万用表测量输入电压
    # 4. 对比ADC读数与实际电压

5.2 预期输出

复制代码
========== ADS1256 Test ==========
Status Register: 0x00
Data Rate Register: 0xA1

Scanning Channels:
AIN0: Raw=0x00000123, Voltage=0.000073V
AIN1: Raw=0x7FFFFF00, Voltage=4.999847V
AIN2: Raw=0x00000000, Voltage=0.000000V
...

Continuous Sampling Test (10 samples):
Sample 1: 2.500123V
Sample 2: 2.500456V
Sample 3: 2.499987V
========== Test Complete ==========

5.3 常见问题排查

问题 原因 解决方案
无数据输出 SPI时序错误 检查CPOL/CPHA设置
数据跳动大 参考电压不稳 更换精密基准源
某通道异常 输入短路 检查通道连接
校准失败 输入悬空 连接已知电压再校准
DRDY不变化 复位引脚未拉高 检查RESET引脚电平

六、精度优化建议

6.1 硬件优化

  1. 模拟电源隔离:AVDD与DVDD分开供电
  2. 参考电压:使用REF5025(0.05%精度)
  3. 输入滤波:每个通道加RC低通滤波(1kΩ+0.1μF)
  4. PCB布局:模拟地与数字地单点连接

6.2 软件优化

c 复制代码
/* 软件滤波 */
#define FILTER_SIZE 10
float filtered_value[FILTER_SIZE];

float MovingAverageFilter(float new_value)
{
    static uint8_t index = 0;
    static float sum = 0;
    
    sum -= filtered_value[index];
    filtered_value[index] = new_value;
    sum += new_value;
    index = (index + 1) % FILTER_SIZE;
    
    return sum / FILTER_SIZE;
}

/* 多次采样取平均 */
float ADS1256_ReadVoltageAvg(ADS1256_Handle* handle, ADS1256_Channel channel, uint8_t times)
{
    float sum = 0;
    for (uint8_t i = 0; i < times; i++) {
        sum += ADS1256_ReadVoltage(handle, channel);
        Delay_Ms(10);
    }
    return sum / times;
}
相关推荐
搁浅小泽2 小时前
PCBA生产工艺流程
单片机·嵌入式硬件·可靠性工程师
GQli204815 小时前
一天看懂一个原理图(day7)电源输入部分
单片机·嵌入式硬件
llilian_1616 小时前
失真度测量仪校准 精准可靠的失真度校准检定测试仪筑牢检测根基 失真度检定装置
功能测试·单片机·嵌入式硬件·硬件工程
XiYang-DING16 小时前
【Java EE】UDP 编程核心类与方法
单片机·udp·java-ee
iCxhust16 小时前
点亮8086最小系统的LED
stm32·单片机·嵌入式硬件·51单片机·微机原理·8086最小系统·8088单板机
时空自由民.17 小时前
开环无感FOC与SPWM&SVPWM
单片机·嵌入式硬件
集芯微电科技有限公司18 小时前
替代TMUX1380A/TMUX1309A双向8:1单通道 4:1双通道控制多路复用器
人工智能·单片机·嵌入式硬件·生成对抗网络·计算机外设
Wallace Zhang18 小时前
SimpleFOC源码学习10(v2.3.2) - 电流传感器CurrentSense.cpp与CurrentSense.h
驱动开发·stm32·学习·电流环·simplefoc·foc电机控制
我要成为嵌入式大佬18 小时前
项目制作日记简介
单片机·嵌入式硬件