IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 正点原子开发板STM32F407ZG-基于AD7606进行八路数据采集 -> 正文阅读

[嵌入式]正点原子开发板STM32F407ZG-基于AD7606进行八路数据采集

购买的AD7606模块
模块基本信息
在淘宝上面购买的这款产品,让店家设置的是串行(SPI)、模拟梁输入范围是正负10V。
板子背面的焊盘选择

焊盘选择,一定要注意每个焊盘点的焊接,可能商家会焊错,而且这夹店铺的文档资料跟这个上面的丝印不匹配,需要额外注意。
1、原理图
原理图参考安富莱的AD7606的
在这里插入图片描述
2.管脚的定义
2.1OS2,OS1,OS0
数据手册上面定义了这三个引脚的功能
在这里插入图片描述
这三个管脚组合控制过采样模式。

000 表示无过采样,最大 200Ksps 采样速率。
001 表示 2 倍过采样, 芯片内部转换需要采集 2 个样本求平均。
010 表示 4 倍过采样,芯片内部转换采集 4 个样本求平均。
011 表示 8 倍过采样, 芯片内部转换采集 8 个样本求平均。
100 表示 16 倍过采样, 芯片内部转换采集 16 个样本求平均。
101 表示 32 倍过采样, 芯片内部转换采集 32 个样本求平均。
110 表示 64 倍过采样, 芯片内部转换采集 64 个样本求平均。

过采样率越高,ADC转换的时间就越长,得到的采样频率就越低,对一些需要快速转换的场合不太适应。根据项目需要来进行选择采样率,这次项目默认000,即不过采样率。
2.2 CONVSTA/B
这两个引脚是选择模拟输入通道的,要对八路所有通道进行模拟输入转换,那就将这两个引脚短接在一起,并通过一个MCU引脚来控制,施加一个转换信号。其他的模拟输入转换可以分别控制STA或者STB来达到效果。
2.3 RANGE
模拟输入范围选择引脚,低电平选择范围是正负5V,高电平选择范围是正负10V。
2.4 ADRD :
芯片的读信号引脚。要是选择的是并行接口驱动,那这个引脚功能就是读取控制输入(RD),要是选择串行接口,即SPI通信,则作为时钟输入(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)决定逻辑接口的工作电压。此引脚的标称电源与主机接口电源相同。

并行输出数据位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工作在并行字节接口模式。
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配置

