由于训练电赛,需要选取一块测量速度快,精度更高速度更快的外部ADC,所以选了一块AD7606。
AD7606是一块八通道,双极性输入,同步采样16位ADC。内置2.5V基准电压。由于AD7606没有内部的寄存器,需要直接利用引脚配置ADC的模式,所以AD7606的控制原理也是很简单,但是需要占用的I/O口的资源很多。
AD7606接线图
AD7606 SPI的串行接口接线图:
AD7606 16位并口接线图:
由这两张图可见除了必须要连接的一些控制线一样之外不同的是数据线的连接,SPI串行通讯用的数据总线的数量只需要一根,而并行通讯的数据总线的数量为16根,对于I/O口不是非常多的单片机还是推荐使用串行通讯。(注:根据数据手册需要把芯片的6脚SER接到高电平上,选择芯片工作在串口模式)
AD7606SPI通讯接口说明
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通道。可以将CVA和CVB接到一起用同一个引脚控制。(若想控制转换速率可以将引脚设置为PWM输出的模式以控制转换速率)
RAGE : 量程范围选择。0表示正负5V, 1表示正负10V.
RD : SPI总线时钟信号
RST : 复位信号
BUSY : 忙信号
CS : 片选信号
FRST : 第1个通道样本的指示信号(可不接)
VIO : 通信接口电平
DB7 : 数据总线
DB15:接地
AD7606时序图
图一图二
图三
(个人认为只需要这三张图就可以完全利用SPI总线将AD7606用起来)
AD7606时序图讲解
图一是整体的一个时序框图,大体的逻辑就是在使用AD7606之前要先复位一下,复位信号是高电平有效,时间至少为50ns。然后就是对采样速率和量程的配置,也就是对OS0,OS1,OS2和RANGE脚的配置,然后再对一些引脚进行一些初始化(也可以直接在GPIO配置的时候进行初始化)。之后就是发送启动信号,也就是将CVA,CVB拉低至少25ns后再拉高(启动信号上升沿有效)。之后AD7606开始转换,BUSY信号线拉高,如果BUSY信号线拉低则表明转换已经完成。转换完成后将CS片选信号线拉低才可以进行数据读取,读取完成后将CS片选信号线拉高即可。(还有一种是在转换时进行数据读取的,由于对于采样速率要求并不是特别的高,所以也没有深入研究)
图二是串行通讯对数据进行读取的时序框图,讲的是在AD7606转换完成后将CS片选信号拉低后的操作。转换完成后CS片选信号拉低,开始读取数据。由于是16位8通道ADC,一次读取一个字节,所以一个通道需要读取两次数据。因为是高位在前低位在后所以就是先读取的是MSB,后读取的LSB,数据需要SCLK下降沿有效。经过16*8 = 128个SCLK读取后已经全部将ADC转换的数据全部读取完了,之后就可以将CS片选信号拉高了(由于串行通讯FRSTDATA数据线可以不接,所以并没有用到这个脚)。
图三是对一个字节的读取,顺序也就是现将时钟线拉高后拉低然后读取一下当前的值然后拉高,重复八次就是一个字节的读取。(MSB的最高位为符号位,若为1则数据为负数,若为0则数据为正数)
AD7606 STM32引脚配置
用的MCU是STM32F103ZET6,系统时钟是72MHz。
RANGE,OS0,OS1,OS2若是需要选择量程和速率的话可以接到单片机引脚上,要是不需要的话可以直接接到地或VCC上(自己选择)。RST,RD,CVA, CVB,CS需要设置为OUTPUT输出模式,GPIO电平和模式默认就可以(我在AD7606初始化的时候对IO口也进行了初始化),DB7数据线接的INPUT脚要设为INPUT模式,需要内设上拉电阻。BUSY信号脚就设置为外部中断,下降沿触发,一定要把中断使能(下降沿触发说明ADC转换已经结束)。
AD7606 程序模块
程序我也是根据提供的例程进行的修改。
我对所有需要调用的函数都进行了宏定义,以方便在程序中调用
#define OS0_1 HAL_GPIO_WritePin(OS0_GPIO_Port,OS0_Pin,GPIO_PIN_SET);//AD速率控制引脚
#define OS0_0 HAL_GPIO_WritePin(OS0_GPIO_Port,OS0_Pin,GPIO_PIN_RESET);
#define OS1_1