基于STM32、HAL库的ADS1220IPWR模数转换器ADC驱动程序设计
一、简介:
ADS1220IPWR是德州仪器(TI)推出的一款24位精密模数转换器(ADC),主要特点包括:
-
24位无失码分辨率
-
2.048V内部基准电压(±0.1%精度)
-
可编程数据速率(5SPS到2kSPS)
-
低功耗:仅1.5mW(3.3V供电时)
-
集成可编程增益放大器(PGA)(1到128倍)
-
4路差分或7路单端输入
-
SPI兼容接口
-
工作温度范围:-40°C到+125°C
-
TSSOP-16封装
二、硬件接口:
ADS1220引脚 | STM32L4引脚 | 功能描述 |
---|---|---|
DVDD | 3.3V | 数字电源(2.7-5.5V) |
AVDD | 3.3V | 模拟电源(2.7-5.5V) |
DGND | GND | 数字地 |
AGND | GND | 模拟地 |
CS | PA4 | 片选(低电平有效) |
SCLK | PA5 | SPI时钟 |
DIN | PA7 | SPI数据输入 |
DOUT/DRDY | PA6 | SPI数据输出/数据就绪 |
DRDY | PA3 | 数据就绪(可选) |
RESET | PA2 | 复位(低电平有效) |
START | PA1 | 开始转换(可选) |
三、头文件:
#ifndef __ADS1220_H
#define __ADS1220_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32l4xx_hal.h"
// ADS1220寄存器地址
#define ADS1220_REG_CONFIG0 0x00
#define ADS1220_REG_CONFIG1 0x01
#define ADS1220_REG_CONFIG2 0x02
#define ADS1220_REG_CONFIG3 0x03
// 命令定义
#define ADS1220_CMD_RESET 0x06
#define ADS1220_CMD_START 0x08
#define ADS1220_CMD_PWRDWN 0x02
#define ADS1220_CMD_RDATA 0x10
#define ADS1220_CMD_RREG 0x20
#define ADS1220_CMD_WREG 0x40
// 数据速率设置
typedef enum {
ADS1220_DR_20SPS = 0x00,
ADS1220_DR_45SPS = 0x01,
ADS1220_DR_90SPS = 0x02,
ADS1220_DR_175SPS = 0x03,
ADS1220_DR_330SPS = 0x04,
ADS1220_DR_600SPS = 0x05,
ADS1220_DR_1000SPS = 0x06
} ADS1220_DataRate;
// PGA增益设置
typedef enum {
ADS1220_GAIN_1 = 0x00,
ADS1220_GAIN_2 = 0x01,
ADS1220_GAIN_4 = 0x02,
ADS1220_GAIN_8 = 0x03,
ADS1220_GAIN_16 = 0x04,
ADS1220_GAIN_32 = 0x05,
ADS1220_GAIN_64 = 0x06,
ADS1220_GAIN_128 = 0x07
} ADS1220_Gain;
// 输入多路复用器配置
typedef enum {
ADS1220_MUX_AIN0_AIN1 = 0x00,
ADS1220_MUX_AIN0_AIN2 = 0x01,
ADS1220_MUX_AIN0_AIN3 = 0x02,
ADS1220_MUX_AIN1_AIN2 = 0x03,
ADS1220_MUX_AIN1_AIN3 = 0x04,
ADS1220_MUX_AIN2_AIN3 = 0x05,
ADS1220_MUX_AIN1_AIN0 = 0x06,
ADS1220_MUX_AIN3_AIN2 = 0x07,
ADS1220_MUX_AIN0_AVSS = 0x08,
ADS1220_MUX_AIN1_AVSS = 0x09,
ADS1220_MUX_AIN2_AVSS = 0x0A,
ADS1220_MUX_AIN3_AVSS = 0x0B,
ADS1220_MUX_VREF_MONITOR = 0x0C,
ADS1220_MUX_AVDD_MONITOR = 0x0D,
ADS1220_MUX_SHORTED = 0x0E
} ADS1220_MuxConfig;
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;
} ADS1220_HandleTypeDef;
// 函数声明
void ADS1220_Init(ADS1220_HandleTypeDef *hadc);
void ADS1220_Reset(ADS1220_HandleTypeDef *hadc);
void ADS1220_StartConversion(ADS1220_HandleTypeDef *hadc);
void ADS1220_PowerDown(ADS1220_HandleTypeDef *hadc);
uint8_t ADS1220_ReadRegister(ADS1220_HandleTypeDef *hadc, uint8_t reg);
void ADS1220_WriteRegister(ADS1220_HandleTypeDef *hadc, uint8_t reg, uint8_t value);
int32_t ADS1220_ReadData(ADS1220_HandleTypeDef *hadc);
void ADS1220_SetDataRate(ADS1220_HandleTypeDef *hadc, ADS1220_DataRate rate);
void ADS1220_SetGain(ADS1220_HandleTypeDef *hadc, ADS1220_Gain gain);
void ADS1220_SetMux(ADS1220_HandleTypeDef *hadc, ADS1220_MuxConfig mux);
uint8_t ADS1220_DataReady(ADS1220_HandleTypeDef *hadc);
#ifdef __cplusplus
}
#endif
#endif /* __ADS1220_H */
四、源文件:
#include "ads1220.h"
#include "string.h"
// 私有函数声明
static void ADS1220_CS_Low(ADS1220_HandleTypeDef *hadc);
static void ADS1220_CS_High(ADS1220_HandleTypeDef *hadc);
static void ADS1220_Delay(uint32_t delay);
static void ADS1220_SPI_Transmit(ADS1220_HandleTypeDef *hadc, uint8_t *data, uint16_t size);
static void ADS1220_SPI_TransmitReceive(ADS1220_HandleTypeDef *hadc, uint8_t *txData, uint8_t *rxData, uint16_t size);
void ADS1220_Init(ADS1220_HandleTypeDef *hadc) {
// 硬件复位
HAL_GPIO_WritePin(hadc->reset_port, hadc->reset_pin, GPIO_PIN_RESET);
ADS1220_Delay(10);
HAL_GPIO_WritePin(hadc->reset_port, hadc->reset_pin, GPIO_PIN_SET);
ADS1220_Delay(10);
// 发送复位命令
ADS1220_Reset(hadc);
// 默认配置
// CONFIG0: MUX AIN0/AIN1, Gain 1, PGA enabled
ADS1220_WriteRegister(hadc, ADS1220_REG_CONFIG0, 0x00);
// CONFIG1: DR=20SPS, Mode=Normal, Conv mode=continuous, Temp sensor disabled
ADS1220_WriteRegister(hadc, ADS1220_REG_CONFIG1, 0x00);
// CONFIG2: VREF internal, 50/60Hz rejection, Power switch open, IDAC off
ADS1220_WriteRegister(hadc, ADS1220_REG_CONFIG2, 0x00);
// CONFIG3: DRDY only, CRC disabled, No checks
ADS1220_WriteRegister(hadc, ADS1220_REG_CONFIG3, 0x00);
// 开始连续转换
ADS1220_StartConversion(hadc);
}
void ADS1220_Reset(ADS1220_HandleTypeDef *hadc) {
uint8_t cmd = ADS1220_CMD_RESET;
ADS1220_CS_Low(hadc);
ADS1220_SPI_Transmit(hadc, &cmd, 1);
ADS1220_CS_High(hadc);
ADS1220_Delay(10); // 等待复位完成
}
void ADS1220_StartConversion(ADS1220_HandleTypeDef *hadc) {
uint8_t cmd = ADS1220_CMD_START;
ADS1220_CS_Low(hadc);
ADS1220_SPI_Transmit(hadc, &cmd, 1);
ADS1220_CS_High(hadc);
}
void ADS1220_PowerDown(ADS1220_HandleTypeDef *hadc) {
uint8_t cmd = ADS1220_CMD_PWRDWN;
ADS1220_CS_Low(hadc);
ADS1220_SPI_Transmit(hadc, &cmd, 1);
ADS1220_CS_High(hadc);
}
uint8_t ADS1220_ReadRegister(ADS1220_HandleTypeDef *hadc, uint8_t reg) {
uint8_t txData[2] = {0};
uint8_t rxData[2] = {0};
txData[0] = ADS1220_CMD_RREG | (reg << 2);
txData[1] = 0x00; // 只读取一个寄存器
ADS1220_CS_Low(hadc);
ADS1220_SPI_TransmitReceive(hadc, txData, rxData, 2);
ADS1220_CS_High(hadc);
return rxData[1];
}
void ADS1220_WriteRegister(ADS1220_HandleTypeDef *hadc, uint8_t reg, uint8_t value) {
uint8_t txData[2] = {0};
txData[0] = ADS1220_CMD_WREG | (reg << 2);
txData[1] = value;
ADS1220_CS_Low(hadc);
ADS1220_SPI_Transmit(hadc, txData, 2);
ADS1220_CS_High(hadc);
}
int32_t ADS1220_ReadData(ADS1220_HandleTypeDef *hadc) {
uint8_t txData[3] = {0};
uint8_t rxData[3] = {0};
int32_t result = 0;
txData[0] = ADS1220_CMD_RDATA;
ADS1220_CS_Low(hadc);
ADS1220_SPI_TransmitReceive(hadc, txData, rxData, 3);
ADS1220_CS_High(hadc);
result = (rxData[0] << 16) | (rxData[1] << 8) | rxData[2];
// 处理24位有符号数转换为32位有符号数
if (result & 0x00800000) {
result |= 0xFF000000;
}
return result;
}
void ADS1220_SetDataRate(ADS1220_HandleTypeDef *hadc, ADS1220_DataRate rate) {
uint8_t config = ADS1220_ReadRegister(hadc, ADS1220_REG_CONFIG1);
config = (config & 0xF8) | (rate & 0x07);
ADS1220_WriteRegister(hadc, ADS1220_REG_CONFIG1, config);
}
void ADS1220_SetGain(ADS1220_HandleTypeDef *hadc, ADS1220_Gain gain) {
uint8_t config = ADS1220_ReadRegister(hadc, ADS1220_REG_CONFIG0);
config = (config & 0x8F) | ((gain & 0x07) << 4);
ADS1220_WriteRegister(hadc, ADS1220_REG_CONFIG0, config);
}
void ADS1220_SetMux(ADS1220_HandleTypeDef *hadc, ADS1220_MuxConfig mux) {
uint8_t config = ADS1220_ReadRegister(hadc, ADS1220_REG_CONFIG0);
config = (config & 0xF0) | (mux & 0x0F);
ADS1220_WriteRegister(hadc, ADS1220_REG_CONFIG0, config);
}
uint8_t ADS1220_DataReady(ADS1220_HandleTypeDef *hadc) {
return (HAL_GPIO_ReadPin(hadc->drdy_port, hadc->drdy_pin) == GPIO_PIN_RESET);
}
// 私有函数实现
static void ADS1220_CS_Low(ADS1220_HandleTypeDef *hadc) {
HAL_GPIO_WritePin(hadc->cs_port, hadc->cs_pin, GPIO_PIN_RESET);
}
static void ADS1220_CS_High(ADS1220_HandleTypeDef *hadc) {
HAL_GPIO_WritePin(hadc->cs_port, hadc->cs_pin, GPIO_PIN_SET);
}
static void ADS1220_Delay(uint32_t delay) {
HAL_Delay(delay);
}
static void ADS1220_SPI_Transmit(ADS1220_HandleTypeDef *hadc, uint8_t *data, uint16_t size) {
HAL_SPI_Transmit(hadc->hspi, data, size, HAL_MAX_DELAY);
}
static void ADS1220_SPI_TransmitReceive(ADS1220_HandleTypeDef *hadc, uint8_t *txData, uint8_t *rxData, uint16_t size) {
HAL_SPI_TransmitReceive(hadc->hspi, txData, rxData, size, HAL_MAX_DELAY);
}
五、应用:
#include "main.h"
#include "ads1220.h"
SPI_HandleTypeDef hspi1;
ADS1220_HandleTypeDef hads1220;
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();
// 初始化ADS1220
hads1220.hspi = &hspi1;
hads1220.cs_port = ADS1220_CS_GPIO_Port;
hads1220.cs_pin = ADS1220_CS_Pin;
hads1220.drdy_port = ADS1220_DRDY_GPIO_Port;
hads1220.drdy_pin = ADS1220_DRDY_Pin;
hads1220.reset_port = ADS1220_RESET_GPIO_Port;
hads1220.reset_pin = ADS1220_RESET_Pin;
ADS1220_Init(&hads1220);
// 配置ADS1220
ADS1220_SetGain(&hads1220, ADS1220_GAIN_1);
ADS1220_SetDataRate(&hads1220, ADS1220_DR_20SPS);
ADS1220_SetMux(&hads1220, ADS1220_MUX_AIN0_AIN1);
while (1) {
if (ADS1220_DataReady(&hads1220)) {
int32_t adcValue = ADS1220_ReadData(&hads1220);
// 转换为电压值 (假设使用内部2.048V参考电压,增益=1)
float voltage = (adcValue * 2.048f) / 8388608.0f; // 2^23 = 8388608
// 在此处处理电压值,如显示、传输等
HAL_Delay(100);
}
}
}
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();
// ADS1220 CS引脚
GPIO_InitStruct.Pin = ADS1220_CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(ADS1220_CS_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(ADS1220_CS_GPIO_Port, ADS1220_CS_Pin, GPIO_PIN_SET);
// ADS1220 DRDY引脚
GPIO_InitStruct.Pin = ADS1220_DRDY_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(ADS1220_DRDY_GPIO_Port, &GPIO_InitStruct);
// ADS1220 RESET引脚
GPIO_InitStruct.Pin = ADS1220_RESET_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ADS1220_RESET_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(ADS1220_RESET_GPIO_Port, ADS1220_RESET_Pin, 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);
}