基于STM32、HAL库的ADS1256IDBR模数转换器ADC驱动程序设计
一、简介:
ADS1256IDBR是德州仪器(TI)生产的一款高精度、24位Δ-Σ模数转换器(ADC),主要特性包括:
-  24位无丢失码分辨率 
-  最高30kSPS的数据速率 
-  低噪声:2.5μV RMS(在30SPS时) 
-  8个单端或4个差分输入通道 
-  内置可编程增益放大器(PGA):1至64V/V 
-  内置低漂移电压基准(2.5V) 
-  SPI兼容接口 
-  工作电压:3.3V或5V 
二、硬件接口:
| ADS1256引脚 | STM32L4引脚 | 功能描述 | 
|---|---|---|
| DVDD | 3.3V | 数字电源 | 
| AVDD | 3.3V | 模拟电源 | 
| DGND | GND | 数字地 | 
| AGND | GND | 模拟地 | 
| CS | PA4 | 片选(低电平有效) | 
| DIN | PA7 | SPI数据输入(MOSI) | 
| DOUT | PA6 | SPI数据输出(MISO) | 
| SCLK | PA5 | SPI时钟 | 
| DRDY | PA3 | 数据就绪(低电平有效) | 
| RESET | PA2 | 复位(低电平有效) | 
注意:模拟和数字地应在一点连接,电源引脚应加去耦电容(0.1μF)
三、头文件:
#ifndef ADS1256_H
 #define ADS1256_H
#include "stm32l4xx_hal.h"
// ADS1256寄存器地址
 #define ADS1256_REG_STATUS  0x00
 #define ADS1256_REG_MUX     0x01
 #define ADS1256_REG_ADCON   0x02
 #define ADS1256_REG_DRATE   0x03
 #define ADS1256_REG_IO     0x04
 #define ADS1256_REG_OFC0    0x05
 #define ADS1256_REG_OFC1    0x06
 #define ADS1256_REG_OFC2    0x07
 #define ADS1256_REG_FSC0    0x08
 #define ADS1256_REG_FSC1    0x09
 #define ADS1256_REG_FSC2    0x0A
// 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
 #define ADS1256_CMD_WREG    0x50
 #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
// PGA增益设置
 typedef enum {
     ADS1256_GAIN_1 = 0,
     ADS1256_GAIN_2,
     ADS1256_GAIN_4,
     ADS1256_GAIN_8,
     ADS1256_GAIN_16,
     ADS1256_GAIN_32,
     ADS1256_GAIN_64
 } ADS1256_Gain;
// 数据速率设置
 typedef enum {
     ADS1256_DRATE_30000 = 0xF0,
     ADS1256_DRATE_15000 = 0xE0,
     ADS1256_DRATE_7500  = 0xD0,
     ADS1256_DRATE_3750  = 0xC0,
     ADS1256_DRATE_2000  = 0xB0,
     ADS1256_DRATE_1000  = 0xA1,
     ADS1256_DRATE_500   = 0x92,
     ADS1256_DRATE_100   = 0x82,
     ADS1256_DRATE_60    = 0x72,
     ADS1256_DRATE_50    = 0x63,
     ADS1256_DRATE_30    = 0x53,
     ADS1256_DRATE_25    = 0x43,
     ADS1256_DRATE_15    = 0x33,
     ADS1256_DRATE_10    = 0x23,
     ADS1256_DRATE_5     = 0x13,
     ADS1256_DRATE_2_5   = 0x03
 } ADS1256_DataRate;
// 输入通道选择
 typedef enum {
     ADS1256_AIN0 = 0,
     ADS1256_AIN1,
     ADS1256_AIN2,
     ADS1256_AIN3,
     ADS1256_AIN4,
     ADS1256_AIN5,
     ADS1256_AIN6,
     ADS1256_AIN7,
     ADS1256_AINCOM
 } ADS1256_Input;
typedef struct {
     SPI_HandleTypeDef *hspi;
     GPIO_TypeDef *cs_port;
     uint16_t cs_pin;
     GPIO_TypeDef *drdy_port;
     uint16_t drdy_pin;
     GPIO_TypeDef *reset_port;
     uint16_t reset_pin;
     ADS1256_Gain gain;
     ADS1256_DataRate data_rate;
 } ADS1256_HandleTypeDef;
// 函数声明
 void ADS1256_Init(ADS1256_HandleTypeDef *hadc);
 void ADS1256_Reset(ADS1256_HandleTypeDef *hadc);
 void ADS1256_WriteReg(ADS1256_HandleTypeDef *hadc, uint8_t reg, uint8_t data);
 uint8_t ADS1256_ReadReg(ADS1256_HandleTypeDef *hadc, uint8_t reg);
 void ADS1256_SendCommand(ADS1256_HandleTypeDef *hadc, uint8_t cmd);
 void ADS1256_WaitDRDY(ADS1256_HandleTypeDef *hadc);
 void ADS1256_SetChannel(ADS1256_HandleTypeDef *hadc, ADS1256_Input positive, ADS1256_Input negative);
 int32_t ADS1256_ReadData(ADS1256_HandleTypeDef *hadc);
 float ADS1256_ReadVoltage(ADS1256_HandleTypeDef *hadc);
