基于STM32F103驱动ADS8688模块 8通道SAR/ADC数据采集信号


一、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复位引脚,低电平复位
CSSPI 片选
SDISPI 数据输入
SDOSPI 数据输出
CLKSPI 时钟输入
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,输入信号源和导线若干。

引脚接线

STM32F103C8T6ADS8688
外部DC 5V电源正VIN
外部DC 5V电源负GND
PA0SDI
PA1RST
PA2DAISY
PA3CLK
PA4CS
PA5SDO
PA9USB转TTL-RX
PA10USB转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)如需简单测试模块功能,建议搭配本店控制板使用,正确接线后给控制板供电即可实现信号采集显示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值