ADS867x 支持双极输入范围的 14 位 500kSPS 4 和 8 通道、单电源 SAR ADC。
器件特性
- 具有集成模拟前端的 14 位模数转换器 (ADC)
- 具有自动和手动扫描功能的 4 通道、8 通道多路复用器
- 通道独立可编程输入:
- ±10.24V、±5.12V、±2.56V、±1.28V、±0.64V
- 10.24V、5.12V、2.56V、1.28V
- 5V 模拟电源:1.65V 到 5V I/O 电源
- 恒定的阻性输入阻抗:1MΩ
- 输入过压保护:高达 ±20V
- 低漂移的片上 4.096V 基准电压
- 出色的性能:
- 500kSPS 的总吞吐量
- 差分非线性 (DNL):±0.2 最低有效位 (LSB);最大积分非线性 (INL):±0.25 LSB
- 增益误差和偏移误差的漂移均较低
- 信噪比 (SNR):85dB;总谐波失真 (THD):–100dB
- 低功耗:65mW
- AUX 输入 → 直接连接到 ADC 输入
- ALARM → 每通道的高低阈值
- SPI- 兼容接口,支持菊花链连接
- 工业温度范围:-40°C 至 125°C
- TSSOP-38 封装 (9.7mm × 4.4mm)
器件应用
- 电力自动化
- 保护中继器
- PLC 模拟输入模块
器件说明
ADS8674 和 ADS8678 是基于 14 位逐次逼近寄存器 (SAR) 模数转换器 (ADC) 的 4 通道、8 通道集成数据采集系统,工作吞吐量达 500kSPS。ADS867x 提供了用于各输入通道的集成模拟前端电路(过压保护高达 ±20V)、支持自动和手动两种扫描模式的 4 通道或 8 通道多路复用器、以及低温度漂移的片上 4.096V 基准电压。
ADS867x 由单个 5V 模拟电源供电,每个输入通道均可支持真正的双极输入范围((±10.24V、 ±5.12V、±2.56V、±1.28V 和 ±0.64V)和单极输入范围(0V 至 10.24V、0V 至 5.12V、0V 至 2.56V 以及 0V 至 1.28V)。 模拟前端在所有输入范围内的增益均经过了精确调整,以确保高直流精度。 输入范围的选择可通过软件进行编程,各通道输入范围的选择相互独立。 该器件提供了一个 1MΩ 的恒定阻性输入阻抗(无论所选输入范围为何)。
ADS8674 和 ADS8678 为数字主机提供了一个兼容串行外设接口 (SPI) 的简单串行接口,同时支持以菊花链方式连接多个器件。 数字电源可提供 1.65V 到 5.25V 范围内的电压,因此可直接连接各种主机控制器。
引脚配置和功能
数字接口配置
驱动示例
- 以 ADS8674 为例,配置手动采集模式
- SPI 采用 MODE1 模式,详细参考【ZYNQ】SPI 简介及 EMIO 模拟 SPI 驱动示例
- ads8674.h
/** * Copyright (c) 2022-2023,HelloAlpha * * Change Logs: * Date Author Notes */ #ifndef __ADS8674_H__ #define __ADS8674_H__ #include "spi_ctrl.h" /* Command Register */ #define NO_OP 0X0000 #define STDBY 0X8200 #define PWR_DN 0X8300 #define RST 0X8500 #define AUTO_RST 0XA000 #define MAN_CH_0 0XC000 #define MAN_CH_1 0XC400 #define MAN_CH_2 0XC800 #define MAN_CH_3 0XCC00 #define MAN_AUX 0XE000 /* Program Register */ #define AUTO_SEQ_EN 0X01 #define Channel_Power_Down 0X02 #define Feature_Select 0X03 #define Channel_0_Input_Range 0X05 #define Channel_1_Input_Range 0X06 #define Channel_2_Input_Range 0X07 #define Channel_3_Input_Range 0X08 #define WRITE 1 #define READ 0 /****Stype of SPI rxData****/ #define WR_REG_DATA_NOT_USE 0 #define WR_CMD_DATA_NOT_USE 0 #define WR_REG_DATA 1 #define WR_CMD_DATA 2 /******ADS8674 Control******/ #define CH3_EN 0X08 #define CH2_EN 0X04 #define CH1_EN 0X02 #define CH0_EN 0X01 #define CH3_PD 0X08 #define CH2_PD 0X04 #define CH1_PD 0X02 #define CH0_PD 0X01 #define VREF_25_25 0X00 #define VREF_125_125 0X01 #define VREF_0625_0625 0X02 #define VREF_0_25 0X05 #define VREF_0_125 0X06 /*** For SPI Bus Control ***/ #define ADS8674_START_COMMUNICATION SPI_START_COMMUNICATION #define ADS8674_END_COMMUNICATION SPI_STOP_COMMUNICATION void ADS8674_SPI_ReadWrite_xBytes(uint8_t *txData, uint8_t *rxData, uint32_t dataLength); void ADS8674_SPI_Write_CommandRegister(uint32_t command); void ADS8674_SPI_Write_ProgramRegister(uint32_t address, uint32_t data); void ADS8674_SPI_Read_ProgramRegister(uint32_t address); void ADS8674_Set_Auto_RST_Mode(void); void ADS8674_Set_Auto_Scan_Sequence(uint32_t sequence); void ADS8674_Set_CH_Range_Select(uint32_t channel, uint32_t range); void ADS8674_Get_AUTO_RST_Mode_Data(void); void ADS8674_Get_Manual_Mode_Data(uint32_t channel); void ADS8674_Init(void); uint32_t ADS8674_Read_CH(uint32_t channel); extern uint8_t ADS8674_rxBuf_4Byte[4]; extern uint8_t ADS8674_rxBuf_16Byte[16]; extern uint8_t Return_Data_Format; #endif
- ads8674.c
/** * Copyright (c) 2022-2023,HelloAlpha * * Change Logs: * Date Author Notes */ #include "ads8674.h" #include "sleep.h" #define DELAY_TIME 500 #define ADS_DELAY(...) usleep(__VA_ARGS__) uint8_t ADS8674_rxBuf_4Byte[4]; uint8_t ADS8674_rxBuf_16Byte[16]; uint8_t Return_Data_Format = 0; void ADS8674_SPI_ReadWrite_xBytes(uint8_t *txData, uint8_t *rxData, uint32_t dataLength) { ADS8674_START_COMMUNICATION; for(uint8_t i = 0; i < dataLength; i++) { rxData[i] = SOFT_SPI_RW_MODE1(txData[i]); } ADS8674_END_COMMUNICATION; } void ADS8674_SPI_Write_CommandRegister(uint32_t command) { uint8_t sendData_Temp[4]; sendData_Temp[0] = (command & 0XFF00) >> 8; sendData_Temp[1] = command & 0X00FF; ADS8674_SPI_ReadWrite_xBytes(sendData_Temp, ADS8674_rxBuf_4Byte, 4); } void ADS8674_SPI_Write_ProgramRegister(uint32_t address, uint32_t data) { uint8_t sendData_Temp[4]; sendData_Temp[0] = (address << 1) | WRITE; sendData_Temp[1] = data; ADS8674_SPI_ReadWrite_xBytes(sendData_Temp, ADS8674_rxBuf_4Byte, 4); } void ADS8674_SPI_Read_ProgramRegister(uint32_t address) { static uint8_t sendData_Temp[4]; sendData_Temp[0] = (address) << 1 | READ; sendData_Temp[1] = 0xFF; ADS8674_SPI_ReadWrite_xBytes(sendData_Temp, ADS8674_rxBuf_4Byte, 4); } void ADS8674_Set_Auto_RST_Mode(void) { Return_Data_Format = WR_CMD_DATA_NOT_USE; ADS8674_SPI_Write_CommandRegister(AUTO_RST); } void ADS8674_Set_Auto_Scan_Sequence(uint32_t sequence) { Return_Data_Format = WR_REG_DATA_NOT_USE; ADS8674_SPI_Write_ProgramRegister(AUTO_SEQ_EN, sequence); } void ADS8674_Set_CH_Range_Select(uint32_t channel, uint32_t range) { Return_Data_Format = WR_REG_DATA_NOT_USE; ADS8674_SPI_Write_ProgramRegister(channel, range); } void ADS8674_Get_AUTO_RST_Mode_Data(void) { Return_Data_Format = WR_CMD_DATA; ADS8674_SPI_Write_CommandRegister(0x00); } void ADS8674_Get_Manual_Mode_Data(uint32_t channel) { Return_Data_Format = WR_CMD_DATA; ADS8674_SPI_Write_CommandRegister(channel); } uint32_t ADS8674_Read_CH(uint32_t channel) { // 1. send MAN_Ch_n command ADS8674_Get_Manual_Mode_Data(channel); ADS_DELAY(DELAY_TIME); // 2. send NO_OP command (0x0000), read data ADS8674_SPI_Write_CommandRegister(NO_OP); ADS_DELAY(DELAY_TIME); uint32_t ADC_Value = ((uint32_t)(ADS8674_rxBuf_4Byte[0] & 0x01) << 24) + ((ADS8674_rxBuf_4Byte[1]) << 16) + ((ADS8674_rxBuf_4Byte[2]) << 8) + ADS8674_rxBuf_4Byte[3]; return ADC_Value; } void ADS8674_Init(void) { ADS8674_SPI_Write_CommandRegister(STDBY); ADS_DELAY(DELAY_TIME); ADS8674_Set_Auto_Scan_Sequence(0x00); ADS_DELAY(DELAY_TIME); ADS8674_SPI_Write_ProgramRegister(Channel_Power_Down, 0); ADS_DELAY(DELAY_TIME); ADS8674_SPI_Write_ProgramRegister(Feature_Select, 0); ADS_DELAY(DELAY_TIME); ADS8674_Set_CH_Range_Select(Channel_0_Input_Range, VREF_0_25); ADS_DELAY(DELAY_TIME); ADS8674_Set_CH_Range_Select(Channel_1_Input_Range, VREF_0_25); ADS_DELAY(DELAY_TIME); ADS8674_Set_CH_Range_Select(Channel_2_Input_Range, VREF_0_25); ADS_DELAY(DELAY_TIME); ADS8674_Set_CH_Range_Select(Channel_3_Input_Range, VREF_0_25); ADS_DELAY(DELAY_TIME); }