#endif // ADS1256_H
四、源文件:
#include "ads1256.h"
 #include "stm32l4xx_hal.h"
 #include <string.h>
// 私有函数声明
 static void ADS1256_CS_Low(ADS1256_HandleTypeDef *hadc);
 static void ADS1256_CS_High(ADS1256_HandleTypeDef *hadc);
 static void ADS1256_Delay(uint32_t delay);
void ADS1256_Init(ADS1256_HandleTypeDef *hadc) {
     // 硬件复位
     ADS1256_Reset(hadc);
     
     // 等待DRDY变低
     ADS1256_WaitDRDY(hadc);
     
     // 发送同步命令
     ADS1256_SendCommand(hadc, ADS1256_CMD_SYNC);
     ADS1256_Delay(10);
     ADS1256_SendCommand(hadc, ADS1256_CMD_WAKEUP);
     ADS1256_Delay(10);
     
     // 配置寄存器
     uint8_t buf[4];
     
     // 配置MUX寄存器 (AIN0和AINCOM差分输入)
     buf[0] = (ADS1256_AIN0 << 4) | ADS1256_AINCOM;
     ADS1256_WriteReg(hadc, ADS1256_REG_MUX, buf[0]);
     
     // 配置ADCON寄存器 (PGA使能,增益设置)
     buf[1] = (0 << 3) | hadc->gain; // CLKOUT关闭,增益设置
     ADS1256_WriteReg(hadc, ADS1256_REG_ADCON, buf[1]);
     
     // 配置数据速率
     ADS1256_WriteReg(hadc, ADS1256_REG_DRATE, hadc->data_rate);
     
     // 自校准
     ADS1256_SendCommand(hadc, ADS1256_CMD_SELFCAL);
     ADS1256_Delay(100); // 等待校准完成
 }
void ADS1256_Reset(ADS1256_HandleTypeDef *hadc) {
     // 拉低复位引脚
     HAL_GPIO_WritePin(hadc->reset_port, hadc->reset_pin, GPIO_PIN_RESET);
     ADS1256_Delay(100);
     
     // 释放复位引脚
     HAL_GPIO_WritePin(hadc->reset_port, hadc->reset_pin, GPIO_PIN_SET);
     ADS1256_Delay(1000); // 等待复位完成
 }
void ADS1256_WriteReg(ADS1256_HandleTypeDef *hadc, uint8_t reg, uint8_t data) {
     ADS1256_WaitDRDY(hadc);
     
     ADS1256_CS_Low(hadc);
     
     uint8_t txBuf[2];
     txBuf[0] = ADS1256_CMD_WREG | reg;
     txBuf[1] = 0x00; // 写入1个寄存器
     txBuf[2] = data;
     
     HAL_SPI_Transmit(hadc->hspi, txBuf, 3, HAL_MAX_DELAY);
     
     ADS1256_CS_High(hadc);
 }
uint8_t ADS1256_ReadReg(ADS1256_HandleTypeDef *hadc, uint8_t reg) {
     ADS1256_WaitDRDY(hadc);
     
     ADS1256_CS_Low(hadc);
     
     uint8_t txBuf[3] = {0};
     uint8_t rxBuf[3] = {0};
     
     txBuf[0] = ADS1256_CMD_RREG | reg;
     txBuf[1] = 0x00; // 读取1个寄存器
     
     HAL_SPI_TransmitReceive(hadc->hspi, txBuf, rxBuf, 3, HAL_MAX_DELAY);
     
     ADS1256_CS_High(hadc);
     
     return rxBuf[2];
 }
void ADS1256_SendCommand(ADS1256_HandleTypeDef *hadc, uint8_t cmd) {
     ADS1256_WaitDRDY(hadc);
     
     ADS1256_CS_Low(hadc);
     HAL_SPI_Transmit(hadc->hspi, &cmd, 1, HAL_MAX_DELAY);
     ADS1256_CS_High(hadc);
 }
void ADS1256_WaitDRDY(ADS1256_HandleTypeDef *hadc) {
     while (HAL_GPIO_ReadPin(hadc->drdy_port, hadc->drdy_pin) == GPIO_PIN_SET) {
         // 等待DRDY变低
     }
 }
