一、ADS8361 ADC模数转换器简介

  ADS8361是一款双通道、16位、500kSPS、模数(A/D)转换器,具有四个全差分输入通道,分为两对,用于高速同步信号采集。采样保持放大器的输入为全差分输入,并与A/D转换器的输入保持差分。这在50kHz时提供了80dB的出色共模抑制,这在高噪声环境中很重要。

特性参数

  • 模块供电:DC 5V
  • 静态功耗:30mA(仅供参考)
  • 通讯协议:SPI串行
  • 通讯电平:3.3V
  • 输入通道数:4个差分通道
  • 基准电压Vref:默认内部2.5V,可焊接SOT23封装的芯片外部输入基准
  • 输入口绝对电压:0-5V,即输入引脚电压必须大于0V
  • 采集范围:±Vref,即采集电压 = (IN +) - (IN -) ≤ ±2.5V,如A0- = 3.5V,A0+ = 1.5V,采集到的电压为 -2.0V
  • 分辨率:16位
  • 芯片最大采样率:500ksps(总吞吐量)

应用场景

  • 电机控制,多轴定位系统,三相电源控制等

二、ADS8361模块接口说明


CLOCK 时钟输入。可以将外部 CMOS 兼容时钟信号施加到 CLOCK 输入端,以使转换过程与外部信号源同步。CLOCK 引脚通过以下公式控制采样率:fSAMPLE(max)= CLOCK/20。
CS SPI片选。当为低电平时,串行输出 A 和串行输出 B 有效;当为高电平时,串行输出处于三态。
BUSY 转换指示.在转换过程中变为高电平,并在串行 A 或串行 B 输出引脚发送完第三个最低有效位 (LSB) 后返回低电平。
RD 串行输出同步脉冲
CONVST 转换开始。当 CONVST 从低电平变为高电平时,设备将从采样模式切换到保持模式,这与外部时钟的状态无关。
M1 用于选择串行输出。当 M1 为低电平时,串行输出 A 和串行输出 B 均被选中进行数据传输。当 M1为高电平时,串行输出 A 配置为同时传输通道 A 和通道 B 的数据;串行输出 B 进入三态(即高阻抗)。
M0 选择双通道或四通道操作模式。当 M0 为低电平时,选择双通道操作模式,并与 A0 协同工作。当 A0 为高电平时,转换通道 A1 和通道 B1。当 A0 为低电平时,转换通道 A0 和通道 B0。当 M0 为高电平时,选择四通道操作模式。在此模式下,所有四个通道按顺序转换,首先转换通道 A0 和 B0,然后转换通道 A1 和 B1。
A0 A0 与 M0 协同工作。当 M0 为低电平且 A0 为高电平时,通道 A1 和通道 B1 将被转换。当 M0 为低电平且 A0 为低电平时,通道 A0 和通道 B0 将被转换。
DATA_A 串行输出数据字由通道信息和 16 位数据组成。工作时,数据在 DCLOCK 的下降沿有效,持续 20 个边沿,从 RD 的上升沿开始计算。当 M1 为高电平时,通道 A 和通道 B 的数据均可用。
DATA_B 串行输出数据字由通道信息和 16 位数据组成。工作时,数据在 DCLOCK 的下降沿有效,持续 20 个边沿,从 RD 的上升沿开始。

三、ADS8361功能框图与时序说明

  ADS8361 是一款高速、低功耗的双通道 16 位模数转换器 (A/D 转换器),输入通道均为全差分输入,典型共模抑制比为 80dB。ADS8361包含了一个双路 4μs 逐次逼近型 A/D 转换器、两个差分采样保持放大器、一个带有 REFIN 和 REFOUT 引脚的内部 +2.5V 基准电压源以及一个高速串行接口。ADS8361 需要外部时钟。为了达到 500kSPS 的最大吞吐量,主时钟频率必须设置为 10MHz。每次 16 位转换至少需要 20 个时钟周期。功能框图如下:

