STM32F407-基于AD7606进行多路数据采集

本文介绍AD7606模数转换器的配置流程,包括管脚定义、过采样模式设置、复位及转换启动方法。还提供了STM32平台上的具体配置实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.原理图

2.管脚定义

2.1 OS2,OS1,OS0

查阅数据手册

 这三个管脚组合控制过采样模式。

  • 000 表示无过采样,最大 200Ksps 采样速率。
  • 001 表示 2 倍过采样, 也就是硬件内部采集 2 个样本求平均。
  • 010 表示 4 倍过采样, 也就是硬件内部采集 4 个样本求平均。
  • 011 表示 8 倍过采样, 也就是硬件内部采集 8 个样本求平均。
  • 100 表示 16 倍过采样, 也就是硬件内部采集 16 个样本求平均。
  • 101 表示 32 倍过采样, 也就是硬件内部采集 32 个样本求平均。
  • 110 表示 64 倍过采样, 也就是硬件内部采集 64 个样本求平均。

过采样倍率越高,ADC 转换时间越长,可得到的最大采样频率就越低。

2.2 CONVSTA/B

转换开始输入A和转换开始输入B。逻辑输入。这些逻辑输入用来启动模拟输入通道转换。要对所有输入通道同时采样,可以将CONVST A和CONVSTB短接在一起,并施加一个转换开始信号。或者,可以用CONVST A启动以下通道的同步采样:AD7606的V1、V2、V3和V4;AD7606-6的V1、V2和V3;AD7606-4的V1和V2。可以用CONVSTB启动对其它模拟输入通道的同步采样:AD7606的V5、V6、V7和V8;AD7606-6的V4、V5和V6;AD7606-4的V3和V4。这只有在过采样未开启时才可行。当CONVST A或CONVSTB引脚从低电平变为高电平时,相应模拟输入的前端采样保持电路被设置为保持。这两个管脚可以并联,我用的AD7606-6,其中CONVSTA 决定 1-3 通道,CONVSTB 决定 4-6 通道。2 个信号可以错开短暂的时间。 这里只用到了5个输入通道。

2.3 RANGE

模拟输入范围选择。逻辑输入。此引脚的极性决定模拟输入通道的输入范围。如果此引脚与逻辑高电平相连,则所有通道的模拟输入范围为±10 V。如果此引脚与逻辑低电平相连,则所有通道的模拟输入范围为±5 V。此引脚的逻辑状态改变会立即影响模拟输入范围。对于快速吞吐速率应用,转换期间建议不要更改此引脚的逻辑状态。详细信息请参见"模拟输入"部分。我用的板子设计的是用VDRIVE控制,VDRIVE为高电平就表示用的10V量程。

2.4 ADRD :

读信号。选择并行接口时为并行数据读取控制输入(RD)/选择串行接口时为串行时钟输入(SCLK)。在并行模式下,如果CS和RD均处于逻辑低电平,则会启用输出总线。在串行模式下,此引脚用作数据传输的串行时钟输入。CS下降沿使数据输出线路DourA和DouB脱离三态,并逐个输出转换结果的MSB。SCLK上升沿将随后的所有数据位逐个送至串行数据输出DouA和DouB。

2.5 ADRESET:

复位信号。当设置为逻辑高电平时,RESET上升沿复位AD7606/AD7606-6/AD7606-4。器件应该在上电后收到一个RESET脉冲。RESET高脉冲宽度典型值为50ns。如果在转换期间施加RESET脉冲,转换将中断。如果在读取期间施加RESET脉冲,输出寄存器的内容将复位至全0。

2.6 ADBUSY :

忙信号。CONVST A和CONVST B均达到上升沿之后,此引脚变为逻辑高电平,表示转换过程已开始。BUSY输出保持高电平,直到所有通道的转换过程完成为止。BUSY下降沿表示转换数据正被锁存至输出数据寄存器,经过时间t,之后便可供读取。在BUSY为 高电平时执行的数据读取操作应当在BUSY下降沿之前完成。当BUSY信号为高电平时,CONVST A或CONVST B的上升沿不起作用。

2.7 ADCS :

片选信号。此低电平有效逻辑输入使能数据帧传输。在并行模式下,如果CS和RD均处于逻辑低电平,则会使能输出总线DB[15:0],使转换结果输出在并行数据总线上。在串行模式下,利用Cs使能串行数据帧传输,并逐个输出串行输出数据的最高有效位(MSB)。

2.8 FRSTDATA

