基于STM32F103驱动ADS8361 16位4通道 ADC模数转换模块采集单端/差分信号

基于STM32F103驱动ADS8361 16位4通道 ADC模数转换模块采集单端/差分信号 文章目录一、ADS8361 ADC模数转换器简介二、ADS8361模块接口说明三、ADS8361功能框图与时序说明四、输入信号与数据输出说明4.1 输入信号4.2 数据输出五、STM32F103驱动ADS8361采集信号准备工作接线说明代码示例效果展示六、注意事项与常见问题一、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.5VA0 1.5V采集到的电压为 -2.0V分辨率16位芯片最大采样率500ksps总吞吐量应用场景电机控制多轴定位系统三相电源控制等二、ADS8361模块接口说明CLOCK时钟输入。可以将外部 CMOS 兼容时钟信号施加到 CLOCK 输入端以使转换过程与外部信号源同步。CLOCK 引脚通过以下公式控制采样率fSAMPLE(max) CLOCK/20。CSSPI片选。当为低电平时串行输出 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。A0A0 与 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 的相位关系要求非常严格如果在不该切换的时间点去拉高/拉低 CONVSTADC 可能会不确定到底哪一个时钟开始转换。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)附近的双极性输入即AB通道输入0-5V输入不了负压信号。如果想要输入负压信号需要在输入接口外接运算放大器电路实现运算放大器电路可参考如下图4.2 数据输出数据的第一位是通道 0 或 1 的状态标志第二位是通道 A 或 B 的第二个状态标志。3-18位为输出数据由最高有效位 (MSB) 到最低有效位 (LSB) 的顺序排列19-20位为0。图8为理想数据换算。五、STM32F103驱动ADS8361采集信号准备工作STM32F103C8T6开发板ADS8361 16位ADC 模数转换器USB转TTL导线若干等。接线说明STM32F103C8T6ADS83615V5VGNDGNDPA0CLOCKPA1CSPA2RDPA3CONPA4M1PA5M0PA6A0PB0DAPB1DBPB10BUSYPA9USB转TTL - RXPA10USB转TTL - TX代码示例ADS8361.c#includestm32f10x.h#includeads8361.h#includedelay.h/********************************************************************************************************** * 函 数 名: ADS8361_IO_Init * 功能说明: ADS8361 IO口初始化 * 形 参: 无 * 返 回 值: 无 **********************************************************************************************************/voidADS8361_IO_Init(void)//ADS8361 IO口初始化{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//使能端口时钟GPIO_InitStructure.GPIO_PinGPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;GPIO_InitStructure.GPIO_ModeGPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStructure);GPIO_InitStructure.GPIO_PinGPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10;GPIO_InitStructure.GPIO_ModeGPIO_Mode_IPU;GPIO_Init(GPIOB,GPIO_InitStructure);CS1;//失能芯片 初始化CLOCK为低CLOCK0;RD0;CONVST0;}/********************************************************************************************************** * 函 数 名: ADS8361_Mode_selection * 功能说明: ADS8361模式选择 * 形 参: mode * 返 回 值: 无 **********************************************************************************************************/voidADS8361_Mode_selection(uint8_tmode)//ADS8361模式选择{switch(mode){caseMode_I:M00;M10;break;caseMode_II:M00;M11;break;caseMode_III:M01;M10;break;caseMode_IV:M01;M11;break;default:break;}}/********************************************************************************************************** * 函 数 名: ADS8361_Init * 功能说明: ADS8361初始化引脚并选择模式 * 形 参: mode * 返 回 值: 无 **********************************************************************************************************/voidADS8361_Init(uint8_tmode)//ADS8361初始化{ADS8361_IO_Init();delay_ms(10);ADS8361_Mode_selection(mode);delay_ms(10);}/********************************************************************************************************** * 函 数 名: ADS8361_ReadData * 功能说明: 读取ADS8361通道AB0或AB1数据(模式I)。不同模式时序请参考ADS8361芯片手册 * 形 参: A0_Select0选择通道A0,B0; A0_Select1时选择通道A1,B1 * 返 回 值: 无 **********************************************************************************************************/voidADS8361_ReadData(uint8_tA0_Select,uint16_t*data){u8 i0;CS0;//使能芯片CLOCK1;A0CH_AB0;//选择下一个转换周期的通道进行读取RD1;CONVST1;// 开始转换CLOCK0;CLOCK1;CLOCK0;CLOCK1;CLOCK0;// 前两个脉冲在模式I下并不起作用没有标志的用途// 所以忽略不读for(i0;i16;i)// 读取16位AD转换后的值高位在前所以每读一位是左移{data[2]1;data[3]1;CLOCK1;if(DATA_A){data[2];}//读取A1通道数据,下一个周期才是A0B0if(DATA_B){data[3];}//读取B1通道数据CLOCK0;}CLOCK1;CLOCK0;CLOCK1;CLOCK0;//补齐一个读写时序20位while(BUSY);// 等待转换周期完成RD0;// 准备下一次转换和读写CONVST0;// 准备下一次转换和读写}/********************************************************************************************************** * 函 数 名: ADS8361_Read_ALLData * 功能说明: 读取ADS8361所有通道数据(模式I) * 形 参: data:数据指针 * 返 回 值: 无 **********************************************************************************************************/voidADS8361_Read_ALLData(uint16_t*data){u8 i0;CS0;//使能芯片CLOCK1;A0CH_AB0;//选择下一个转换周期的通道进行读取RD1;CONVST1;// 开始转换CLOCK0;CLOCK1;CLOCK0;CLOCK1;CLOCK0;// 前两个脉冲在模式I下并不起作用没有标志的用途// 所以忽略不读for(i0;i16;i)// 读取16位AD转换后的值高位在前所以每读一位是左移{data[2]1;data[3]1;CLOCK1;if(DATA_A){data[2];}//读取A1通道数据,下一个周期才是A0B0if(DATA_B){data[3];}//读取B1通道数据CLOCK0;}CLOCK1;CLOCK0;CLOCK1;CLOCK0;//补齐一个读时序20位while(BUSY);// 等待转换周期完成RD0;// 准备下一次转换和读写CONVST0;// 准备下一次转换和读写CLOCK1;A0CH_AB1;// 选择通道进行读取RD1;CONVST1;// 开始转换CLOCK0;CLOCK1;CLOCK0;CLOCK1;CLOCK0;// 前两个脉冲在模式I下并不起作用没有标志的用途// 所以忽略不读for(i0;i16;i)// 读取16位AD转换后的值高位在前所以每读一位是左移{data[0]1;data[1]1;CLOCK1;if(DATA_A){data[0];}//读取A0通道数据if(DATA_B){data[1];}//读取B0通道数据CLOCK0;}CLOCK1;CLOCK0;CLOCK1;CLOCK0;//补齐一个读时序20位while(BUSY);// 等待转换周期完成RD0;// 准备下一次转换和读写CONVST0;// 准备下一次转换和读写}main.c#includesys.h#includeads8361.h#includedelay.h#includeusart.hintmain(void){uint8_ti0;charshowLcd[30];charinfoBackPC[64];uint16_tvalue[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(i0;i2;i)//发送{sprintf(infoBackPC,A%d%05dmV B%d%05dmV\r\n,i,(int16_t)(value[i*2])*ADS8361_LSB,i,(int16_t)(value[i*21])*ADS8361_LSB);usart_SendString(infoBackPC);}usart_SendString(\r\n);delay_ms(100);}}效果展示输入信号V A01.49A0-1.197 B02.515B0-1.807A11.197A1-1.807 B11.49B1-2.515注意输入浮空时电压不为0。六、注意事项与常见问题注意事项(1)模块为低功耗模块建议供电电源不超过5.25V。(2)由于模块是高精度器件为了避免不必要的干扰建议使用线性电源供电。(3)输入输出信号线建议尽量短过长容易引入噪声信号。接触不良或劣质的线材可能导致信号衰减或者噪声过大。(4)配送的代码仅为本店配套主控板使用程序注释完整不讲解程序宝贝详情展示以外的功能需要自行开发。(5)如需简单测试模块功能建议搭配本店控制板使用正确接线后给控制板供电即可实现信号采集显示。常见问题Q模块可输入负电压吗?A不可以输入口电压必须大于0V电压范围为0到5V差模电压范围不超过士VREF(±2.5V)即(IN) - (IN-)要在±2.5V以内。Q模块输出电压与ADC值的对应关系是什么?A0 - 32767对应0V - 2.5V32768 - 65535对应-2.5V - 0V。即十六进制0 - 7FFF对应0V - 2.5V8000 - FFFF对应-2.5V - 0VADS8361的ADC最高位为符号位。Q每个通道是否独立具有500kSPS数据更新率?AADS8361的最大总吞吐量为500kSPS。每个通道的吞吐量取决于读取选择的通道数。如果仅选择一个通道则通道的吞吐量等于 500kSPS如果选择了四个通道则等于每个通道125kSPS依此类推。Q提供的程序支持500kSPS的数据更新率吗?A提供的程序为软件模拟SPI通讯所以无法达到最大速度默认程序只做模块功能验证以便快速测试模块好坏。如需进行性能验证请参考芯片手册自行编程或更换高速MCU或FPGA实现高速采集。Q比如给一个电压2.1234V的一个电压让模块去一直采集它的结果是怎样的数值会跳动吗A数据肯定是有跳动的这个不是单一条件决定的电源纹波噪声线材过长等因素都会对其造成影响。Q模块正常驱动后没有接电压的管脚显示也有电压正常吗?A模块默认程序是4通道一直采集的在没有接入电压的时候也会采集到管脚上的浮空电压可将管脚直接接地即为0电压。