时序特性如下:


  ADS8361 具有四个模拟输入,分为两个通道(A 和 B)。通道选择由 M0、M1和 A0控制。每个通道有两个输入端(A0、A1 和 B0、B1),它们同时进行采样和转换,从而保留两个模拟输入端信号的相对相位信息。所有转换均通过将 CONVST 引脚拉高至少 15ns 来在 ADS8361 上启动。CONVST 拉高会使两个采样保持放大器同时进入保持状态,并在两个通道上启动转换过程。RD 引脚可以连接到 CONVST 以简化操作。根据 M0、M1 和 A0 引脚的状态,ADS8361 将 (a) 工作在双通道或四通道模式,并且 (b) 同时在串行 A 和串行 B 输出端口输出数据,或者仅通过串行 A 输出端口传输两个通道的数据。

  ADS8361 通过地址引脚 M0、M1和 A0配置为四种不同的工作模式,而M0则用于选择双通道或四通道工作模式。
    在双通道工作模式下,A0 用于选择通道 0 和通道 1;
    在四通道工作模式下,A0 引脚将被忽略,通道会在每次转换后自动切换。
  M1用于选择串行数据是同时通过串行 A 数据输出和串行 B 数据输出传输,还是两个通道都通过串行 A 端口输出数据。模式选择如下:

模式 I (M0 = 0, M1 = 0)
  当 M0 和 M1均设置为0时,ADS8361 将以双通道模式运行(必须使用 A0 引脚在通道 A 和 B 之间切换)。通过将 CONVST 置高至少 15ns 来启动转换。非常重要的一点是,CONVST 必须在外部时钟下降沿之前至少 10ns 或在下降沿之后至少 5ns 置高。如果在此时间范围内将 CONVST 置高,则无法确定 ADS8361 何时启动转换。执行一次转换需要 20 个时钟周期。CONVST 置高后,ADS8361 将立即从采样模式切换到保持模式,该切换与外部时钟异步。 BUSY 输出随后将变为高电平,并在整个转换周期内保持高电平。在外部时钟第一个周期的下降沿,ADS8361 根据 A0的状态(高电平 = 通道 1,低电平 = 通道 0)锁存下一个转换周期的地址。该地址必须在外部时钟第一个周期的下降沿之前 15ns 选择,并在时钟沿之后保持 15ns。为了获得最大吞吐量,CONVST 和 RD 引脚应连接在一起。必须将 CS 拉低才能使能 CONVST 和 RD 输入。数据在每个转换的 20 个时钟周期的下降沿都有效。数据的第一位是通道 0 或 1 的状态标志,第二位是通道 A 或 B 的第二个状态标志。在模式 I 中,第一位和第二位均为 0。后续数据将按最高有效位 (MSB) 到最低有效位 (LSB) 的顺序排列,最后两位为0。

模式 II (M0 = 0, M1 = 1)
  当 M1 设置为1时,ADS8361 仅通过串行数据 A 引脚输出数据。除串行数据 B 输出在 M1 变为高电平后进行转换后会变为三态(即高阻抗)外,所有其他引脚的功能与模式 I 相同。此模式的另一个区别在于 CONVST 。由于输出两个 A/D 转换器的结果需要 40 个时钟周期(而不是 M1 = 0 时的 20 个时钟周期),因此 ADS8361 需要 4μs 才能完成两个 A/D 转换器的转换。

模式 III (M0 = 1, M1 = 0)
  当 M0 设置为1时,ADS8361 将依次循环遍历通道 0 和通道 1(忽略 A0 引脚)。同时,将 M1 设置为0会使串行输出 A 和 B 都处于有效状态。

模式 IV (M0 = 1, M1 = 1)
  与模式 II 类似,模式 IV 仅使用串行 A 输出线传输数据。在 M1 变为高电平后的第一次转换之后,串行 B 输出将进入三态。与模式 II 一样,当 M1 = 1 时,第二个 CONVST 命令始终被忽略。

  最后读取数据,在所有四个时序图中,CONVST 和 RD 连接在一起。如果需要,可以将这两条线分开。串行输出(A 和 B)上的数据将在 RD 上升沿之后的第三个 SCLK 上升沿之后生效。

