赞
踩
了解一下ad7606模块,并学习制作一个。
先了解一下关元AD7606的信息。(芯片手册的内容)
SPI总线包括4条逻辑线,定义如下:
Master input slave output
主机输入,从机输出(数据来自从机);Master output slave input
主机输出,从机输入(数据来自主机);Serial Clock
串行时钟信号,由主机产生发送给从机;Slave Select
片选信号,由主机发送,以控制与哪个从机通信,通常是低电平有效信号。其他制造商可能会遵循其他命名规则,但是最终他们指的相同的含义。以下是一些常用术语;
SIMO
,DOUT
,DO
,SDO
或SO
(在主机端);SOMI
,DIN
,DI
,SDI
或SI
(在主机端);CE
,CS
或SSEL
;本文将按照以下命名进行讲解[MISO, MOSI, SCK,NSS]
在软件配置上将根据时序图进行配置。
我是在网上找了相关的例程,后进行一点修改。
我采用的是STM32F103VCT6,全部引脚引出,用ZET6也可以。AD7606是用的;凌智电子的模块。
AD7606模块采用5v供电,J11跳线帽接3.3v,J2跳线帽接±5v。
采用串行连接。AD7606与单片机连接示意图:
AD7606 | 全称 | 单片机 | 功能介绍 |
+5 | +5 | ||
GND | GND | ||
REST | RESET | C8 | GPIO复位AD7606 |
SER | PAR/SER/ BYTE SEL | +3.3V | 并行/串行/字节接口选择输入,接3.3V |
STBY | STBY | B11 | 待机模式输入 |
OS2 | OS2 | B13 | 过采样模式引脚。 |
OS1 | OS1 | B14 | |
OS0 | OS0 | B15 | |
CO_A | CONVST A | B10 | 启动模拟输入通道转换信号 |
CO_B | CONVST B | C9 | |
CS_N | CS | A6 | 片选,置低后标志可以开始输出模拟量 |
RD/SC | RD/SCLK | A7 | 串行时钟输入(SCLK)。SCLK上升沿将随后的所有数据位逐个送至串行数据输出DOUTA和DOUTB |
DB7 | DB7/DOUTA | C6 | 串行接口数据输出引脚(DOUTA)。 |
BUSY | BUSY | A5 | 输出繁忙 |
DB15 | DB15/BYTE SEL | GND | 并行/串行/字节接口选择输入,接地 |
FR_D | FRSTDATA | A4 | 数字输出(可不接) |
当选择串行接口时,应将引脚 DB[15:9]和DB[6:0]接地。
在实际使用时空接也是可以的。但画电路的时候建议接地。
只用一路DOUT 线的缺点是:如果在转换之后进行读 取,则吞吐速率会下降。串行模式下,不用的DOUT线应保 持不连接。
省电模式
过采样位解码
该引脚可以不接
AD7606.C
-
- #include <stm32f10x.h>
- #include "Delay.h"
- #include "AD7606.h"
- //#include "lze_lcd.h"
-
- extern u8 IO_TAG;
- //-----------------------------------------------------------------
- // 初始化程序区
- //-----------------------------------------------------------------
- //-----------------------------------------------------------------
- // void GPIO_AD7606_Configuration(void)
- //-----------------------------------------------------------------
- //
- // 函数功能: AD7606引脚配置函数
- // 入口参数: 无
- // 返回参数: 无
- // 全局变量: 无
- // 调用模块: RCC_APB2PeriphClockCmd(); GPIO_Init();
- // 注意事项: 用GPIO驱动方式和FSMC驱动方式下的引脚配置不一样
- //
- //-----------------------------------------------------------------
- void GPIO_AD7606_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- // 使能IO口时钟
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
- RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
- RCC_APB2Periph_GPIOE,
- ENABLE);
- GPIO_DeInit(GPIOA);//将GPIOx外设寄存器初始化为默认复位值
- GPIO_DeInit(GPIOB);//除了B4和A15是高电平。B3没信号外,其他io口被拉低。(默认值)
- GPIO_DeInit(GPIOC);
- GPIO_DeInit(GPIOD);
- GPIO_DeInit(GPIOE);
- //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- // AD7606
- //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- // 控制线配置
- // CS_N RD/SCLK
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- // FRSTDATA BUSY
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING ;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- // rst convstB convstA STby OS12 OS11 OS10
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 |
- GPIO_Pin_13 | GPIO_Pin_14 |
- GPIO_Pin_15 ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 ;
-
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
-
-
- //数据线配置(1)
- // DoutA
- // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
-
- //-----------------------------------------------------------------
- // void AD7606_Init(void)
- //-----------------------------------------------------------------
- //
- // 函数功能: AD7606初始化函数
- // 入口参数: 无
- // 返回参数: 无
- // 全局变量: 无
- // 调用模块:
- // 注意事项: 无
- //-----------------------------------------------------------------
- void AD7606_Init(void)
- {
- convstA_Set; //B10
- convstB_Set; //C9
- delay_ms(1);
- STby_Set; //B11
- clk_Set; //A7
- cs_Set; //A6
- OS10_Reset; //B15
- OS11_Reset; //B14
- OS12_Reset; //B13
- AD7606_reset(); //复位
- delay_ms(1); //
- AD7606_startconvst(); // 启动转换
- }
-
- /* * 名称:AD7606_startconvst() * 功能:启动转换 */
- void AD7606_startconvst(void)
- {
- convstA_Reset; //B10
- convstB_Reset; //C9
- delay_us (1);
- convstA_Set; //B10
- convstB_Set; //C9
- }
-
- /* * 名称:AD7606_reset() * 功能:复位模块 */
- void AD7606_reset(void)
- {
- rst_Reset; //C8
- delay_us (1);
- rst_Set; //C8
- delay_us(1);
- rst_Reset; //C8
- }
-
- /*
- * 名称:AD7606_read_data()
- * 功能:读取数据
- * 返回值:返回一个结构体指针,该指针为指向结构体数组的首地址
- */
- void AD7606_read_data(s16 * DB_data)
- {
- u8 i,j;
- for(i=0;i<8;i++)
- {
- u16 DB_data1 = 0;
- cs_Reset; //A6
- delay_us(1);
- for(j=0;j<16;j++)
- {
- clk_Reset; //A7
- delay_us(1);
- // DB_data1 = ((u16)(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0))<< (15-j)) + DB_data1 ;
- DB_data1 = ((u16)(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6))<< (15-j)) + DB_data1 ;
- clk_Set; //A7
- delay_us(1);
- }
- cs_Set; //A6
- DB_data[i] = (u16)DB_data1;
- }
- }
-
AD7606.H
- #ifndef _AD7606_H
- #define _AD7606_H
-
-
- #define sampling_0times 0
- #define sampling_2times 1
- #define sampling_4times 2
- #define sampling_8times 3
- #define sampling_16times 4
- #define sampling_32times 5
- #define sampling_64times 6
-
- #define STby_Set GPIO_SetBits(GPIOB,GPIO_Pin_11)
-
- #define OS10_Set GPIO_SetBits(GPIOB,GPIO_Pin_15)
- #define OS10_Reset GPIO_ResetBits(GPIOB,GPIO_Pin_15)
- #define OS11_Set GPIO_SetBits(GPIOB,GPIO_Pin_14)
- #define OS11_Reset GPIO_ResetBits(GPIOB,GPIO_Pin_14)
- #define OS12_Set GPIO_SetBits(GPIOB,GPIO_Pin_13)
- #define OS12_Reset GPIO_ResetBits(GPIOB,GPIO_Pin_13)
- #define convstA_Set GPIO_SetBits(GPIOB,GPIO_Pin_10)
- #define convstA_Reset GPIO_ResetBits(GPIOB,GPIO_Pin_10)
- #define convstB_Set GPIO_SetBits(GPIOC,GPIO_Pin_9)
- #define convstB_Reset GPIO_ResetBits(GPIOC,GPIO_Pin_9)
- #define rst_Set GPIO_SetBits(GPIOC,GPIO_Pin_8)
- #define rst_Reset GPIO_ResetBits(GPIOC,GPIO_Pin_8)
- #define clk_Set GPIO_SetBits(GPIOA,GPIO_Pin_7)
- #define clk_Reset GPIO_ResetBits(GPIOA,GPIO_Pin_7)
- #define cs_Set GPIO_SetBits(GPIOA,GPIO_Pin_6)
- #define cs_Reset GPIO_ResetBits(GPIOA,GPIO_Pin_6)
- #define frstdata_Set GPIO_SetBits(GPIOA,GPIO_Pin_4)
- #define frstdata_Reset GPIO_ResetBits(GPIOA,GPIO_Pin_4)
- #define busy_Set GPIO_SetBits(GPIOA,GPIO_Pin_5)
- #define busy_Reset GPIO_ResetBits(GPIOA,GPIO_Pin_5)
- #include "stm32f10x.h" // Device header
-
- extern void GPIO_AD7606_Configuration(void);
- extern void AD7606_Init(void);
- extern void AD7606_startconvst(void);
- extern void AD7606_reset(void);
- extern void AD7606_read_data(s16 * DB_data) ;
-
- #endif
-
- //-----------------------------------------------------------------
- // End Of File
- //-----------------------------------------------------------------
-
- //数字:0
- //CH1: 1789.4 mv 0xadcf 44495
- //CH2: 4547.4 mv 0xf46a 62570
- //CH3: 1540.5 mv 0xa770 42864
- //CH4: 4823.5 mv 0xfb7b 64379
- //CH5: 1000.4 mv 0x999c 39324
- //CH6: 2565.0 mv 0xc1aa 49578
- //CH7: 1362.2 mv 0xa2df 41695
- //CH8: 2978.1 mv 0xcc3d 52285
-
main.c
- #include "stm32f10x.h" // Device header
-
- #include "AD7606.h"
- #include "PeripheralInit.h"
-
-
- //注意:
- // (1) 串行:SER = 1;D15 = 0;
- // (2) 通过J3跳帽选择输入电压的范围,修改程序第92行中sprintf里面的(float)(DB_data[i]*5000.0/32768)的5000.0,在5000.0和10000.0根据跳帽改变。
- // (3) J2跳帽这里连接3.3V,具体选择看引脚功能。
-
-
- int main(void)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
-
- u8 dis_buf[40];
- u8 i;
- uint8_t temp;
- s16 DB_data[8] = {0};
- delay_init(); //延时初始化
- PeripheralInit(); // 外设初始化
-
- while(1)
- {
-
- printf("数字:%d\r\n",Num++);
- delay_ms (1000);
-
- AD7606_startconvst(); //AD7606开始转换
- temp = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5); // 读取 BUSY的状态
-
- while(temp == 0) //当busy为低电平时,数据转换完毕,此时可以读取数据
- {
- delay_us(1);
- temp = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5); // 读取 BUSY的状态
- }
- AD7606_read_data(DB_data); //读取数据放至数组DB_data[]
-
- for(i=0;i<8;i++)
- {
- sprintf((char*)dis_buf,"CH%1d:%8.1f mv 0x%04x %6d\r\n", i+1, (float)(DB_data[i]*5000.0/32768), (u16)(DB_data[i]^0x8000), (u16)(DB_data[i]^0x8000));
- printf("CH%1d:%8.1f mv 0x%04x %6d\r\n", i+1, (float)(DB_data[i]*5000.0/32768), (u16)(DB_data[i]^0x8000), (u16)(DB_data[i]^0x8000)); //在串口显示结果
- delay_ms(20);
- }
- delay_ms(100);
-
- }
- }
之前有一个疑问,为什么不用单片机自带的ad而用模块?
整理一下网上的答案
1、AD7606是8路同步采样,内部ADC不是,最高只能三路同步。 2、内置的精度有效位没有7606高 3、7606是真双极性,支持正负10V,而内置的只能0-3.3V,不支持负压采集。 4、7606最高是200Ksps。内置是3.6Msps |
AD7606优势在于高精度,支持宽电压,可达±10V。抗干扰能力强。
单片机的优势在于价格便宜。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。