数字输出。FRSTDATA输出信号指示何时在并行、字节或串行接口上回读第-通道V1。当CS输入为高电平时,FRSTDATA输 出引脚处于三态。CS下降沿使FRSTDATA脱离三态。在并行模式下,与V1结果相对应的RD下降沿随后将FRSTDATA引脚设为高电平,表示输出数据总线可以提供V1的结果。在RD的下一个下降沿之后,FRSTDATA输出恢复逻辑低电平。在串行模式下,FRSTDATA在CS下降沿变为高.电平,因为此时将在DourA上输出V1的MSB。在CS 下降沿之后的第16个SCLK下降沿,它恢复低电平。

2.9 DB0-DB15 

数据总线。

并行输出数据位DB6至DB0:

当PAR/SER/BYTE SEL = 0时,这些引脚充当三态并行数字输入/输出引脚。当PARCS和RD均处于低电平时,这些引脚用来输出转换结果的DB6至DB0。当PAR/SER/BYTE SEL = 1时,这些引脚应与AGND相连。当工作在并行字节接口模式时,DB[7:0]通 过2个RD操作输出16位转换结果。DB7(引脚24)为MSB,DB0为LSB。逻辑电源输入。此引脚的电源电压(2.3 V至5.25 V)决定逻辑接口的工作电压。此引脚的标称电源与主机接口(即DSP和FPGA)电源相同。


并行输出数据位7(DB7)/串行接口数据输出引脚(DouA):
当PAR/SER/BYTE SEL = 0时,此引脚充当三态并行数字输入/输出引脚。当CS和RD均处于低电平时,此引脚用来输出转换结果的DB7。当PAR/SER/BYTE SEL= 1时,此引脚用作DouA,并输出串行转换数据,当工作在并行字节模式时,DB7为该字节的MSB。

并行输出数据位8(DB8)/串行接口数据输出引脚DO_B):

当PAR/SER/BYTESEL= 0时,此引脚充当三态并行数字输入/输出引脚。当CS和RD均处于低电平时,此引脚用来输出转换结果的DB8。当PAR/SER/BYTE SEL= 1时,此引脚用作Dou B,并输出串行转换数据。


并行输出数据位DB13至DB9:

当PAR/SER/BYTESEL= 0时,这些引脚充当三态并行数字输入/输出引脚。当CS和RD均处于低电平时,这些引脚用来输出转换结果的DB13至DB9。当PAR/SER/BYTESEL= 1时,这些引脚应与AGND相连。


并行输出数据位14 (DB14)/高字节使能(HBEN):

当PAR/SER/BYTE SEL = 0时,此引脚充当三态并行数字输出引脚。当CS和RD均处于低电平时,此引脚用来输出转换结果的DB14。当PAR/SER/BYTE SEL = 1且DB15/BYTESEL = 1时,AD7606/ AD7606-6/AD7606-4.工作在并行字节接口模式。在并行字节模式下,HBEN引脚用来选择是首先输出转换结果的高字节(MSB)还是低字节(LSB)。当HBEN= 1时,首先输出MSB,然后输出LSB。当HBEN= 0时,首先输出LSB,然后输出MSB。

并行输出数据位15(DB15)/并行字节模式选择(BYTESEL):

 当PAR/SER/BYTE SEL = 0时,此引脚充当三态并行数字输出引脚。当CS和RD均处于低电平时,此引脚用来输出转换结果的DB15。当PAR/SER/BYTESEL= 1时,BYTE SEL引脚用来在串行接口模式与并行字节接口模式之间做出选择。当PAR/SER/BYTE SEL = 1且DB15/BYTE SEL = 0时,AD7606工作在串行接口模式。当PAR/SER/BYTE SEL = 1且DB15/BYTE SEL= 1时,AD7606工作在并行字节接口模式。

2.10 V1-V6

模拟输入,此引脚为单端模拟输入,此通道的模拟输入范围由 RANGE 引脚决定。

3. 时序图

3.1 转换时序

t5:

CONVST A 和 CONVST B 上升沿之间最大允许的延迟时间。一般是用一根控制线同时控制CONVST A 和 CONVST B,因此可以不用管这个时间。

t3 :

最短的 CONVST A/B 电平脉冲,最小值 25ns。

t4 :

BUSY 下降沿到 CS 下降沿设置时间,最小值 0ns,所以可以忽略。

tCYCLE:

并行模式,无过采样,转换后并读取数据的最大值是 5us,即最高支持的时钟速度是 20MHz 及其以上。

tCONV :

转换时间。

3.2 驱动时序

t8 :

CS 到 RD 的设置时间,最小值是 0ns,可以忽略。

t10 :

RD 读信号的低电平脉冲宽度,通信电压不同,时间不同。对于 STM32 来说,FMC 通信电平一般是3.3V,即最小值 21ns。

t11 :

RD 高电平脉冲宽度,最小值 15ns。

t9 :

CS 到 RD 保持时间,最小值 0ns,可以忽略。

