一、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 测试方法
-
硬件检查:
bash# 1. 测量VREF电压(应为5.0V±0.1%) # 2. 测量DVDD电压(应为3.3V) # 3. 检查晶振是否起振(7.68MHz) -
软件测试:
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 硬件优化
- 模拟电源隔离:AVDD与DVDD分开供电
- 参考电压:使用REF5025(0.05%精度)
- 输入滤波:每个通道加RC低通滤波(1kΩ+0.1μF)
- 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;
}