目录

一、AD7606数据手册

1.ADC采样原理

2.AD7606使用手册

二、实例

1.状态转移图

2.Verilog代码

3.仿真结果

总结



一、AD7606数据手册

1.ADC采样原理

在实际的工程中,经前端传感器出来的信号基本都是模拟信号,而后端mcu主控芯片是基于数字信号进行处理的,因此需要用到ADC进行模数转换。ADC包括三个基本功能:抽样量化编码。抽样过程是将模拟信号在时间上离散化,使之成为抽样信号;量化是将抽样信号的幅度离散化使之成为数字信号;而编码则是将数字信号转换成数字系统所能接受的形式。如何实现这三个功能就决定了ADC的形式和性能。同时,ADC的分辨率(即采样精度)越高,需要的转换时间就越长,转换速度就越低,故ADC的分辨率和转换速率两者总是相互制约的。

对于一个16位的ADC来说,如果输入的模拟信号幅值在0到3.3V,那么采样后输出的数字信号对应的应该在0到65535,采样精度是1/65536。因此,我们发现,采样位数越高的AD,其采样精度越高,信噪比越大,其越接近原始信号。

采样率即是两个采样点之间的间隔时间,两个采样点之间的间隔时间越短,其采样率越高。根据奈奎斯特采样定律,信号的采样率应该大于其最大频率的2倍。而实际应用中,通常选择信号最大频率的几十倍的采样率,为了更加准确有效的恢复出原始信号。

2.AD7606使用手册

AD7606是16位,8通道同步采集模数数据采集系统。各器件均内置模拟输入钳位保护、二阶抗混叠滤波器、跟踪保持放大器、16位电荷再分配逐次逼近型模数转换器、灵活的数字滤波器、2.5V基准电压源、基准电压缓冲以及高速串行和并行接口。

AD7606采用5V单电源供电,可以处理正负10V和正负5V真双极性输入信号,同时所有通道均能以高达200kSPS的吞吐速率采样。输入钳位保护电路可以耐受最高达正负16.5V的电压。无论以何种采样频率工作,  AD7606的模拟输入阻抗均为1MΩ。它采用单电源工作方式,具有片内滤波和高输入阻抗,因此无需驱动运算放大器和外部双极性电源。AD7606抗混叠滤波器的3dB截止频率22kHz;当采样率为200kSPS时,它具有40dB抗混叠抑制特性。灵活的数字滤波器采用引脚驱动,可以改善信噪比(SNR),并降低3dB带宽。

下面给出AD7606引脚配置和功能描述,下图是AD7606的引脚图:

下图给出AD7606的引脚功能描述:

其中,AD7606可以选择三种工作模式,通过配置引脚PAR/SER/BYTE SEL和DB15,如下图所示:

上述三种工作模式都需要首先给AD7606一个转换信号,如果是各通道同步采样,则需要同时给出CONVST_A和CONVST_B信号,然后等待BUSY信号,如果选择等待AD转换后读取,则需要等待BUSY信号拉低后再进行数据读取;如果选择在AD转换期间读取,则不需要等待BUSY信号拉低。下面给出两种不同时刻读取数据的时序图:

在读取数据时,需要首先给AD7606一个读取数据的使能信号CS,接着给出读取数据的时钟信号RD/SCLK,然后AD7606给出相应的数据。

如果工作在并行接口模式,在CS信号拉低后,RD给出8个时钟,分别读取8个通道采集到的数据DATA[15:0],在读取通道1时FRSTDATA信号拉高,时序图如下所示:

如果工作在串行接口模式,在CS信号拉低后,SCLK给出16*4=64个时钟,分别读取DOUTA输出的采集到的通道1~4上的数据和DOUTB上输出的采集到的通道5~8上的数据,在读取通道1时,FRSTDATA信号拉高时序图如下所示:

如果工作在并行字节接口模式,在CS信号拉低后,RD给出2*8=16个时钟,两个时钟为一组,分别读取某一通道采集到的数据的高八位和低八位,数据从DATA[7:0]输出,时序图如下所示:

下表给出上述三种模式对应的时序规格:

二、实例