void ADS1256_SetChannel(ADS1256_HandleTypeDef *hadc, ADS1256_Input positive, ADS1256_Input negative) {
     uint8_t mux = (positive << 4) | negative;
     ADS1256_WriteReg(hadc, ADS1256_REG_MUX, mux);
     
     // 发送同步和唤醒命令以应用新设置
     ADS1256_SendCommand(hadc, ADS1256_CMD_SYNC);
     ADS1256_Delay(10);
     ADS1256_SendCommand(hadc, ADS1256_CMD_WAKEUP);
     ADS1256_Delay(10);
 }
int32_t ADS1256_ReadData(ADS1256_HandleTypeDef *hadc) {
     ADS1256_WaitDRDY(hadc);
     
     ADS1256_CS_Low(hadc);
     
     uint8_t txBuf[4] = {ADS1256_CMD_RDATA, 0x00, 0x00, 0x00};
     uint8_t rxBuf[4] = {0};
     
     HAL_SPI_TransmitReceive(hadc->hspi, txBuf, rxBuf, 4, HAL_MAX_DELAY);
     
     ADS1256_CS_High(hadc);
     
     // 组合24位数据
     int32_t value = (rxBuf[1] << 16) | (rxBuf[2] << 8) | rxBuf[3];
     
     // 处理符号位扩展
     if (value & 0x00800000) {
         value |= 0xFF000000;
     }
     
     return value;
 }
float ADS1256_ReadVoltage(ADS1256_HandleTypeDef *hadc) {
     int32_t raw = ADS1256_ReadData(hadc);
     
     // 计算电压 (假设使用内部2.5V基准)
     float voltage = (raw * 2.5f) / (8388607.0f * (1 << hadc->gain));
     
     return voltage;
 }
static void ADS1256_CS_Low(ADS1256_HandleTypeDef *hadc) {
     HAL_GPIO_WritePin(hadc->cs_port, hadc->cs_pin, GPIO_PIN_RESET);
 }
static void ADS1256_CS_High(ADS1256_HandleTypeDef *hadc) {
     HAL_GPIO_WritePin(hadc->cs_port, hadc->cs_pin, GPIO_PIN_SET);
 }
static void ADS1256_Delay(uint32_t delay) {
     HAL_Delay(delay);
 }
五、应用:
#include "stm32l4xx_hal.h"
 #include "ads1256.h"
SPI_HandleTypeDef hspi1;
 ADS1256_HandleTypeDef hadc1;
void SystemClock_Config(void);
 static void MX_GPIO_Init(void);
 static void MX_SPI1_Init(void);
int main(void) {
     HAL_Init();
     SystemClock_Config();
     MX_GPIO_Init();
     MX_SPI1_Init();
     
     // 初始化ADS1256
     hadc1.hspi = &hspi1;
     hadc1.cs_port = GPIOA;
     hadc1.cs_pin = GPIO_PIN_4;
     hadc1.drdy_port = GPIOA;
     hadc1.drdy_pin = GPIO_PIN_3;
     hadc1.reset_port = GPIOA;
     hadc1.reset_pin = GPIO_PIN_2;
     hadc1.gain = ADS1256_GAIN_1;
     hadc1.data_rate = ADS1256_DRATE_100;
     
     ADS1256_Init(&hadc1);
     
     while (1) {
         // 读取AIN0电压
         float voltage = ADS1256_ReadVoltage(&hadc1);
         
         // 可以在此处添加电压处理逻辑
         // 例如发送到串口或进行其他处理
         
         HAL_Delay(100); // 每100ms读取一次
     }
 }
void SystemClock_Config(void) {
     // 系统时钟配置代码 (根据具体硬件配置)
 }
static void MX_SPI1_Init(void) {
     hspi1.Instance = SPI1;
     hspi1.Init.Mode = SPI_MODE_MASTER;
     hspi1.Init.Direction = SPI_DIRECTION_2LINES;
     hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
     hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
     hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
     hspi1.Init.NSS = SPI_NSS_SOFT;
     hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
     hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
     hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
     hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
     hspi1.Init.CRCPolynomial = 7;
     if (HAL_SPI_Init(&hspi1) != HAL_OK) {
         Error_Handler();
     }
 }
static void MX_GPIO_Init(void) {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
     
     // 启用时钟
     __HAL_RCC_GPIOA_CLK_ENABLE();
     
     // DRDY引脚配置 (输入)
     GPIO_InitStruct.Pin = GPIO_PIN_3;
     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
     GPIO_InitStruct.Pull = GPIO_PULLUP;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
     
     // CS引脚配置 (输出)
     GPIO_InitStruct.Pin = GPIO_PIN_4;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // 初始高电平
     
     // RESET引脚配置 (输出)
     GPIO_InitStruct.Pin = GPIO_PIN_2;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); // 初始高电平
     
     // SPI引脚配置
     GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
     GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 }
void Error_Handler(void) {
     while(1) {
         // 错误处理
     }
 }