4.配置过程

4.1 IO配置

void AD7606_CtrlLinesConfig(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	/* 使能FSMC时钟 */
	RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);

	/* 使能 GPIO时钟,数据总线 */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG, ENABLE);

	//7管脚GPIOD
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
																GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10  | GPIO_Pin_14 | 
																GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource4 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource5 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FSMC);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
	                            GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
	                            GPIO_Pin_15;
	GPIO_Init(GPIOE, &GPIO_InitStructure);

	{
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOE, ENABLE);

		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
		GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
		GPIO_Init(GPIOD, &GPIO_InitStructure);

		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
		GPIO_Init(GPIOE, &GPIO_InitStructure);
		
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
		GPIO_Init(GPIOF, &GPIO_InitStructure);
	}
}

4.2 FSCM访问时序

AD7606规格书要求(3.3V时):RD读信号低电平脉冲宽度最短21ns,高电平脉冲最短宽度15ns。

 按照如下配置读数均正常。为了和同BANK的配置相同,选择3-0-6-1-0-0
        3-0-5-1-0-0 : RD高持续75ns, 低电平持续50ns.  1us以内可读取8路样本数据到内存。
        1-0-1-1-0-0 : RD高75ns,低电平执行12ns左右,下降沿差不多也12ns.  数据读取正确。

采用A模式

	fsmcStructure.FSMC_AddressSetupTime = 3;
	fsmcStructure.FSMC_AddressHoldTime = 0;
	fsmcStructure.FSMC_DataSetupTime = 6;
	fsmcStructure.FSMC_BusTurnAroundDuration = 1;
	fsmcStructure.FSMC_CLKDivision = 0;
	fsmcStructure.FSMC_DataLatency = 0;
	fsmcStructure.FSMC_AccessMode = FSMC_AccessMode_A;
	init.FSMC_Bank = FSMC_Bank1_NORSRAM4;
	init.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
	init.FSMC_MemoryType = FSMC_MemoryType_SRAM;
	init.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
	init.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
	init.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
	init.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
	init.FSMC_WrapMode = FSMC_WrapMode_Disable;
	init.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
	init.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
	init.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
	init.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
	init.FSMC_WriteBurst = FSMC_WriteBurst_Disable;

	init.FSMC_ReadWriteTimingStruct = &timing;
	init.FSMC_WriteTimingStruct = &timing;

	FSMC_NORSRAMInit(&init);

	FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);

4.3 过采样配置

void AD7606_SetOS(uint8_t _ucOS) 
{ 
g_tAD7606.ucOS = _ucOS; 
switch (_ucOS) 
{ 
case AD_OS_X2: 
OS2_0(); 
OS1_0(); 
OS0_1(); 
break; 
case AD_OS_X4: 
OS2_0(); 
OS1_1(); 
OS0_0(); 
break; 
case AD_OS_X8:
OS2_0(); 
OS1_1(); 
OS0_1(); 
break; 
case AD_OS_X16: 
OS2_1(); 
OS1_0(); 
OS0_0(); 
break; 
case AD_OS_X32: 
OS2_1(); 
OS1_0(); 
OS0_1(); 
break; 
case AD_OS_X64: 
OS2_1(); 
OS1_1(); 
OS0_0(); 
break; 
case AD_OS_NO: 
default: 
g_tAD7606.ucOS = AD_OS_NO; 
OS2_0(); 
OS1_0(); 
OS0_0(); 
break; 
} 
} 

4.4 复位函数

void AD7606_Reset(void)
{
	RESET_0();	/* 退出复位状态 */

	RESET_1();	/* 进入复位状态 */
	RESET_1();	/* 仅用于延迟。 RESET复位高电平脉冲宽度最小50ns。 */
	RESET_1();
	RESET_1();

	RESET_0();	/* 退出复位状态 */
}

4.5 开启转换

void AD7606_StartConvst(void)
{
	CONVST_0();
	CONVST_0();
	CONVST_0();

	CONVST_1();
}

4.6 读取函数

void AD7606_ReadNowAdc(void)
{
	g_tAD7606.sNowAdc[0] = AD7606_RESULT();	/* 读第1路样本 */
	g_tAD7606.sNowAdc[1] = AD7606_RESULT();	/* 读第2路样本 */
	g_tAD7606.sNowAdc[2] = AD7606_RESULT();	/* 读第3路样本 */
	g_tAD7606.sNowAdc[3] = AD7606_RESULT();	/* 读第4路样本 */
	g_tAD7606.sNowAdc[4] = AD7606_RESULT();	/* 读第5路样本 */
    g_tAD7606.sNowAdc[5] = AD7606_RESULT();	/* 读第6路样本 */
}

评论 92
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值