注意:
  ADS8361 的 CONVST(启动转换)信号,和外部时钟 CLOCK 的相位关系要求非常严格,如果在不该切换的时间点去拉高/拉低 CONVST,ADC 可能会不确定到底哪一个时钟开始转换。ADS8361 是同步采样 ADC,有外部 CLOCK和CONVST 启动信号。但真正开始转换,不是 CONVST 一来立刻开始。而是ADC 会等到 CLOCK 的某个上升沿才正式开始转换。

  什么时候开始转换如下图所示,其核心意思是ADC 内部需要判断:这个 CONVST 属于哪个时钟周期?但如果:CONVST 恰好出现在 CLOCK 边沿附近,ADC 内部触发器可能会:有时认为属于当前周期,有时认为属于下一周期。于是,转换开始时间不确定,这就是所谓时序竞争。

  如何确定CONVST 属于哪个时钟周期,官方手册把 CLOCK 周期分成了:A区,B区,C区,ADC 在CLOCK 上升沿真正触发转换,主要看CONVST。
  A区:CONVST 在 cycle1 前一个下降沿之前 10ns以上 到达,那么就在cycle1上升沿开始转换。即在D1下降沿前的t1以上时间,CONVST到达,那么就在cycle1上升沿开始转换。
  B区:CONVST 出现在cycle1 前下降沿后 5ns到 cycle2 前下降沿前 10ns,那么就在cycle2上升沿开始转换。即D1下降沿后t2时间到D2下降沿前10ns范围内,CONVST到达,那么就在cycle2上升沿开始转换。
  C区:CONVST 更晚,即cycle2 下降沿后 5ns,则继续往后推。

  最危险的是灰色区域:官方手册强调,CONVST 不要在 CLOCK 下降沿附近切换,即t1到t2范围内。因为ADC 内部触发器建立保持时间不满足会出现亚稳态,结果:ADC 有时当前周期启动,有时下一周期启动,于是采样时间抖动,这对高速采样非常致命。

四、输入信号与数据输出说明

4.1 输入信号

ADS8361 的模拟输入有两种常见的驱动方式:单端输入或差分输入。
  单端输入时,-IN 输入保持在共模电压。+IN 输入围绕该共模电压摆动,峰峰值幅度为(共模电压 + VREF))和 (共模电压 – VREF)。VREF 的值决定了共模电压的变化范围。
  差分输入时,输入幅度为 +IN 和 -IN 输入之差,即 (+IN) – (-IN)。每个输入的峰峰值幅度围绕该共模电压在 ±1/2 VREF 范围内变化。然而,由于输入相位相差 180°,差分电压的峰峰值幅度为 +VREF 到 -VREF。 VREF 的值还决定了两个输入端可能共有的电压范围。

  ADS8361 的差分输入可接受内部参考电压 (2.5V) 附近的双极性输入(-VREF 和 +VREF),对应于 0V 至 5V 的输入范围(参考电压为 2.5V)。也可以通过使用包含单个放大器和四个外部电阻的简单运算放大器电路,将 ADS8361 配置为接受双极性输入,传统的 ±2.5V、±5V 和 ±10V 的输入范围。

  注意:店铺售卖的模块的模拟输入范围是基于内部参考电压 (2.5V)附近的双极性输入,即A,B通道输入0-5V,输入不了负压信号。

  如果想要输入负压信号,需要在输入接口外接运算放大器电路实现,运算放大器电路可参考如下图:

4.2 数据输出

  数据的第一位是通道 0 或 1 的状态标志,第二位是通道 A 或 B 的第二个状态标志。3-18位为输出数据,由最高有效位 (MSB) 到最低有效位 (LSB) 的顺序排列,19-20位为0。图8为理想数据换算。


五、STM32F103驱动ADS8361采集信号

准备工作

  STM32F103C8T6开发板,ADS8361 16位ADC 模数转换器,USB转TTL,导线若干等。

接线说明

STM32F103C8T6 ADS8361
5V 5V
GND GND
PA0 CLOCK
PA1 CS
PA2 RD
PA3 CON
PA4 M1
PA5 M0
PA6 A0
PB0 DA
PB1 DB
PB10 BUSY
PA9 USB转TTL -> RX
PA10 USB转TTL -> TX

代码示例

ADS8361.c

#include "stm32f10x.h"
#include "ads8361.h"
#include "delay.h"

/**********************************************************************************************************
*	函 数 名: ADS8361_IO_Init
*	功能说明: ADS8361 IO口初始化
*	形    参: 无
*	返 回 值: 无
**********************************************************************************************************/
void ADS8361_IO_Init(void)	   //ADS8361 IO口初始化
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);	 //使能端口时钟

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;				 
	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_0|GPIO_Pin_1|GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	CS=1;  //失能芯片 初始化CLOCK为低
  CLOCK=0;
	RD=0;          
  CONVST=0; 
}

