本实验是用ADC0809CCN进行数据采样,并用7段数码管进行显示。

  ADC0809由一个8路模拟开关、一个地址锁存与译码器、一个A/D转换器和一个三态输出锁存器组成。多路开关可选通8个模拟通道,允许8路模拟量分时输入,共用A/D转换器进行转换。三态输出锁器用于锁存A/D转换完的数字量,当OE端为高电平时,才可以从三态输出锁存器取走转换完的数据。如下图所示。

时序图(本实验用上升沿去采数据):

原理图:

工作方式:

ALE为地址锁存允许输入线,高电平有效。当ALE线为高电平时,地址锁存与译码器将A,B,C三条地址线的地址信号进行锁存,经译码后被选中的通道的模拟量进入转换器进行转换。A,B和C为地址输入线,用于选通IN0-IN7上的一路模拟量输入,这里选通IN0。START为转换启动信号。当START上跳沿时,所有内部寄存器清零;下跳沿时,开始进行A/D转换;在转换期间,START应保持低电平。EOC为转换结束信号,在转换期间EOC为低。当EOC在为高电平时,表明转换结束;否则,表明正在进行A/D转换。OE为输出允许信号,用于控制三条输出锁存器向FPGA输出转换得到的数据。OE=1,输出转换得到的数据;OE=0,输出数据线呈高阻状态。D7-D0为数字量输出线,可以得到状态图。

状态图:

代码实现:

adc0809_control.v

  1. module adc0809_control(
  2. //input
  3. sys_clk,
  4. rst_n,
  5. eoc,//adc转换结束信号标志
  6. data,//adc转换出的数据,
  7.  
  8. //ouput
  9. clk_adc,//给adc的时钟500HZ
  10. ale,//adc地址锁存
  11. start,//启动adc
  12. address,//adc地址选通
  13. oe,//控制adc数据传出
  14. seg_data//传给数码显示
  15. );
  16. input sys_clk;//27MHZ
  17. input rst_n;
  18. input eoc;
  19. input [:] data;
  20.  
  21. output clk_adc;
  22. output ale;
  23. output start;
  24. output [:] address;
  25. output oe;
  26. output [:] seg_data;
  27. /*********************************************/
  28. parameter IDLE = 'd0,
  29. ALE = 'd1,
  30. START_P = 'd2,
  31. START_N = 'd3,
  32. CHECK_EOC_P = 'd4,
  33. CHECK_EOC_N = 'd5,
  34. OE = 'd6,
  35. SEND_DATA = 'd7;
  36. /*********************************************/
  37. //产生500kHZ的频率
  38. reg clk_adc;
  39. reg [:] cnt;
  40. always @(posedge sys_clk or negedge rst_n)
  41. if(!rst_n) begin
  42. cnt <= 'd0;
  43. clk_adc <= 'b0;
  44. end
  45. else if(cnt == 'd26)
  46. begin
  47. cnt <= 'd0;
  48. clk_adc <= ~clk_adc;
  49. end
  50. else
  51. cnt <= cnt + 'b1;
  52. /*********************************************/
  53. reg start;
  54. reg ale;
  55. reg oe;
  56. reg [:] data_temp;
  57. reg [:] state;
  58. //always @(clk_adc or rst_n or eoc)//用组合逻辑方式不行,采集不到数据
  59. always @(posedge clk_adc or negedge rst_n)
  60. if(!rst_n) begin
  61. start <= 'b0;
  62. ale <= 'b0;
  63. oe <= 'b0;
  64. data_temp <= 'd0;
  65. state <= IDLE;
  66. end
  67. else
  68. case(state)
  69. IDLE: begin
  70. ale <= 'b0;
  71. start <= 'b0;
  72. oe <= 'b0;
  73. state <= ALE;
  74. end
  75.  
  76. ALE: begin
  77. ale <= 'b1;
  78. start <= 'b0;
  79. state <= START_P;
  80. end
  81.  
  82. START_P: begin
  83. ale <= 'b0;//1
  84. start <= 'b1;
  85. state <= START_N;
  86. end
  87.  
  88. START_N: begin
  89. ale <= 'b0;
  90. start <= 'b0;
  91. state <= CHECK_EOC_P;
  92. end
  93.  
  94. CHECK_EOC_P: begin
  95. if(eoc == 'b1)
  96. state = CHECK_EOC_P;
  97. else
  98. state = CHECK_EOC_N;//检测到了低电平,说明开始转换
  99. end
  100.  
  101. CHECK_EOC_N: begin
  102. if(eoc == 'b0)
  103. state <= CHECK_EOC_N;//等待转换的结束
  104. else
  105. state <= OE;
  106. end
  107.  
  108. OE: begin
  109. oe <= 'b1;
  110. state <= SEND_DATA;
  111. end
  112.  
  113. SEND_DATA: begin
  114. data_temp <= data;
  115. state <= IDLE;
  116. end
  117.  
  118. default: begin
  119. ale <= 'b0;
  120. start <= 'b0;
  121. oe <= 'b0;
  122. state <= IDLE;
  123. end
  124. endcase
  125. /*********************************************/
  126. assign address = 'b000;//选通IN0
  127. assign seg_data = data_temp;
  128. /*********************************************/
  129. endmodule

display_control.v

  1. module display_control(
  2. //input
  3. sys_clk,
  4. rst_n,
  5. seg_data,
  6.  
  7. //output
  8. slec_wei,
  9. slec_duan
  10. );
  11. input rst_n;
  12. input [:] seg_data;
  13. input sys_clk;
  14.  
  15. output [:] slec_wei;
  16. output [:] slec_duan;
  17. /*****************************************/
  18. parameter SEG_NUM0 = 'h3f,//c0,
  19. SEG_NUM1 = 'h06,//f9,
  20. SEG_NUM2 = 'h5b,//a4,
  21. SEG_NUM3 = 'h4f,//b0,
  22. SEG_NUM4 = 'h66,//99,
  23. SEG_NUM5 = 'h6d,//92,
  24. SEG_NUM6 = 'h7d,//82,
  25. SEG_NUM7 = 'h07,//F8,
  26. SEG_NUM8 = 'h7f,//80,
  27. SEG_NUM9 = 'h6f,//90,
  28. SEG_NUMa = 'h77,
  29. SEG_NUMb = 'h7c,
  30. SEG_NUMc = 'h39,
  31. SEG_NUMd = 'h5e,
  32. SEG_NUMe = 'h79,
  33. SEG_NUMf = 'h71;
  34. /*****************************************/
  35. reg[:] cnt;
  36. always @ (posedge sys_clk or negedge rst_n)
  37. if(!rst_n) cnt <= 'd0;
  38. else cnt <= cnt+'b1;
  39. /*****************************************/
  40. wire[:] num; //用两位数码管显示
  41. assign num = cnt[] ? seg_data[:] : seg_data[:];
  42. assign slec_wei[] = cnt[];
  43. assign slec_wei[] = ~cnt[];
  44.  
  45. //由于板上数码管是四位,另两位不点亮
  46. assign slec_wei[] = 'b1;
  47. assign slec_wei[] = 'b1;
  48.  
  49. reg [:] slec_duan;
  50. always @ (posedge sys_clk)
  51. case(num) //进行编码
  52. 'h0: slec_duan <= SEG_NUM0;
  53. 'h1: slec_duan <= SEG_NUM1;
  54. 'h2: slec_duan <= SEG_NUM2;
  55. 'h3: slec_duan <= SEG_NUM3;
  56. 'h4: slec_duan <= SEG_NUM4;
  57. 'h5: slec_duan <= SEG_NUM5;
  58. 'h6: slec_duan <= SEG_NUM6;
  59. 'h7: slec_duan <= SEG_NUM7;
  60. 'h8: slec_duan <= SEG_NUM8;
  61. 'h9: slec_duan <= SEG_NUM9;
  62. 'ha: slec_duan <= SEG_NUMa;
  63. 'hb: slec_duan <= SEG_NUMb;
  64. 'hc: slec_duan <= SEG_NUMc;
  65. 'hd: slec_duan <= SEG_NUMd;
  66. 'he: slec_duan <= SEG_NUMe;
  67. 'hf: slec_duan <= SEG_NUMf;
  68. default:slec_duan <= SEG_NUM0;
  69. endcase
  70. /*****************************************/
  71. endmodule

adc0809_top.v

  1. module adc0809_top(//input
  2. sys_clk,
  3. rst_n,
  4. eoc,
  5. data,
  6.  
  7. //output
  8. clk_adc,
  9. ale,
  10. start,
  11. address,
  12. oe,
  13. slec_wei,
  14. slec_duan
  15. );
  16. input sys_clk;//27MHZ
  17. input rst_n;
  18. input [:] data;
  19. input eoc;
  20.  
  21. output clk_adc;
  22. output ale;
  23. output start;
  24. output [:] address;
  25. output oe;
  26. output [:] slec_wei;
  27. output [:] slec_duan;
  28.  
  29. wire [:] seg_data;
  30.  
  31. adc0809_control u1(
  32. //input
  33. .sys_clk(sys_clk),
  34. .rst_n(rst_n),
  35. .eoc(eoc),//adc转换结束信号标志
  36. .data(data),//adc转换出的数据,
  37.  
  38. //ouput
  39. .clk_adc(clk_adc),//给adc的时钟500HZ
  40. .ale(ale),//adc地址锁存
  41. .start(start),//启动adc
  42. .address(address),//adc地址选通
  43. .oe(oe),//控制adc数据传出
  44. .seg_data(seg_data)//传给数码显示
  45. );
  46.  
  47. display_control u2(
  48. //input
  49. .sys_clk(sys_clk),
  50. .rst_n(rst_n),
  51. .seg_data(seg_data),
  52.  
  53. //output
  54. .slec_wei(slec_wei),
  55. .slec_duan(slec_duan)
  56. );
  57. endmodule

仿真代码:

  1. `timescale ns/ ps
  2. module adc0809_top_vlg_tst();
  3. // constants
  4. // general purpose registers
  5. reg eachvec;
  6. // test vector input registers
  7. reg [:] data;
  8. reg eoc;
  9. reg rst_n;
  10. reg sys_clk;
  11. // wires
  12. wire [:] address;
  13. wire ale;
  14. wire clk_adc;
  15. wire oe;
  16. wire [:] slec_duan;
  17. wire [:] slec_wei;
  18. wire start;
  19.  
  20. // assign statements (if any)
  21. adc0809_top i1 (
  22. // port map - connection between master ports and signals/registers
  23. .address(address),
  24. .ale(ale),
  25. .clk_adc(clk_adc),
  26. .data(data),
  27. .eoc(eoc),
  28. .oe(oe),
  29. .rst_n(rst_n),
  30. .slec_duan(slec_duan),
  31. .slec_wei(slec_wei),
  32. .start(start),
  33. .sys_clk(sys_clk)
  34. );
  35. initial
  36. begin
  37. sys_clk =;
  38. rst_n = ;
  39. #;
  40. rst_n = ;
  41. end
  42. always # sys_clk = ~sys_clk;
  43.  
  44. initial begin
  45. data = 'h0;
  46. eoc = ;
  47. end
  48.  
  49. always @(negedge start)
  50. begin
  51. #;
  52. eoc = ;
  53. data <= data + 'b1;
  54. #;
  55. eoc = ;
  56. end
  57. endmodule

仿真波形:

调试过程的心情:

  看完人家的例子,时序图也看明白了,然后开始写自己的代码,在编译时也遇到很奇怪的问题,如下图,代码中找了许久都没找到,这让很头疼,后来我就把关于case这段语句剪切掉,只留接口定义部分,进行编译,编译OK,我在把刚才剪切掉的代码复制原位置(完全是一摸一样),编译既然通过了,很郁闷,这个问题一直没有弄明白,实在想不通,就跳过这个问题,既然编译通过了,那赶紧下载到板子上去验证吧,下完之后,显示两个0,变阻器无论怎么调都没用,哎,无语了,只能回过头在检查代码,看是否哪里有错误。实在检查不出来,只有仿真看时序对不对哦,仿真后还真没看出来有啥问题(很可能当时仿真代码没有写好,其实也没仔细的看波形),然后反复的看别人的代码,对照自己的代码是否哪里写的不对。最终把这个语句always @(clk_adc or rst_n or eoc)改为时序逻辑always @(posedge clk_adc or negedge rst_n)就可以了 ,终于看到了数码显示数据了,调电位器,数据也在变动,很高兴啊。。。。

总结:

1、例子最好找一个比较规范的例子,可以到网上收集相同的例子,进行参考对比。

2、遇到问题时,不要气馁,沉住气。问题总会解决的。

基于Verilog HDL的ADC0809CCN数据采样的更多相关文章

  1. 基于Verilog HDL 各种实验

    菜鸟做的的小实验链接汇总:           1.基于Verilog HDL 的数字时钟设计 2.乘法器 3.触发器(基本的SR触发器.同步触发器.D触发器) 4.基于Verilog HDL的ADC ...

  2. 基于Verilog HDL 的数字电压表设计

    本次实验是在“基于Verilog HDL的ADC0809CCN数据采样”实验上进一步改进,利用ADC0809采集到的8位数据,进行BCD编码,以供查表方式相加进行显示,本次实验用三位数码管. ADC0 ...

  3. 基于Verilog HDL整数乘法器设计与仿真验证

    基于Verilog HDL整数乘法器设计与仿真验证 1.预备知识 整数分为短整数,中整数,长整数,本文只涉及到短整数.短整数:占用一个字节空间,8位,其中最高位为符号位(最高位为1表示为负数,最高位为 ...

  4. 基于Verilog HDL 的数字时钟设计

    基于Verilog HDL的数字时钟设计 一.实验内容:     利用FPGA实现数字时钟设计,附带秒表功能及时间设置功能.时间设置由开关S1和S2控制,分别是增和减.开关S3是模式选择:0是正常时钟 ...

  5. 基于Verilog HDL的二进制转BCD码实现

    在项目设计中,经常需要显示一些数值,比如温湿度,时间等等.在数字电路中数据都是用二进制的形式存储,要想显示就需要进行转换,对于一个两位的数值,对10取除可以得到其十位的数值,对10取余可以得到个位的数 ...

  6. 基于Verilog HDL的超前进位全加器设计

    通常我们所使用的加法器一般是串行进位,将从输入的ci逐位进位地传递到最高位的进位输出co,由于电路是有延迟的,这样的长途旅行是需要时间的,所以为了加快加法器的运算,引入了超前进位全加器. 全加器的两个 ...

  7. paper:基于verilog HDL 的高速可综合FSM设计

    1.寄存器输出型状态机 VS 组合逻辑输出型状态机 2.状态编码方法 这块讲的不好,也比较少. 3.系统设计中模块划分的指导性原则

  8. 自己动手写处理器之第二阶段(2)——Verilog HDL简单介绍

    将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第六篇.我尽量每周四篇 2.3 Verilog HDL简单介绍 本书实现的OpenMIPS处理器是使用Verilog HDL编 ...

  9. 关于初次使用Verilog HDL语言需要懂的基本语法

    关于初次使用Verilog HDL语言需要懂的基本语法 1.常量 数字表达式全面的描述方式为:<位宽><进制><数字> 8’b10101100,表示位宽为8的二进制 ...

随机推荐

  1. CSS样式与选择器

    CSS构造块的样式: 1.  h1{color:red;background-color:yellow} 其中:h1是选择器,花括号内是声明部分.多个声明之间用分号隔开. 2.为样式规则添加注释:/* ...

  2. js基础和工具库

    /* * 作者: 胡乐 * 2015/4/18 * js 基础 和 工具库 * * * */ //根据获取对象 function hGetId(id){ return document.getElem ...

  3. linux文件特殊属性介绍(s,s,t)

    文件的权限有rwx这3个读.写.执行的权限.但是,怎么 /tmp权限有些奇怪?还有, /usr/bin/passwd也有些奇怪,怎么回事呢? [root@linux ~]# ls -ld /tmp ; ...

  4. 通过CSS实现各种方向的三角形

    #triangle-up { width: 0; height: 0; border-left: 50px solid transparent; border-right: 50px solid tr ...

  5. Codeforce#354_B_Pyramid of Glasses(模拟)

    题目连接:http://codeforces.com/contest/676/problem/B 题意:给你一个N层的杯子堆成的金字塔,倒k个杯子的酒,问倒完后有多少个杯子的酒是满的 题解:由于数据不 ...

  6. debian下安装repo

    1.去google网站上下载repo脚本(用php语言写成的脚本) https://gerrit.googlesource.com/git-repo/+/stable/repo 可以将脚本复制下来并保 ...

  7. [转]Flash、Flex、AS3.0框架及类库资源收集之十全大补

    原文地址:http://www.d5power.com/portal.php?mod=view&aid=27 APIs.Libs.Components1.as3ebaylibhttp://co ...

  8. centos精简系统 源码安装客户端git

    CentOS的yum源中git版本比较低,需要最新版本git,只能自己编译安装,现在记录下编译安装的内容,留给自己备忘. 对于精简型的centos系统,会缺少很多依赖包和插件,要源码安装客户端git, ...

  9. Nginx 和 IIS 实现动静分离【转载】

    前段时间,搞Nginx+IIS的负载均衡,想了解的朋友,可以看这篇文章:<nginx 和 IIS 实现负载均衡>,然后也就顺便研究了Nginx + IIS 实现动静分离.所以,一起总结出来 ...

  10. rsync unison+inotify双向实时同步

    rsync多线程同步 A:文件服务器 ip:10.10.1.10 B:备份服务器 ip:10.10.1.11 1.在B服务器上安装rsync软件 tar xzvf rsync-3.1.0.tar.gz ...