|
出厂的AD7606模块缺省是8080 并行接口。
如果用SPI接口模式,需要修改 R1 R2电阻配置。
并口模式跳线: R1 悬空(不贴),R2贴10K电阻
SPI接口模式跳线:R1 贴10K电阻, R2 悬空(不贴)
AD7606 的配置很简单,它没有内部寄存器。量程范围和过采样参数是通过外部IO控制的。
采样速率由MCU或DSP提供的脉冲频率控制。
AD7606 必须使用单5V供电。
AD7606 和MCU之间的通信接口电平由VIO引脚控制。也就是说 VIO必须接单片机的电源,可以是3.3V也可以是5V。
【模块引脚说明】
OS2 OS1 OS2 : 的组合状态选择过采样模式。
000表示无过采样,最大200Ksps采样速率。
001表示2倍过采样, 也就是硬件内部采集2个样本求平均
010表示4倍过采样, 也就是硬件内部采集4个样本求平均
011表示8倍过采样, 也就是硬件内部采集8个样本求平均
100表示16倍过采样, 也就是硬件内部采集16个样本求平均
101表示32倍过采样, 也就是硬件内部采集32个样本求平均
110表示64倍过采样, 也就是硬件内部采集64个样本求平均
过采样倍率越高,ADC转换时间越长,可得到的最大采样频率就越低。
CVA,CVB : 启动AD转换的控制信号。CVA决定1-4通道,CVB决定5-8通道。
2个信号可以错开短暂的时间。一般情况可以将CVA,CVB并联在一起。
RAGE : 量程范围选择。0表示正负5V, 1表示正负10V.
RD : 读信号
RST : 复位信号
BUSY : 忙信号
CS : 片选信号
FRST : 第1个通道样本的指示信号
VIO : 通信接口电平
DB0-DB15 : 数据总线
【16位并行模式接线图】 --- AD7606也支持8位总线模式,请参见AD7606数据手册
AD7606模块 MCU侧
GND <----- 地
+5V <----- 5V电源
RAGE <----- 可接GPIO也可接固定电平
OS2 <----- 可接GPIO也可接固定电平
OS1 <----- 可接GPIO也可接固定电平
OS0 <----- 可接GPIO也可接固定电平
CVA <----- 接GPIO(输出)用于启动AD转换 【推荐接具有PWM输出能力的引脚】
CVB <---|
RD <----- 8080总线读信号 NOE
RST <----- GPIO输出 硬件复位AD606
BUSY -----> GPIO输入 AD606正在转换指示。【推荐接具有外部中断能力的引脚】
CS <----- 8080总线片选 NCS
VIO <----- 单片机的电源
DB0-DB15 -----> 8080数据总线(16位)
FRST 可不接
【SPI接口模式接线图】
AD7606模块 MCU侧
GND <----- 地
+5V <----- 5V电源
RAGE <----- 任意输出GPIO,可接固定电平
OS2 <----- 任意输出GPIO,可接固定电平
OS1 <----- 任意输出GPIO,可接固定电平
OS0 <----- 任意输出GPIO, 可接固定电平
CVA <----- 接GPIO(输出)用于启动AD转换 【推荐接具有PWM输出能力的引脚】
CVB <---|
RD/SCLK <----- SPI总线时钟 SCK
RST <----- 任意输出GPIO, 用于硬件复位AD606
BUSY -----> GPIO输入, AD606正在转换指示。【推荐接具有外部中断能力的引脚】
CS <----- SPI总线片选 SCS
VIO <----- 单片机电源
DB7(DOUTA) -----> SPI总线数据线MISO
DB15 ------ GND
其他数据线: 可不接或接GND
FRST 可不接
【软件定时采集的实现方案1】 --- 我们提供的 spi 的例子采用这种方案 见 bsp_spi_ad7606.c 文件
在定时器中断服务程序中实现:
定时器中断ISR:
{
中断入口;
读取8个通道的采样结果保存到RAM; ----> 读取的其实是上次的采集结果,对于连续采集来说,是没有关系的
启动下次ADC采集;(翻转CVA和CVB)
中断返回;
}
定时器的频率就是ADC采样频率。这种模式可以不连接 BUSY 口线。
【软件定时采集的实现方案2】 --- 我们提供的 8080接口例子采用这种方案 见 bsp_ad7606.c 文件
配置CVA CVB 引脚为PWM输出模式,周期设置为需要的采样频率; ---> 之后MCU将产生周期非常稳定的AD转换信号
将BUSY口线设置为中断下降沿触发模式;
外部中断ISR
{
中断入口;
读取8个通道的采样结果保存到RAM;
中断返回;
}
【软件定时采集的实现方案1和方案2的差异】
(1)方案1 可以少用 BUSY口线, 但是其他中断服务程序或者主程序临时关闭全局中断时,可能导致ADC转换周期存在轻微抖动。
(2)方案2 可以确保采集时钟的稳定性,因为它是MCU硬件产生的。但是需要多接一根 BUSY口线。
单片机源程序如下:
- #include "stm32f10x.h"
- #include <stdio.h>
- #include "bsp.h"
- #include "bsp_spi_ad7606.h"
- #include "bsp_timer.h"
- FIFO_T g_tAD; /* 定义一个交换缓冲区,用于存储AD采集数据,并用于写入SD卡 */
- void bsp_TIM4_Configuration(void);
- /*
- *********************************************************************************************************
- * 函 数 名: bsp_InitAD7606
- * 功能说明: 初始化AD7606 SPI口线
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void bsp_InitAD7606(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- SPI_InitTypeDef SPI_InitStructure;
-
- /* AD_SPI_CS_GPIO, AD_SPI_MOSI_GPIO, AD_SPI_MISO_GPIO, AD_SPI_DETECT_GPIO
- and AD_SPI_SCK_GPIO Periph clock enable */
- RCC_APB2PeriphClockCmd(AD_CS_GPIO_CLK | AD_SPI_MISO_GPIO_CLK | AD_SPI_SCK_GPIO_CLK
- , ENABLE);
-
- /* AD_SPI Periph clock enable */
- RCC_APB1PeriphClockCmd(AD_SPI_CLK, ENABLE);
-
- /* Configure AD_SPI pins: SCK */
- GPIO_InitStructure.GPIO_Pin = AD_SPI_SCK_PIN;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(AD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
-
- /* Configure AD_SPI pins: MISO */
- GPIO_InitStructure.GPIO_Pin = AD_SPI_MISO_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(AD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Pin = AD_CS_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(AD_CS_GPIO_PORT, &GPIO_InitStructure);
-
- /* AD_SPI Config */
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
- //SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx;
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
- SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
- SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
- SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
- SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
- SPI_InitStructure.SPI_CRCPolynomial = 7;
- SPI_Init(AD_SPI, &SPI_InitStructure);
-
- SPI_Cmd(AD_SPI, ENABLE); /* AD_SPI enable */
-
- /* 配置其它的GPIO */
- /* 使能GPIO时钟 */
- RCC_APB2PeriphClockCmd(AD_RESET_GPIO_CLK | AD_CONVST_GPIO_CLK | AD_OS0_GPIO_CLK
- | AD_OS1_GPIO_CLK | AD_OS2_GPIO_CLK, ENABLE);
- /* 配置RESET GPIO */
- GPIO_InitStructure.GPIO_Pin = AD_RESET_PIN;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(AD_RESET_GPIO_PORT, &GPIO_InitStructure);
-
- /* 配置CONVST GPIO */
- GPIO_InitStructure.GPIO_Pin = AD_CONVST_PIN;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(AD_CONVST_GPIO_PORT, &GPIO_InitStructure);
- /* 配置OS0-2 GPIO */
- GPIO_InitStructure.GPIO_Pin = AD_OS0_PIN;
- GPIO_Init(AD_OS0_GPIO_PORT, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = AD_OS1_PIN;
- GPIO_Init(AD_OS1_GPIO_PORT, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = AD_OS2_PIN;
- GPIO_Init(AD_OS2_GPIO_PORT, &GPIO_InitStructure);
- /* 设置过采样模式 */
- ad7606_SetOS(0);
- /* 设置GPIO的初始状态 */
- ad7606_Reset(); /* 硬件复位复AD7606 */
-
- AD_CONVST_HIGH(); /* CONVST脚设置为高电平 */
- bsp_TIM4_Configuration(); /* 配置TIM2定时中断 */
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ad7606_Reset
- * 功能说明: 硬件复位AD7606
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void ad7606_Reset(void)
- {
- /* AD7606是高电平复位,要求最小脉宽50ns */
-
- AD_RESET_LOW();
-
- AD_RESET_HIGH();
- AD_RESET_HIGH();
- AD_RESET_HIGH();
- AD_RESET_HIGH();
-
- AD_RESET_LOW();
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ad7606_SetOS
- * 功能说明: 设置过采样模式(数字滤波,硬件求平均值)
- * 形 参:_ucMode : 0-6 0表示无过采样,1表示2倍,2表示4倍,3表示8倍,4表示16倍
- * 5表示32倍,6表示64倍
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void ad7606_SetOS(uint8_t _ucMode)
- {
- if (_ucMode == 1)
- {
- AD_OS2_0();
- AD_OS1_0();
- AD_OS0_1();
- }
- else if (_ucMode == 2)
- {
- AD_OS2_0();
- AD_OS1_1();
- AD_OS0_0();
- }
- else if (_ucMode == 3)
- {
- AD_OS2_0();
- AD_OS1_1();
- AD_OS0_1();
- }
- else if (_ucMode == 4)
- {
- AD_OS2_1();
- AD_OS1_0();
- AD_OS0_0();
- }
- else if (_ucMode == 5)
- {
- AD_OS2_1();
- AD_OS1_0();
- AD_OS0_1();
- }
- else if (_ucMode == 6)
- {
- AD_OS2_1();
- AD_OS1_1();
- AD_OS0_0();
- }
- else /* 按0处理 */
- {
- AD_OS2_0();
- AD_OS1_0();
- AD_OS0_0();
- }
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ad7606_StartConv
- * 功能说明: 启动AD7606的ADC转换
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void ad7606_StartConv(void)
- {
- /* 上升沿开始转换,低电平持续时间至少25ns */
- AD_CONVST_LOW();
- AD_CONVST_LOW();
- AD_CONVST_LOW(); /* 连续执行2次,低电平约50ns */
-
- AD_CONVST_HIGH();
- }
- /*
- *********************************************************************************************************
- * 函 数 名: bsp_TIM4_Configuration
- * 功能说明: 配置TIM4定时器
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void bsp_TIM4_Configuration(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
-
- /* TIM2 clock enable */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
- /* Configure the NVIC Preemption Priority Bits[配置优先级组] */
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
- /* Enable the TIM2 gloabal Interrupt [允许TIM2全局中断]*/
- NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: bsp_SET_TIM4_FREQ
- * 功能说明: 设置TIM4定时器频率
- * 形 参:_ulFreq : 采样频率,单位Hz,
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void bsp_SET_TIM4_FREQ(uint32_t _ulFreq)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- uint16_t usPrescaler;
- uint16_t usPeriod;
- TIM_DeInit(TIM4); /* 复位TIM2定时器 */
- /* TIM2 configuration
- TIM2CLK = 36 MHz
- */
- if (_ulFreq == 0)
- {
- return; /* 采样频率为0,停止采样 */
- }
- else if (_ulFreq <= 100) /* 采样频率小于100Hz */
- {
- usPrescaler = 36000; /* TM2CLK = 72 000 000/36000 = 2000 */
- usPeriod = 2000 / _ulFreq;
- }
- else if (_ulFreq <= 200000) /* 采样频率 :100Hz - 200kHz */
- {
- usPrescaler = 36 - 1; /* TM2CLK = 36 000 000/36 = 2 000 000 */
- usPeriod = 2000000 / _ulFreq;
- }
- else /* 采样频率大于 200kHz */
- {
- return;
- }
-
- TIM_TimeBaseStructure.TIM_Period = usPeriod - 1; /* 计数周期 */
- TIM_TimeBaseStructure.TIM_Prescaler = usPrescaler; /* 分频系数 */
- TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; /* */
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数方向向上计数
- TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
- /* Clear TIM2 update pending flag[清除TIM2溢出中断标志] */
- TIM_ClearFlag(TIM4, TIM_FLAG_Update);
- TIM_SetCounter(TIM4, 0);
- /* Enable TIM2 Update interrupt [TIM2溢出中断允许]*/
- TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
- /* TIM2 enable counter [允许tim2计数]*/
- TIM_Cmd(TIM4, ENABLE);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ad7606_ReadBytes
- * 功能说明: 读取AD7606的采样结果
- * 形 参:
- * 返 回 值: 无
- *********************************************************************************************************
- */
- uint16_t ad7606_ReadBytes(void)
- {
- uint16_t usData = 0;
-
- /* Wait until the transmit buffer is empty */
- while (SPI_I2S_GetFlagStatus(AD_SPI, SPI_I2S_FLAG_TXE) == RESET)
- {
- }
-
- /* Send the byte */
- SPI_I2S_SendData(AD_SPI, 0xFFFF);
- /* Wait until a data is received */
- while (SPI_I2S_GetFlagStatus(AD_SPI, SPI_I2S_FLAG_RXNE) == RESET)
- {
- }
-
- /* Get the received data */
- usData = SPI_I2S_ReceiveData(AD_SPI);
- /* Return the shifted data */
- return usData;
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ad7606_IRQSrc
- * 功能说明: 定时调用本函数,用于读取AD转换器数据
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void ad7606_IRQSrc(void)
- {
- uint8_t i;
- uint16_t usReadValue;
- TIM_ClearFlag(TIM4, TIM_FLAG_Update);
- /* 读取数据
- 示波器监测,CS低电平持续时间 35us
- */
- AD_CS_LOW();
- for (i = 0; i < CH_NUM; i++)
- {
- usReadValue = ad7606_ReadBytes();
- if (g_tAD.usWrite < FIFO_SIZE)
- {
- g_tAD.usBuf[g_tAD.usWrite] = usReadValue;
- ++g_tAD.usWrite;
- }
- }
-
- AD_CS_HIGH();
- ad7606_StartConv();
- }
- /*
- *********************************************************************************************************
- * 函 数 名: GetAdcFormFifo
- * 功能说明: 从FIFO中读取一个ADC值
- * 形 参:_usReadAdc : 存放ADC结果的变量指针
- * 返 回 值: 1 表示OK,0表示暂无数据
- *********************************************************************************************************
- */
- uint8_t GetAdcFormFifo(uint16_t *_usReadAdc)
- {
- uint16_t usWrite;
-
- DISABLE_INT();
- usWrite = g_tAD.usWrite;
- ENABLE_INT();
-
- if (usWrite != g_tAD.usRead)
- {
- *_usReadAdc = g_tAD.usBuf[g_tAD.usRead];
- DISABLE_INT();
- if (++g_tAD.usRead >= FIFO_SIZE)
- {
- g_tAD.usRead = 0;
- }
- ENABLE_INT();
- return 1;
- }
- return 0;
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ad7606_StartRecord
- * 功能说明: 开始采集
- * 形 参:_ulFreq : 采样频率, 单位 HZ
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void ad7606_StartRecord(uint32_t _ulFreq)
- {
- //ad7606_Reset(); /* 复位硬件 */
- ad7606_StartConv(); /* 启动采样,避免第1组数据全0的问题 */
- g_tAD.usRead = 0; /* 必须在开启TIM2之前清0 */
- g_tAD.usWrite = 0;
- bsp_TIM4_Configuration(); /* 配置TIM2定时中断 */
- bsp_SET_TIM4_FREQ(_ulFreq); /* 设置采样频率, 并使能TIM2定时采样中断 */
- }
- /*
- *********************************************************************************************************
- * 函 数 名: ad7606_StopRecord
- * 功能说明: 停止采集
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void ad7606_StopRecord(void)
- {
- /* TIM2 enable counter [允许tim2计数]*/
- TIM_Cmd(TIM4, DISABLE);
- }
- void TIM4_IRQHandler(void)
- {
- ad7606_IRQSrc();
- }
复制代码 全部资料51hei下载地址:
AD7606数据采集模块资料(2015-01-22).7z
(3.99 MB, 下载次数: 35)
|
评分
-
查看全部评分
|