/**********************************************************************************************************
*	函 数 名: ADS8361_Mode_selection
*	功能说明: ADS8361模式选择
*	形    参: mode
*	返 回 值: 无
**********************************************************************************************************/
void ADS8361_Mode_selection(uint8_t mode)//ADS8361模式选择
{
	switch(mode)
  {
    case Mode_I:	M0 = 0; M1 = 0;
      break;
		case Mode_II:	M0 = 0; M1 = 1;
      break;
		case Mode_III:M0 = 1; M1 = 0;
      break;
		case Mode_IV:	M0 = 1; M1 = 1;
      break;
    default:
      break;
  }
}

/**********************************************************************************************************
*	函 数 名: ADS8361_Init
*	功能说明: ADS8361初始化引脚并选择模式
*	形    参: mode
*	返 回 值: 无
**********************************************************************************************************/
void ADS8361_Init(uint8_t mode)	   //ADS8361初始化
{
	ADS8361_IO_Init();
	delay_ms(10);
	ADS8361_Mode_selection(mode);
	delay_ms(10);
}

/**********************************************************************************************************
*	函 数 名: ADS8361_ReadData
*	功能说明: 读取ADS8361通道AB0或AB1数据(模式I)。不同模式时序请参考ADS8361芯片手册!!!
*	形    参: A0_Select=0选择通道A0,B0; A0_Select=1时选择通道A1,B1
*	返 回 值: 无
**********************************************************************************************************/
void ADS8361_ReadData(uint8_t A0_Select,uint16_t *data)
{
  u8 i = 0;	
  
	CS=0;  	//使能芯片
	CLOCK=1;
	A0=CH_AB0; //选择下一个转换周期的通道进行读取
	RD=1;  
	CONVST=1;  // 开始转换
	CLOCK=0;

	CLOCK=1;
	CLOCK=0;
	CLOCK=1;
	CLOCK=0;// 前两个脉冲在模式I下并不起作用没有标志的用途// 所以忽略不读
								
	for(i=0;i<16;i++)  // 读取16位AD转换后的值,高位在前,所以每读一位是左移
	{
		data[2] <<= 1;
		data[3] <<= 1;
		CLOCK=1;
		if(DATA_A){data[2]++;}//读取A1通道数据,下一个周期才是A0B0
		if(DATA_B){data[3]++;}//读取B1通道数据
		CLOCK=0;
	}
	CLOCK=1;
	CLOCK=0;
	CLOCK=1;
	CLOCK=0;//补齐一个读写时序20位
	
	while(BUSY);  // 等待转换周期完成

	RD=0;         // 准备下一次转换和读写
	CONVST=0;     // 准备下一次转换和读写
	
}


/**********************************************************************************************************
*	函 数 名: ADS8361_Read_ALLData
*	功能说明: 读取ADS8361所有通道数据(模式I)
*	形    参: data:数据指针
*	返 回 值: 无
**********************************************************************************************************/

void ADS8361_Read_ALLData(uint16_t *data)
{
	u8 i = 0;	
	
	CS=0;  	//使能芯片
	CLOCK=1;
	A0=CH_AB0; //选择下一个转换周期的通道进行读取
	RD=1;  
	CONVST=1;  // 开始转换
	CLOCK=0;

	CLOCK=1;
	CLOCK=0;
	CLOCK=1;
	CLOCK=0;// 前两个脉冲在模式I下并不起作用没有标志的用途// 所以忽略不读
								
	for(i=0;i<16;i++)  // 读取16位AD转换后的值,高位在前,所以每读一位是左移
	{
		data[2] <<= 1;
		data[3] <<= 1;
		CLOCK=1;
		if(DATA_A){data[2]++;}//读取A1通道数据,下一个周期才是A0B0
		if(DATA_B){data[3]++;}//读取B1通道数据
		CLOCK=0;
	}
	CLOCK=1;
	CLOCK=0;
	CLOCK=1;
	CLOCK=0;//补齐一个读时序20位
	
	while(BUSY);  // 等待转换周期完成

	RD=0;         // 准备下一次转换和读写
	CONVST=0;     // 准备下一次转换和读写
	
	CLOCK=1;
	A0=CH_AB1; // 选择通道进行读取

	RD=1;  
	CONVST=1;  // 开始转换
	CLOCK=0;

	CLOCK=1;
	CLOCK=0;
	CLOCK=1;
	CLOCK=0;// 前两个脉冲在模式I下并不起作用没有标志的用途// 所以忽略不读
                                 
	for(i=0;i<16;i++)  // 读取16位AD转换后的值,高位在前,所以每读一位是左移
	{
		data[0] <<= 1;
		data[1] <<= 1;
		CLOCK=1;
		if(DATA_A){data[0]++;}//读取A0通道数据
		if(DATA_B){data[1]++;}//读取B0通道数据
		CLOCK=0;
	}
	CLOCK=1;
	CLOCK=0;
	CLOCK=1;
	CLOCK=0;//补齐一个读时序20位
	
	while(BUSY);  // 等待转换周期完成

	RD=0;         // 准备下一次转换和读写
	CONVST=0;     // 准备下一次转换和读写
}