要求:通过AD7606同步采集八个通道的数据,FPGA按照串行读取的操作,分别读取各通道采集到的数据。

1.状态转移图

共定义九个状态进行转换,通过输入caiji_flag标志信号开始每次的数据采集,当数据采集结束后,输出caiji_over结束信号。

2.Verilog代码

module ad7606_1(input        clk,input        res,input        dout_a,     //ad7606通道a输入串行读取数据input        dout_b,    //ad7606通道b输入串行读取数据input        ad_busy,   //ad7606输入busy信号input        caiji_flag,  //外界输入开始数据采集的标志output   reg ad_cs,     //读ad7606的使能信号output   reg ad_rd,     //读ad7606的时钟信号output   reg ad_convstab  //ad7606开始转换信号,低电平有效);parameter     IDLE         = 9'b0_0000_0001;
parameter     AD_CONV      = 9'b0_0000_0010;
parameter     WAIT_1       = 9'b0_0000_0100;
parameter     WAIT_BUSY    = 9'b0_0000_1000;
parameter     READ_CH15    = 9'b0_0001_0000;
parameter     READ_CH26    = 9'b0_0010_0000;
parameter     READ_CH37    = 9'b0_0100_0000;
parameter     READ_CH48    = 9'b0_1000_0000;
parameter     READ_STOP    = 9'b1_0000_0000; parameter     CONV_TIME         =  5; //AD_CONV状态持续时间等价转换信号低电平持续时间
parameter     WAIT_TIME         =  5; //WAIT_1状态持续时间
parameter     FIV_CLK           =  4;
parameter     CNT_CLK           =  16;   //每个通道一次发送的时钟个数reg           [8:0]stata;
reg           [5:0]cnt  ;   //在数据读取状态表示分频系数
reg           [4:0]cnt_bite;reg           [15:0]databuffa;  //a通道串并转换后存储
reg           [15:0]databuffb;  //b通道串并转换后存储
//存储八个通道采集到的数据
reg           [15:0] data_ch1;
reg           [15:0] data_ch2;
reg           [15:0] data_ch3;
reg           [15:0] data_ch4;
reg           [15:0] data_ch5;
reg           [15:0] data_ch6;
reg           [15:0] data_ch7;
reg           [15:0] data_ch8;
reg           [2 :0] over;
wire               caiji_over;always@(posedge clk or negedge res)if(!res)cnt <= 'd0;else if(stata == AD_CONV)if(cnt == CONV_TIME)cnt <= 'd0;else cnt <= cnt + 1;else if(stata == WAIT_1)if(cnt == WAIT_TIME)cnt <= 'd0;else  cnt <= cnt + 1;else if(stata == WAIT_BUSY)  //为了在下一个状态,cnt从6开始计数,为了让CS和RD信号前后有延时if(ad_busy == 1'b0)cnt <= 'd6;else cnt <= cnt;else if(stata == READ_CH15 || stata == READ_CH26 || stata == READ_CH37 || stata == READ_CH48)if(cnt == (2*FIV_CLK-1))cnt <= 'd0;elsecnt <= cnt + 1;always@(posedge clk or negedge res)if(!res)cnt_bite <=  'd0;else if(stata == READ_CH15 )if(cnt_bite == (CNT_CLK) && cnt == (2*FIV_CLK-1))cnt_bite <= 'd0;else if(cnt == (2*FIV_CLK-1))cnt_bite <= cnt_bite + 1;else cnt_bite <= cnt_bite;else if( stata == READ_CH26 || stata == READ_CH37 || stata == READ_CH48)if(cnt_bite == (CNT_CLK -1) && cnt == (2*FIV_CLK-1))cnt_bite <= 'd0;else if(cnt == (2*FIV_CLK-1))cnt_bite <= cnt_bite + 1;else cnt_bite <= cnt_bite;else cnt_bite <= 'd0;always@(posedge clk or negedge res)if(!res)stata <= 4'd0;else begincase(stata)IDLE         :  if(caiji_flag == 1'b1)stata <= AD_CONV;else stata <= IDLE;AD_CONV      :  if(cnt == CONV_TIME)stata <= WAIT_1;else stata <= AD_CONV;WAIT_1       :  if(cnt == WAIT_1)stata <= WAIT_BUSY;else stata <= WAIT_1;WAIT_BUSY    :  if(ad_busy == 1'b0)stata <= READ_CH15;elsestata <= WAIT_BUSY;                        READ_CH15    :  if(cnt_bite == (CNT_CLK ) && cnt == (2*FIV_CLK-1))stata <= READ_CH26;else stata <= READ_CH15;READ_CH26    :  if(cnt_bite == (CNT_CLK -1) && cnt == (2*FIV_CLK-1))stata <= READ_CH37;else stata <= READ_CH26;READ_CH37    :  if(cnt_bite == (CNT_CLK -1) && cnt == (2*FIV_CLK-1))stata <= READ_CH48;else stata <= READ_CH37;READ_CH48    :  if(cnt_bite == (CNT_CLK -1) && cnt == (2*FIV_CLK-1))stata <= READ_STOP;else stata <= READ_CH48;READ_STOP    :  stata <= IDLE;default:stata <= IDLE;endcaseend //输出信号
always@(posedge clk or negedge res)if(!res)ad_convstab <=  1'b1; else if(stata == AD_CONV)ad_convstab <=  1'b0;else ad_convstab <= 1'b1;always@(posedge clk or negedge res)if(!res)ad_cs <= 1'b1;else if(stata == WAIT_BUSY && ad_busy == 1'b0)ad_cs <= 1'b0;else if(stata == READ_STOP)ad_cs <= 1'b1;else ad_cs <= ad_cs;
always@(posedge clk or negedge res)if(!res)ad_rd <= 1'b1;else if(stata == READ_CH15 || stata == READ_CH26 || stata == READ_CH37 || stata == READ_CH48)if(cnt == (FIV_CLK-1))ad_rd <= 1'b0;else if(cnt == 2*FIV_CLK-1)ad_rd <= 1'b1;else ad_rd <= ad_rd;else ad_rd <= 1'b1;//处理输入的串行数据
always@(posedge clk or negedge res)if(!res)begindatabuffa <= 16'd0;databuffb <= 16'd0;end else if(stata == READ_CH15 || stata == READ_CH26 || stata == READ_CH37 || stata == READ_CH48)beginif(cnt == FIV_CLK && ad_rd == 1'b0)begindatabuffa <= {databuffa[14:0],dout_a};databuffb <= {databuffb[14:0],dout_b};end else begindatabuffa <= databuffa;databuffb <= databuffb; end       end else begindatabuffa <= 16'd0;databuffb <= 16'd0;   end //将采集到的数据存储到data_ch1-data_ch8中
always@(posedge clk or negedge res)if(!res)begindata_ch1   <=   16'd0;data_ch2   <=   16'd0;data_ch3   <=   16'd0;data_ch4   <=   16'd0;data_ch5   <=   16'd0;data_ch6   <=   16'd0;data_ch7   <=   16'd0;data_ch8   <=   16'd0;end else if(stata == READ_CH15 && cnt_bite == (CNT_CLK) && cnt == (2*FIV_CLK-1))begindata_ch1   <= databuffa;data_ch5   <= databuffb;end else if(stata == READ_CH26 && cnt_bite == (CNT_CLK -1) && cnt == (2*FIV_CLK-1))begindata_ch2   <= databuffa;data_ch6   <= databuffb;endelse if(stata == READ_CH37 && cnt_bite == (CNT_CLK -1) && cnt == (2*FIV_CLK-1))begindata_ch3   <= databuffa;data_ch7   <= databuffb;endelse if(stata == READ_CH48 && cnt_bite == (CNT_CLK -1) && cnt == (2*FIV_CLK-1))begindata_ch4   <= databuffa;data_ch8   <= databuffb;endelse begindata_ch1   <=   data_ch1 ;data_ch2   <=   data_ch2 ;data_ch3   <=   data_ch3 ;data_ch4   <=   data_ch4 ;data_ch5   <=   data_ch5 ;data_ch6   <=   data_ch6 ;data_ch7   <=   data_ch7 ;data_ch8   <=   data_ch8 ;end //八个通道采集结束后,对over信号打拍处理,输出over_flag
assign caiji_over = over[2];
always@(posedge clk or negedge res)if(!res)over <= 3'd0;else if(stata == READ_STOP)beginover[0] <= 1'b1;   over[1] <= over[0];over[2] <= over[1];endelse beginover[0] <= 1'b0;    over[1] <= over[0];over[2] <= over[1];     end     endmodule

下面给出tb测试文件:

`timescale 1ns/1ns
module tb1();
reg     clk;
reg     res;
reg     data_b;
reg     data_a;
reg     busy;
reg     caiji_flag;
wire    ad_cs;
wire    ad_rd;
wire    ad_convstab;
reg     ad_convstab_buffer;
wire    convstab_flag;reg    [9:0]cnt;
initial beginclk <= 1'b0;res <= 1'b0;busy <= 1'b0;data_a <= 1'b0;data_b <= 1'b0;caiji_flag <= 1'b0;#100 res <= 1'b1;end
always #10 clk <= ~clk;//检测ad_convstb的下降沿
always@(posedge clk)ad_convstab_buffer <= ad_convstab;
assign convstab_flag = (~ad_convstab)&ad_convstab_buffer;always@(posedge clk or negedge res)if(!res)cnt <= 0;else if(convstab_flag)cnt <= cnt + 1;else if(cnt == 7)cnt <= cnt;else cnt <= cnt + 1;always@(posedge clk)beginif(cnt >5 && cnt <8)begincaiji_flag <= 1'b1;busy       <= 1'b0;end else if(cnt == 8)begincaiji_flag <= 1'b0;busy       <= 1'b0;end  else if(cnt>8 && cnt<20)beginbusy   <= 1'b1;caiji_flag <= 1'b0;end else if(cnt == 20)beginbusy   <= 1'b0;caiji_flag <= 1'b0;end else busy  <=  busy;
end
always@(posedge ad_rd or posedge ad_cs)if(ad_cs)begindata_a <= 1'b0;data_b <= 1'b0;end else begindata_a <= {$random}%2;data_b <= {$random}%2;   end ad7606_1  u_ad7606_1( .                   clk          (clk)    ,.                   res        (res)    ,.                   dout_a       (data_a)    ,             //ad7606 数据.                   dout_b       (data_b)    ,.                   ad_busy      (busy)    ,             //ad7606 busy.                   caiji_flag   (caiji_flag)    ,.                   ad_cs        (ad_cs)    ,                //ad7606 AD 片选.                   ad_rd        (ad_rd)    ,            //ad7606 AD 串行读数据时钟.                   ad_convstab  (ad_convstab)     //ad7606 AD convert start
);
endmodule

3.仿真结果

仿真结果如下图所示:图1给出了前五个状态的时序图,图2给出了后四个状态(数据采集)的时序图,图3给出了整体的时序仿真图。

图1

图2

图3


总结

总体而言,该芯片是一款性能不错的AD芯片,操作时序图相对比较简单,基本能够满足一般系统的性能要求。当然如果系统对数据采集的要求过高,即要求高信噪比,那么在AD选型的过程中可以考虑18位的AD(AD7690、CBM79AD60)或者是24位AD(AD1258)芯片;这里给大家推荐一下AD7690,18位的AD芯片,单通道数据采集,差分输入,串行读取AD数据,其操作时序十分简单,封装为MSOP-10,占用PCB空间较小。

初次创作,难免文章中存在错误,希望读者能够及时纠正并给予私信,望大家共同进步!

FPGA控制AD7606进行数据采集相关推荐

  1. 【FPGA】FPGA对AD7606进行串行数据采集

    个人笔记.这段时间在用FPGA对AD7606进行数据采集,现在把检测过程和遇到的问题记录一下,方便以后避坑.文章最后有相关资料链接. 1.AD7606概述 AD7606是16位,8通道同步采集模数数据 ...

  2. omapl138 fpga三核高速数据采集处理核心平台方案

    支持32路AD采集,32路DA输出. 支持多路RS485.RS232串口: 支持实时系统,控制延时: 支持DSP和ARM的多核通信,提供丰富的采样demo: 支持图形界面编程,触控! 1.OMAP-L ...

  3. STM32F407控制AD7606 采用HAL库的TIM和SPI

    前言 本文介绍基于STM32F407的AD7606 8通道同步采集控制方式,总体思路:PWM驱动AD7606完成模数转换,AD7606转换完成后其BUSY引脚给出下降沿,STM32捕获外部中断并在中断 ...

  4. FPGA 控制 FLASH 之 Startup 原语使用相关链接

    固件远程更新之STARTUPE2原语(fpga控制flash) 上个格式不方便看,看这个转载的: https://blog.csdn.net/Reborn_Lee/article/details/89 ...

  5. FPGA控制AD7768采集

    1.1 FPGA控制AD7768采集 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4) FPGA控制AD7768采集: 5)结束语. 1.1.2 本节引言 "不 ...

  6. FPGA控制不其他芯片

    1.1 FPGA控制不其他芯片 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA控制不其他芯片: 5)结束语. 1.1.2 本节引言 "不积跬步,无以至 ...

  7. ZYNQ FPGA控制LED灯不闪烁

    1.1 ZYNQ FPGA控制LED灯不闪烁 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)ZYNQ FPGA控制LED灯不闪烁: 5)结束语. 1.1.2 本节引言 ...

  8. FPGA采集AD7606串行输源码加讲解

    FPGA采集AD7606串行输源码加讲解 那是2020年,在我上家公司时,由于刚接触FPGA,所以啥也不会,就被大佬安排去写一个国产FPGA的项目,其中就包含AD7606的采集,很遗憾,当时我没能搞定 ...

  9. FPGA控制TDC-GPX2时间间隔测量(一)

    距离上一次使用FPGA控制TDC芯片测量时间间隔已经过去一年多了,当时采用的TDC芯片是TI的一款芯片TDC7200,最后测量结果所能达到的精度为百皮秒级别,最近使用入手了AMS生产的TDC-GPX2 ...

最新文章

  1. OpenCV之highgui 模块. 高层GUI和媒体I/O: 为程序界面添加滑动条 OpenCV的视频输入和相似度测量 用OpenCV创建视频
  2. 软件测试矩阵,什么是过程/数据矩阵(U/C矩阵)?
  3. dell r740如何做raid_戴尔入门级4K、IPS广色域显示器:S2721QS表现如何?
  4. xml节点的添加和删除
  5. Initializer provides no value for this binding element and the binding element has no default value
  6. 蓝桥杯真题-连号区间数-枚举
  7. [2020-09-11 CQBZ/HSZX多校联测 T2] 泰拳警告(组合数+数学期望)
  8. 对mysql的总结与反思_深入了解MySQL,一篇简短的总结
  9. 项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享
  10. web 3d 资源库大全
  11. 虚拟机打开了服务器维护,Vmware WorkStation 打开远程服务器上的虚拟机
  12. RGMII(Reduced Gigabit Media Independent Interface)
  13. 如何通过word自动生成论文目录
  14. 基于Bmob的仿微信即时聊天软件
  15. Pixelmator Pro 2.1.2 图像处理软件
  16. 程序员被离职赔偿18万,房贷八千,只够还一年半,领导:回来上班
  17. 怎样用电池给铁锅作防锈
  18. C语言利用二叉树的操作实现根据给定的字符串生成二叉树并前序、中序、后序输出二叉树。
  19. gitlab项目的备份与迁移
  20. 机器学习第三章笔记——决策树

热门文章

  1. MySQL创建数据库得语句是什么_创建数据库的语句是什么
  2. Android 高级开发 JNI NDK 介绍与使用
  3. 清华毕业程序员国企干了14年,去应聘小公司,看到工资后愣了
  4. mysql通过股票代码查数据_如何在交易数据中查询各个版本交易量前三的股票?(MySQL分组排名)...
  5. Notepad++ 安装 HexEditor 插件
  6. win10使用administrator登录却仍然没权限
  7. html怎样调节字间距,css怎么调整字间距?
  8. AndroidStudio:The number of method references in a .dex file cannot exceed 64K错误
  9. JavaWeb HTTP状态 405 - 方法不允许
  10. 【备战NOIP】专题复习1-动态规划-背包问题