文章目录
一、ADS8688模块简介
ADS8688是一款8通道集成数据采集系统,基于16位逐次逼近(SAR)模数转换器 (ADC),工作时的吞吐量可达500kSPS。器件提供了用于各输入通道的集成模拟前端电路(过压保护高达+20V)、支持自动和手动两种扫描模式的8通道多路复用器、以及低温度漂移的片上4.096V基准电压。采用5V单模拟电源供电时,器件上的各输入通道均可支持±10.24V、 ±5.12V和2.56V的实际双极输入范围以及0V到 10.24V和0V到5.12V的单极输入范围。模拟前端在所有输入范围内的增益均经过精确微调,以确保高直流精度。输入范围的选择可通过软件进行编程,各通道输入范围的选择相互独立。该器件提供了一个1M Ω的恒定阻性输入阻抗。
特性
- 分辨率:16位 SAR ADC
- 通道数:8 路单端输入通道(支持多种模拟量程)
- 支持自动和手动两种扫描模式的8通道多路复用器(MUX)
- 通道的可编程输入范围:
双极:±10.24V、±5.12V和±2.56V
单极:0V到10.24V和0V到5.12V - 供电电源:DC 5V
- 内部基准:4.096V 精密基准电压
- 接口:SPI接口
- 恒定的阻性输入阻抗:1MQ
- 500kSPS的总吐
- 差分非线性(DNL):±0.5最低有效位(LSB)
- 最大积分非线性(INL):±0.75LSB
- 信噪比(SNR):92dB
- 总谐波失真(THD): -102dB
- 低功耗:65mW
二、模块接口和引脚说明
RST | 复位引脚,低电平复位 |
---|---|
CS | SPI 片选 |
SDI | SPI 数据输入 |
SDO | SPI 数据输出 |
CLK | SPI 时钟输入 |
DAISY | 以菊花链模式链接串行通信期间的数据输入 |
简单说明,菊花链就是把多个 SPI 设备像一串项链那样串在一起,让主机用同一组时钟(SCLK)、主出数据(MOSI)和片选(CS)一次性把命令“推”进整串设备,同时一次性从整串读出它们的输出。好处是省线、接线简单;坏处是需要按“链序”拼装命令与解析数据,延迟和故障传播要注意。
用比喻理解,把每个 SPI 设备想像成一个移位寄存器,它有一个输入口(SDI / MOSI),一个输出口(SDO / MISO),当主机每打一位时,这个寄存器就“向右”推一位,最右边的位就从 SDO 输出。把多个这样的寄存器串起来(SDO₁ → SDI₂ → SDO₂ → SDI₃ …),就是菊花链。主机只需一套 MOSI / SCLK / CS 就能同时对整串设备“打包”发送/读取数据 —— 数据会在各设备间被逐位传递。
读写顺序记住这一句就够:“发送顺序 = 链尾 → … → 链首;读取顺序 = 链尾 → … → 链首。”
三、功能框图和时序图
其中下图为菊花链模式的连接示意和时序图,以及操作模式的转换图
四、ADC传递函数
ADS8688 为多通道器件,所有输入通道均支持单端、双极性和单极性输入范围。对于双极性和单极性输入范围,器件的输出均为标准二进制格式。所有模拟通道的输出代码格式相同。图 69 显示了每个 ADC 通道在所有输入范围内的理想传输特性。每个输入信号的满量程范围 (FSR) 等于正满量程 (PFS) 输入电压与负满量程 (NFS) 输入电压之差。由于 ADC 的分辨率为 16 位,因此 LSB 大小等于 FSR / 216 = FSR / 65536。对于参考电压 VREF = 4.096 V,表 4 列出了与不同输入范围对应的 LSB 值。
ADC 输出为 16 位无符号值,但表示的电压与配置的输入范围相关。ADC换算公式:
输入电压 = (ADC输出值-32767) x 量程 / 65535
例:若量程为 ±10.24V,对应范围为 20.48V,ADC 输出值为 65535 → 电压 = (65535-32767) × 20.48 / 65535 ≈ 10.24V,ADC 输出值为 0 → -10.24V;65535 → +10.24V,32768为中点码 = 0V 。注意:当量程为单极性时,则无需减去32767。
五、STM32F103驱动ADS8688模块采集信号
准备工作
STM32F103C8T6最小系统板、ADS8688 ADC采集模块、USB转TTL,输入信号源和导线若干。
引脚接线
STM32F103C8T6 | ADS8688 |
---|---|
外部DC 5V电源正 | VIN |
外部DC 5V电源负 | GND |
PA0 | SDI |
PA1 | RST |
PA2 | DAISY |
PA3 | CLK |
PA4 | CS |
PA5 | SDO |
PA9 | USB转TTL-RX |
PA10 | USB转TTL-TX |
代码示例
ads8688.c
/**********************************************************
本程序仅供学习使用,未经作者许可,不得用于其它任何用途
功能:ADS8688,16位AD
显示:12864cog
接口:接口请参照ads8688.h 可直接连接本店主控板TLV5608接口
时间:2020/12/13
版本:0.2
作者:康威电子
其他:本程序自做模块功能验证,以便快速测试模块好坏。
如需进行性能验证,请自行编程.更换高速MCU或FPGA实现高速采集!!!!
**********************************************************/
#include "stm32f10x.h"
#include "ads8688.h"
#include "delay.h"
/**********************************************************************************************************
* 函 数 名: ADS8688_IO_Init
* 功能说明: ADS8688 IO口初始化
* 形 参: 无
* 返 回 值: 无
**********************************************************************************************************/
void ADS8688_IO_Init(void) //ADS8688 IO口初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
DAISY_L;
CS_H;
RST_H;
CLK_L;
delay_ms(5);
}
/**********************************************************************************************************
* 函 数 名: ADS8688_Init
* 功能说明: ADS8688初始化
* 形 参: 无
* 返 回 值: 无
**********************************************************************************************************/
void ADS8688_Init(uint8_t ch_en) //ADS8688初始化
{
ADS8688_IO_Init();
SOFT_RESET(); //复位
delay_ms(25);
Set_Auto_Scan_Sequence(ch_en);//使能通道
ADS8688_WriteReg(CH_PD,~ch_en);//通道退出低功耗状态 通道上电
delay_ms(50);
while(ADS8688_ReadReg(AUTO_SEQ_EN)!=ch_en)//是否使能成功
{
Set_Auto_Scan_Sequence(ch_en);//使能通道
ADS8688_WriteReg(CH_PD,~ch_en);//通道退出低功耗状态 通道上电
delay_ms(50);
}
}
/**********************************************************************************************************
* 函 数 名: ADS8688_SPI_Read8Bit
* 功能说明: 从SPI总线读8个bit数据。 不带CS控制。
* 形 参: 无
* 返 回 值: 无
**********************************************************************************************************/
uint8_t ADS8688_SPI_Read8Bit(void)
{
uint8_t i=0;
uint8_t read=0;
for(i=0;i<8;i++)
{
read<<=1;
CLK_H;
delay_us(100);
if(READ_SDO) read++;
CLK_L;
delay_us(100);
}
return read;
}
/**********************************************************************************************************
* 函 数 名: ADS8688_SPI_Write8Bit
* 功能说明: 向SPI总线写8个bit数据。 不带CS控制。
* 形 参: data : 数据
* 返 回 值: 无
**********************************************************************************************************/
void ADS8688_SPI_Write8Bit(uint8_t data)
{
uint8_t i=0;
CS_L;
for(i=0;i<8;i++)
{
if(data&0x80) SDI_H;
else SDI_L;
data<<=1;
CLK_H;
delay_us(100);
CLK_L;
delay_us(100);
}
}
/**********************************************************************************************************
* 函 数 名: ADS8688_WriteCmd
* 功能说明: 写命令寄存器
* 形 参: cmd : 命令
* 返 回 值: 无
**********************************************************************************************************/
void ADS8688_WriteCmd(uint16_t cmd)//写ADS8688命令寄存器
{
CS_L;
ADS8688_SPI_Write8Bit(cmd>>8 & 0XFF);
ADS8688_SPI_Write8Bit(cmd & 0XFF);
ADS8688_SPI_Write8Bit(0X00);
ADS8688_SPI_Write8Bit(0X00);
CS_H;
}
/*
*********************************************************************************************************
* 函 数 名: SOFT_RESET
* 功能说明: 软件复位
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void SOFT_RESET(void)//软件复位
{
ADS8688_WriteCmd(RST);
}
/**********************************************************************************************************
* 函 数 名: AUTO_RST_Mode
* 功能说明: 自动模式
* 形 参: 无
* 返 回 值: 无
**********************************************************************************************************/
void AUTO_RST_Mode(void)//自动扫描模式
{
ADS8688_WriteCmd(AUTO_RST);
}
/**********************************************************************************************************
* 函 数 名: MAN_CH_Mode
* 功能说明: 手动模式通道选择
* 形 参: ch : 要选择的通道
* 返 回 值: 无
**********************************************************************************************************/
void MAN_CH_Mode(uint16_t ch)//手动模式
{
ADS8688_WriteCmd(ch);
}
/**********************************************************************************************************
* 函 数 名: ADS8688_ReadReg
* 功能说明: 读指定的寄存器
* 形 参: addr : 寄存器地址
* 返 回 值: data : 读到的寄存器值。
**********************************************************************************************************/
uint8_t ADS8688_ReadReg(uint8_t addr)
{
uint8_t data = 0;
CS_L;
ADS8688_SPI_Write8Bit(addr<<1);
data = ADS8688_SPI_Read8Bit();
data = ADS8688_SPI_Read8Bit();
CS_H;
return data;
}
/**********************************************************************************************************
* 函 数 名: ADS8688_WriteReg
* 功能说明: 写指定的寄存器
* 形 参: addr : 寄存器地址
* data : 寄存器值
* 返 回 值: 无
**********************************************************************************************************/
void ADS8688_WriteReg(uint8_t addr,uint8_t data)
{
CS_L;
ADS8688_SPI_Write8Bit(addr<<1| 0X01);
ADS8688_SPI_Write8Bit(data);
CS_H;
}
/**********************************************************************************************************
* 函 数 名: Set_Auto_Scan_Sequence
* 功能说明: 设置自动扫描序列通道
* 形 参: seq:需要设置自动扫描序列使能寄存器的值
* 返 回 值: 无
**********************************************************************************************************/
void Set_Auto_Scan_Sequence(uint8_t seq)
{
ADS8688_WriteReg(AUTO_SEQ_EN, seq);
}
/**********************************************************************************************************
* 函 数 名: Set_CH_Range
* 功能说明: 设置指定通道测量范围
* 形 参: ch : 通道
* range : 测量范围
* 返 回 值: 无
**********************************************************************************************************/
void Set_CH_Range(uint8_t ch,uint8_t range)
{
ADS8688_WriteReg(ch,range);
}
/**********************************************************************************************************
* 函 数 名: Get_AUTO_RST_Mode_Data
* 功能说明: 读取自动扫描模式AD值
* 形 参:data : 数据指针
* chnum : 通道个数
* 返 回 值: 无
**********************************************************************************************************/
void Get_AUTO_RST_Mode_Data(uint16_t *data, uint8_t chnum)
{
uint8_t i=0,datal=0,datah=0;
for (i=0; i<chnum; i++)
{
CS_L;
ADS8688_SPI_Write8Bit(0X00);
ADS8688_SPI_Write8Bit(0X00);
datah = ADS8688_SPI_Read8Bit();
datal = ADS8688_SPI_Read8Bit();
//delay_ms(1);
CS_H;
*(data+i) = datah<<8 | datal;
}
}
/**********************************************************************************************************
* 函 数 名: Get_MAN_CH_Mode_Data
* 功能说明: 读取手动模式AD值
* 形 参: 无
* 返 回 值: 无
**********************************************************************************************************/
uint16_t Get_MAN_CH_Mode_Data(void)
{
u8 datah=0,datal=0;
CS_L;
ADS8688_SPI_Write8Bit(0X00);
ADS8688_SPI_Write8Bit(0X00);
datah = ADS8688_SPI_Read8Bit();
datal = ADS8688_SPI_Read8Bit();
CS_H;
return (datah<<8 | datal);
}
main.c
/**********************************************************
本程序仅供学习使用,未经作者许可,不得用于其它任何用途
功能:ADS8688,16位AD 8通道自动扫描采集 使用芯片内部基准4.096V
显示:12864cog
接口:接口请参照ads8688.h 可直接连接本店主控板TLV5608接口
时间:2020/12/13
版本:0.2
作者:康威电子
其他:本程序只做模块功能验证,以便快速测试模块好坏。
如需进行性能验证,请自行编程.更换高速MCU或FPGA实现高速采集!!!!
当选择量程为双极性时,0V对应32767,因此V=(ADC值-32767)*量程/65535;当量程为单极性时,则无需减去32767。
**********************************************************/
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "usb_lib.h"
#include "math.h"
#include "hw_config.h"
#include "string.h"
#include "stdlib.h"
#include "ads8688.h"
/**********************************************************
* 函数功能 ---> USB连接/断开
* 入口参数 ---> usb_sw:USB开启/关闭控制。0:关闭
* 1:打开
* 返回数值 ---> none
* 功能说明 ---> none
**********************************************************/
void USB_Port_Set(u8 usb_sw)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PORTA时钟
if(usb_sw) _SetCNTR(_GetCNTR()&(~(1<<1)));//退出断电模式
else
{
_SetCNTR(_GetCNTR()|(1<<1)); // 断电模式
GPIOA->CRH &= 0XFFF00FFF;
GPIOA->CRH |= 0X00033000;
PAout(12) = 0;
}
}
int main(void)
{
uint8_t i=0;
char infoBackPC[64];
uint16_t value[9];
SystemInit();
delay_init(72); //延时初始化
uart_init(9600); //串口初始化
delay_ms(1000);
USB_Port_Set(0); //USB先断开
delay_ms(600);
USB_Port_Set(1); //USB再次连接
USB_Config();
ADS8688_Init(CH0_EN|CH1_EN|CH2_EN|CH3_EN|CH4_EN|CH5_EN|CH6_EN|CH7_EN);//ADS8688初始化
Set_CH_Range(CHIR_0,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_1,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_2,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_3,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_4,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_5,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_6,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_7,ADS8688_IR_N2_5V);//设置通道输入范围:±10.24V ±2.5*ref ref=4.096V
AUTO_RST_Mode();//进入自动扫描模式
while(1)
{
delay_ms(10);
//手动采集
// MAN_CH_Mode(MAN_CH_0);
// value[0]=Get_MAN_CH_Mode_Data();//读取通道数据,
// MAN_CH_Mode(MAN_CH_1);
// value[1]=Get_MAN_CH_Mode_Data();//读取通道数据
// MAN_CH_Mode(MAN_CH_2);
// value[2]=Get_MAN_CH_Mode_Data();//读取通道数据,
// MAN_CH_Mode(MAN_CH_3);
// value[3]=Get_MAN_CH_Mode_Data();//读取通道数据
// MAN_CH_Mode(MAN_CH_4);
// value[4]=Get_MAN_CH_Mode_Data();//读取通道数据,
// MAN_CH_Mode(MAN_CH_5);
// value[5]=Get_MAN_CH_Mode_Data();//读取通道数据
// MAN_CH_Mode(MAN_CH_6);
// value[6]=Get_MAN_CH_Mode_Data();//读取通道数据,
// MAN_CH_Mode(MAN_CH_7);
// value[7]=Get_MAN_CH_Mode_Data();//读取通道数据
// MAN_CH_Mode(MAN_AUX);
// value[8]=Get_MAN_CH_Mode_Data();//采集AUX通道 AUX电压=value[8]*4096/65535 此通道直接输入至ADC,无内部PGA,输入范围为0-4.096V。
//自动采集
Get_AUTO_RST_Mode_Data(value,8);//自动扫描模式,自动扫描并转换8通道。数据存在value数组中
for(i = 0; i < 4; i++)//发送
{
sprintf(infoBackPC, "AIN%d=%06dmV AIN%d=%06dmV ",i*2+1,(int16_t)((value[i*2]-32767)*CONST_N2_5V_LSB_mV),i*2+2,(int16_t)((value[i*2+1]-32767)*CONST_N2_5V_LSB_mV));
USB_TxWrite((uint8_t*)infoBackPC, strlen(infoBackPC)); //usb发送
printf("%s",infoBackPC); //串口发送
}
USB_TxWrite("\r\n", 2); //usb发送
printf("\r\n"); //串口发送
}
}
效果展示
IN1接GND,IN2接2.47V,IN3接3.31V,IN4接4.94V,IN5接-5.05V,IN6-8悬空。
六、常见问题和注意事项
常见问题:
Q:模块可测量负电压吗?
A:可以,当量程选择为双极性时,即可测量负电压。
Q:最大值是65535吗?怎样换算成电压?
A:是的,当选择量程为双极性时,0V对应32767,因此V=(ADC值-32767)* 量程/65535;当量程为单极性时;则无需减去32767。
Q:每个通道是否独立具有500KSPS数据更新率?
A:ADS8688的最大总吞吐量为500KSPS。每个通道的吞吐量取决于在多路复用器扫描序列中选择的通道数。如果仅选择两个通道,则每个通道的吞吐量等于250KSPS,如果选择了四个通道,则等于每个通 道125KSPS,依此类推。
Q:AUX与其他通道有什么区别?
A:AUX通道在芯片内部通过多路复用器直接与高精度16位ADC的连接;由于没有前端PGA,因此AUX通道仅支持0V至VREF的单极性输入范围。
Q:每个通道是否可独立配置输入范围?
A:ADS8688每个通道均有PGA,因此可独立配置输入范围与极性。
Q:比如给一个电压:2.1234V的一个电压让模块去一直采集,它的结果是怎样的?数值会跳动吗?
A:数据肯定是有跳动的,这个不是单一条件决定的,电源纹波噪声,线材过长等因素都会对其造成影响。
Q:ADS8688采集小电压信号不准,是什么情况?
A:可能是量程范围配置过大,可根据自己要采集的信号范围合理设置芯片量程范围(PGA)。
Q:模块正常驱动后,没有接电压的管脚显示也有电压,正常吗?
A:模块默认是8通道一直采集的,在没有接入电压的时候也会采集到管脚上的浮空电压,可将管脚直接接地,即为0电压。
注意事项:
(1)模块为低功耗模块,建议供电电源不超过5.25V。
(2)由于模块是高精度器件。为了避免不必要的干扰,建议使用线性电源供电。
(3)输入输出信号线建议尽量短,过长容易引入噪声信号。接触不良或劣质的线材可能导致信号衰减或者噪声过大。
(4)如需简单测试模块功能,建议搭配本店控制板使用,正确接线后给控制板供电即可实现信号采集显示。