main.c

#include "sys.h"
#include "ads8361.h"
#include "delay.h"
#include "usart.h"

int main(void)
{
	uint8_t i=0;
	char showLcd[30];
	char infoBackPC[64];
	uint16_t value[4];
	
	SystemInit();
	delay_init();	     //延时初始化
	usart_Init(115200);   //串口初始化
	delay_ms(100);
	
	ADS8361_Init(Mode_I);
	usart_SendString("ADS8361\r\n");
	
	while(1)
	{
		ADS8361_Read_ALLData(value);//读取数据
		
		for(i = 0; i <2; i++)//发送
		{
			sprintf(infoBackPC, "A%d=%05dmV  B%d=%05dmV\r\n",i,(int16_t)(value[i*2])*ADS8361_LSB,i,(int16_t)(value[i*2+1])*ADS8361_LSB);			
			usart_SendString(infoBackPC);
		}
		
		usart_SendString("\r\n");

		delay_ms(100);
	}
}

效果展示

输入信号(V): A0+:1.49,A0-:1.197; B0+:2.515,B0-:1.807
        A1+:1.197,A1-:1.807; B1+:1.49,B1-:2.515
注意:输入浮空时,电压不为0。

六、注意事项与常见问题

注意事项:
  (1)模块为低功耗模块,建议供电电源不超过5.25V。
  (2)由于模块是高精度器件,为了避免不必要的干扰,建议使用线性电源供电。
  (3)输入输出信号线建议尽量短,过长容易引入噪声信号。接触不良或劣质的线材可能导致信号衰减或者噪声过大。
  (4)配送的代码仅为本店配套主控板使用,程序注释完整,不讲解程序,宝贝详情展示以外的功能需要自行开发。
  (5)如需简单测试模块功能,建议搭配本店控制板使用,正确接线后给控制板供电即可实现信号采集显示。

常见问题
  Q:模块可输入负电压吗?
  A:不可以,输入口电压必须大于0V,电压范围为0到5V,差模电压范围不超过士VREF(±2.5V),即(IN+) - (IN-)要在±2.5V以内。

  Q:模块输出电压与ADC值的对应关系是什么?
  A:0 - 32767对应0V - 2.5V;32768 - 65535对应-2.5V - 0V。即十六进制0 - 7FFF对应0V - 2.5V;8000 - FFFF对应-2.5V - 0V,ADS8361的ADC最高位为符号位。

  Q:每个通道是否独立具有500kSPS数据更新率?
  A:ADS8361的最大总吞吐量为500kSPS。每个通道的吞吐量取决于读取选择的通道数。如果仅选择一个通道,则通道的吞吐量等于 500kSPS,如果选择了四个通道,则等于每个通道125kSPS,依此类推。

  Q:提供的程序支持500kSPS的数据更新率吗?
  A:提供的程序为软件模拟SPI通讯,所以无法达到最大速度;默认程序只做模块功能验证,以便快速测试模块好坏。如需进行性能验证,请参考芯片手册自行编程或更换高速MCU或FPGA实现高速采集。

  Q:比如给一个电压:2.1234V的一个电压让模块去一直采集,它的结果是怎样的?数值会跳动吗?
  A:数据肯定是有跳动的,这个不是单一条件决定的,电源纹波噪声,线材过长等因素都会对其造成影响。

  Q:模块正常驱动后,没有接电压的管脚显示也有电压,正常吗?
  A:模块默认程序是4通道一直采集的,在没有接入电压的时候也会采集到管脚上的浮空电压,可将管脚直接接地,即为0电压。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