/*
*********************************************************************************************************
*	oˉ êy ??: bsp_InitAD7606
*	1|?ü?μ?÷: 3?ê??ˉAD7606 SPI?ú??
*	D?    2?£o?T
*	·μ ?? ?μ: ?T
*********************************************************************************************************
*/
void bsp_spi_InitAD7606(void)
{
	AD7606_ConfigGPIO();		/* ????GPIO */
	
#ifdef HARD_SPI
	AD7606_CfgSpiHard();
#endif
	
//	AD7606_SetInputRange(g_tAD7606.Range);	/* éè??2é?ùá?3ì */

	/* éè??1y2é?ù?£ê? */
	//ad7606_SetOS(0);
	AD7606_RESET();				/* ó2?t?′???′AD7606 */
	
	AD7606_CONVST_H;			/* CONVST??éè???a??μ??? */	
}
/*
*********************************************************************************************************
*	oˉ êy ??: AD7606_ConfigGPIO
*	1|?ü?μ?÷: ????GPIO?£ 2?°üਠSCK  MOSI  MISO 12?íμ?SPI×ü???£
*	D?    2?: ?T
*	·μ ?? ?μ: ?T
*********************************************************************************************************
*/
static void AD7606_ConfigGPIO(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	/* ′ò?aGPIOê±?ó */
	RCC_AHB1PeriphClockCmd(RCC_CS | RCC_RANGE | RCC_BUSY | RCC_RESET | RCC_CONVST, ENABLE);

	/* 配置几个推挽输出IO*/
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;		/*  设为输出口*/
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		/* 设为推挽模式*/
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	/* 上下拉电阻不使能*/
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	/* IO口最大速度*/

	GPIO_InitStructure.GPIO_Pin = PIN_RESET;
	GPIO_Init(PORT_RESET, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = PIN_CONVST;
	GPIO_Init(PORT_CONVST, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = PIN_RANGE;
	GPIO_Init(PORT_RANGE, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = PIN_CS;
	GPIO_Init(PORT_CS, &GPIO_InitStructure);

	/* 配置GPIO为浮动输入模式(实际上CPU复位后就是输入状态) */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;		/* 设为输入口*/
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		/*  设为推挽模式*/
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	/* 无需上下拉电阻 */
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	/* IO口最大速度 */

	GPIO_InitStructure.GPIO_Pin = PIN_BUSY;
	GPIO_Init(PORT_BUSY, &GPIO_InitStructure);
}

配置SPI

/*
*********************************************************************************************************
*	oˉ êy ??: bsp_InitSPIBus
*	1|?ü?μ?÷: ????SPI×ü???£ ??°üਠSCK?¢ MOSI?¢ MISO?ú??μ??????£2?°üà¨????CS£?ò22?°üà¨íaéèD???ì?óDμ?INT?¢BUSYμè
*	D?    2?: ?T
*	·μ ?? ?μ: ?T
*********************************************************************************************************
*/
void bsp_InitSPIBus(void)
{
#ifdef SOFT_SPI		/* 软件SPI*/
	GPIO_InitTypeDef  GPIO_InitStructure;

	/* 打开GPIO时钟 */
	RCC_AHB1PeriphClockCmd(RCC_SCK | RCC_MOSI | RCC_MISO, ENABLE);

	/* 配置几个推挽输出IO */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;		/* éè?aê?3??ú */
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		/* éè?aí?íì?£ê? */
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	/* é???à-μ?×è2?ê1?ü */
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;	/* IO?ú×?′ó?ù?è *///25

	GPIO_InitStructure.GPIO_Pin = PIN_SCK;
	GPIO_Init(PORT_SCK, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = PIN_MOSI;
	GPIO_Init(PORT_MOSI, &GPIO_InitStructure);

	/* ????GPIO?a???ˉê?è??£ê?(êμ?êé?CPU?′??oó?íê?ê?è?×′ì?) */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;		/* éè?aê?è??ú */
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		/* éè?aí?íì?£ê? */
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	/* ?TDèé???à-μ?×è */
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;	/* IO?ú×?′ó?ù?è */

	GPIO_InitStructure.GPIO_Pin = PIN_MISO;
	GPIO_Init(PORT_MISO, &GPIO_InitStructure);
#endif
}

/*
*********************************************************************************************************
*	函数名: ad7606_ReadBytes
*	功能说明: 读取AD7606的采样结果
*	形  参:
*	返回值: 无
*********************************************************************************************************
*/
uint8_t bsp_spiRead1(void)
{
#ifdef SOFT_SPI		/* èí?tSPI */
	uint8_t i;
	uint8_t read = 0;

	for (i = 0; i < 8; i++)
	{
		SCK_0();
		bsp_spiDelay();
		read = read << 1;
		if (MISO_IS_HIGH())
		{
			read++;
		}
		SCK_1();
		bsp_spiDelay();
	}
	return read;
#endif
}

4.3 过采样配置
过采样配置可以硬件上引脚全部接地,或者接MCU的引脚进行控制

//设置AD7606的过采样率OS[2:0]
void AD7606_SETOS(uint8_t osv)
{
	
  switch(osv)
  {
  case 0://000无过采样率
    AD7606OS0_L;
    AD7606OS1_L;
    AD7606OS2_L;
    break;
  case 1://001  2倍过采样率
    AD7606OS0_H;
    AD7606OS1_L;
    AD7606OS2_L;
    break;
  case 2://010?¢4±?1y2é?ù?ê
    AD7606OS0_L;
    AD7606OS1_H;
    AD7606OS2_L;
    break;
  case 3://011  8倍过采样率
    AD7606OS0_H;
    AD7606OS1_H;
    AD7606OS2_L;
    break;
  case 4://100  16倍过采样率
    AD7606OS0_L;
    AD7606OS1_L;
    AD7606OS2_H;
    break;
  case 5://101  32倍过采样率
    AD7606OS0_H;
    AD7606OS1_L;
    AD7606OS2_H;
    break;
  case 6://110  64倍过采样率
    AD7606OS0_L;
    AD7606OS1_H;
    AD7606OS2_H;
    break;
  }
}

4.4 复位函数

//AD7606?′??ê?è?oˉêy
void AD7606_RESET(void)
{
	AD7606_CS_H;
	AD7606_RESET_L;
	AD7606_RESET_H;
	AD7606_RESET_H;
	AD7606_RESET_H;
	AD7606_RESET_H;
	AD7606_RESET_L;
}

4.5 开启转换

void AD7606_STARTCONV(void)    //?a??×a??
 {
//	AD7606_CONVST_H;
    AD7606_CONVST_L;
    AD7606_CONVST_L;
    AD7606_CONVST_L;
	AD7606_CONVST_H;
 }

4.7 读取AD转换器数据

 //函数名: AD7606_scan功能说明: 扫描调用本函数,用于读取AD转换器数据
void AD7606_Scan(void) 		
{
	uint8_t i;			

	/* BUSY = 0 时.ad7606处于空闲状态ad转换结束 */	
	if (BUSY_IS_LOW())	   
    { 
		AD7606_CS_L; /* SPI片选 = 0 */
		for (i = 0; i < 8; i++)
		{
			s_adc_now[i] = bsp_spiRead1();	
			s_adc_now[i] = s_adc_now[i] * 256 + bsp_spiRead1(); /* 读数据 */
		}
	
		AD7606_CS_H; /* SPI片选 = 1 */
	  AD7606_STARTCONV();	/* 给开始信号*/	

	}
}	 

4.7 处理采样后的数据

//	函数名: AD7606_Mak
//	功能说明: 处理采样后的数据
//	形   参 :无
//	返回值: 无 
void AD7606_Mak(void)
{
	uint8_t i;
	int16_t adc;
  
//	printf("1");
	for (i = 0;i < 8; i++)
	{	
		s_dat[i] = AD7606_ReadAdc(i);
		adc = s_dat[i];
		s_volt[i] = (adc * 10000) / 32767;
    
	}
}

4.8 显示采样后的数据

//函数名: AD7606_Disp
//功能说明: 显示采样后的数据

void AD7606_Disp(void)
{
	int16_t i;	
	int16_t iTemp;

	/* ′òó?2é?ˉêy?Y */
	for (i = 0; i < 8; i++)
	{                
   		iTemp = s_volt[i];	/* uV  */
		
		if (s_dat[i] < 0)
		{
			iTemp = -iTemp;
          printf(" CH%d = %6d,0x%04X (-%d.%d%d%d V) \r\n", i+1, s_dat[i], (uint16_t)s_dat[i], iTemp /1000, (iTemp%1000)/100, (iTemp%100)/10,iTemp%10);
		}
		else
		{
         	printf(" CH%d = %6d,0x%04X ( %d.%d%d%d V) \r\n", i+1, s_dat[i], s_dat[i] , iTemp /1000, (iTemp%1000)/100, (iTemp%100)/10,iTemp%10);                    
		}
	}

}

4.9 测试结果


在这里插入图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-19 12:12:44  更:2021-08-19 12:13:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 23:26:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码