找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6755|回复: 4
打印 上一主题 下一主题
收起左侧

AD采样的FPGA程序书写 Verilog代码

[复制链接]
跳转到指定楼层
楼主
ID:522075 发表于 2019-4-26 11:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
提供一段AD采样的FPGA程序
程序如下

Verilog源程序如下:
  1. //---------------------------------------------------------------------------
  2. //--        文件名                :        Ad_Module.v
  3. //--        作者                :        ZIRCON
  4. //--        描述                :        AD模块
  5. //---------------------------------------------------------------------------

  6. `define AD_CLK_TIME                        10'd49        //1.1M, 909ns,909 / (1 / 50M) = 45 =0x2D
  7. `define AD_CLK_TIME_HALF        10'd24        //909ns / 2 = 454.5ns 45 / 2 = 22        

  8. module Ad_Module
  9. (        
  10.         //Input
  11.         CLK_50M,RST_N,
  12.         //Output
  13.         AD_CS,AD_CLK,AD_DATA,data_out
  14. );
  15.         
  16. //---------------------------------------------------------------------------
  17. //--        外部端口声明
  18. //---------------------------------------------------------------------------
  19. input                                        CLK_50M;                                //时钟的端口,开发板用的50M晶振
  20. input                                        RST_N;                                //复位的端口,低电平复位
  21. input                                        AD_DATA;                                //AD数据端口
  22. output                                AD_CS;                                //AD片选端口
  23. output                                AD_CLK;                                //AD时钟端口,最大不超过1.1MHz
  24. output        [ 7:0]        data_out;                        //AD模数转换完成的数据输出


  25. //---------------------------------------------------------------------------
  26. //--        内部端口声明
  27. //---------------------------------------------------------------------------
  28. reg                                        AD_CS;                                //AD片选信号端口
  29. reg                                        AD_CS_N;                                //AD_CS的下一个状态
  30. reg                                        AD_CLK;                                //AD时钟,最大不超过1.1MHz
  31. reg                                        AD_CLK_N;                        //AD_CLK的下一个状态

  32. reg                [ 2:0]        ad_fsm_cs;                        //状态机的当前状态
  33. reg                [ 2:0]        ad_fsm_ns;                        //状态机的下一个状态

  34. reg                [ 5:0]        time_cnt;                        //用于记录一个时钟所用时间的定时器
  35. reg                [ 5:0]        time_cnt_n;                        //time_cnt的下一个状态
  36. reg                [ 5:0]        bit_cnt;                                //用来记录时钟周期个数的计数器
  37. reg                [ 5:0]        bit_cnt_n;                        //bit_cnt的下一个状态

  38. reg                [ 7:0]        data_out;                        //用来保存稳定的AD数据
  39. reg                [ 7:0]        data_out_n;                        //data_out的下一个状态
  40. reg                [ 7:0]        ad_data_reg;                //用于保存数据的移位寄存器
  41. reg                [ 7:0]        ad_data_reg_n;                //ad_data_reg_n的下一个状态

  42. parameter        FSM_IDLE                        = 3'h0;        //状态机的初始状态;
  43. parameter        FSM_READY                = 3'h1;        //满足CS有效时的第一个1.4us的延时状态
  44. parameter        FSM_DATA                        = 3'h2;        //读取8个数据状态
  45. parameter        FSM_WAIT_CONV        = 3'h3;        //等待转换状态,等待17us;
  46. parameter        FSM_END                        = 3'h4;        //结束的状态

  47. //---------------------------------------------------------------------------
  48. //--        逻辑功能实现        
  49. //---------------------------------------------------------------------------
  50. //时序电路,用来给ad_fsm_cs寄存器赋值
  51. always @ (posedge CLK_50M or negedge RST_N)
  52. begin
  53.         if(!RST_N)                                                                //判断复位
  54.                 ad_fsm_cs <= 1'b0;                                //初始化ad_fsm_cs值
  55.         else
  56.                 ad_fsm_cs <= ad_fsm_ns;                        //用来给ad_fsm_ns赋值
  57. end

  58. //组合电路,用来实现状态机
  59. always @ (*)
  60. begin
  61.         case(ad_fsm_cs)                                                //判断状态机的当前状态
  62.                 FSM_IDLE:
  63.                                                                                                 //3 x 0.909us = 2.727us用于初始化延时
  64.                         if((bit_cnt == 6'd2 ) && (time_cnt == `AD_CLK_TIME))
  65.                                 ad_fsm_ns = FSM_READY;        //如果空闲状态完成就进入延时状态
  66.                         else
  67.                                 ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变
  68.                 FSM_READY:
  69.                                                                                                 //2 x 0.909us = 1.818us用于延迟1.4us
  70.                         if((bit_cnt == 6'd2 ) && (time_cnt == `AD_CLK_TIME))
  71.                                 ad_fsm_ns = FSM_DATA;        //如果延时状态完成就进入读取数据状态
  72.                         else
  73.                                 ad_fsm_ns = ad_fsm_cs;  //否则保持原状态不变
  74.                 FSM_DATA:
  75.                                                                                                 //读取数据8位,1~8个时钟脉冲
  76.                         if((bit_cnt == 6'd8 ) && (time_cnt == `AD_CLK_TIME))
  77.                                 ad_fsm_ns = FSM_WAIT_CONV;//如果读取数据状态完成就进入等待状态
  78.                         else
  79.                                 ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变               
  80.                 FSM_WAIT_CONV:
  81.                                                                                                 //19 x 0.909us = 17.271us用于延迟17us
  82.                         if((bit_cnt == 6'd10) && (time_cnt == `AD_CLK_TIME))
  83.                                 ad_fsm_ns = FSM_END;                //如果等待状态完成就进入读取状态
  84.                         else
  85.                                 ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变  
  86.                 FSM_END:                                                               
  87.                         ad_fsm_ns = FSM_READY;                //完成一次数据转换,进入下一次转换
  88.                 default:ad_fsm_ns = FSM_IDLE;                                
  89.         endcase
  90. end

  91. //时序电路,用来给time_cnt寄存器赋值
  92. always @ (posedge CLK_50M or negedge RST_N)
  93. begin
  94.         if(!RST_N)                                                                //判断复位
  95.                 time_cnt <= 6'h0;                                        //初始化time_cnt值
  96.         else
  97.                 time_cnt <= time_cnt_n;                        //用来给time_cnt赋值
  98. end

  99. //组合电路,实现0.909us的定时计数器
  100. always @ (*)
  101. begin
  102.         if(time_cnt == `AD_CLK_TIME)                //判断0.909us时间
  103.                 time_cnt_n = 6'h0;                                //如果到达0.909us,定时器清零
  104.         else
  105.                 time_cnt_n = time_cnt + 6'h1;        //如果未到0.909us,定时器继续加1
  106. end

  107. //时序电路,用来给bit_cnt寄存器赋值
  108. always @ (posedge CLK_50M or negedge RST_N)
  109. begin
  110.         if(!RST_N)                                                                //判断复位
  111.                 bit_cnt <= 6'h0;                                        //初始化bit_cnt值
  112.         else
  113.                 bit_cnt <= bit_cnt_n;                        //用来给bit_cnt赋值
  114. end

  115. //组合电路,用来记录时钟周期个数的计数器
  116. always @ (*)
  117. begin
  118.         if(ad_fsm_cs != ad_fsm_ns)                        //判断状态机的当前状态
  119.                 bit_cnt_n = 6'h0;                                        //如果当前的状态不等于下一个状态,计时器就清零
  120.         else if(time_cnt == `AD_CLK_TIME_HALF)//判断0.4545us时间
  121.                 bit_cnt_n = bit_cnt + 6'h1;        //如果到达0.4545us,计数器就加1
  122.         else
  123.                 bit_cnt_n = bit_cnt;                                //否则计数器保持不变
  124. end

  125. //时序电路,用来给AD_CLK寄存器赋值
  126. always @ (posedge CLK_50M or negedge RST_N)
  127. begin
  128.         if(!RST_N)                                                                //判断复位
  129.                 AD_CLK <= 1'h0;                                        //初始化AD_CLK值
  130.         else
  131.                 AD_CLK <= AD_CLK_N;                                //用来给AD_CLK赋值
  132. end

  133. //组合电路,用来生成AD的时钟波形
  134. always @ (*)
  135. begin
  136.         if(ad_fsm_cs != FSM_DATA)                        //判断状态机的当前状态
  137.                 AD_CLK_N = 1'h0;                                        //如果当前的状态不等于读取数据状态,AD_CLK_N就置0
  138.         else if(time_cnt == `AD_CLK_TIME_HALF)//判断0.4545us时间
  139.                 AD_CLK_N = 1'h1;                                        //如果到达0.4545us,ADC_CLK_N就置1
  140.         else if(time_cnt == `AD_CLK_TIME)//判断0.909us时间
  141.                 AD_CLK_N = 1'h0;                                        //如果到达0.909us,AD_CLK_N就置0
  142.         else
  143.                 AD_CLK_N = AD_CLK;                                //否则保持不变
  144. end

  145. //时序电路,用来给AD_CS寄存器赋值
  146. always @ (posedge CLK_50M or negedge RST_N)
  147. begin
  148.         if(!RST_N)                                                                //判断复位
  149.                 AD_CS <= 1'h0;                                                //初始化AD_CS值
  150.         else
  151.                 AD_CS <= AD_CS_N;                                        //用来给AD_CS赋值
  152. end

  153. //组合电路,用来生成AD的片选波形
  154. always @ (*)
  155. begin
  156.         if((ad_fsm_cs == FSM_DATA) || (ad_fsm_cs == FSM_READY))//判断状态机的当前状态
  157.                 AD_CS_N = 1'h0;//如果当前的状态等于读取数据状态或等于延时1.4us状态,AD_CS_N就置0
  158.         else
  159.                 AD_CS_N = 1'h1;//如果当前的状态不等于读取数据状态或不等于延时1.4us状态,AD_CS_N就置1
  160. end

  161. //时序电路,用来给ad_data_reg寄存器赋值
  162. always @ (posedge CLK_50M or negedge RST_N)
  163. begin
  164.         if(!RST_N)                                                                //判断复位
  165.                 ad_data_reg <= 8'h0;                                //初始化ad_data_reg值
  166.         else
  167.                 ad_data_reg <= ad_data_reg_n;        //用来给ad_data_reg赋值
  168. end

  169. //组合电路,将AD线上的数据保存到移位寄存器中
  170. always @(*)
  171. begin
  172.         if((ad_fsm_cs == FSM_DATA) && (!AD_CLK) && (AD_CLK_N))//判断每一个时钟的上升沿
  173.                 ad_data_reg_n = {ad_data_reg[6:0],AD_DATA};//将数据存入移位寄存器中,高位优先
  174.         else
  175.                 ad_data_reg_n = ad_data_reg;        //否则保持不变
  176. end

  177. //时序电路,用来给data_out寄存器赋值
  178. always @ (posedge CLK_50M or negedge RST_N)
  179. begin
  180.         if(!RST_N)                                                                //判断复位
  181.                 data_out <= 8'h0;                                        //初始化data_out值
  182.         else
  183.                 data_out <= data_out_n;                        //用来给data_out赋值
  184. end

  185. //组合电路,将移位寄存器中的数据存入data_out中,可用于输出
  186. always @ (*)
  187. begin
  188.         if(ad_fsm_cs == FSM_END)                        //判断复位
  189.                 data_out_n = ad_data_reg;                //初始化data_out值
  190.         else
  191.                 data_out_n = data_out;                        //用来给data_out赋值
  192. end

  193. endmodule
复制代码

所有资料51hei提供下载:
Ad_Module.rar (2.06 KB, 下载次数: 80)



评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:537367 发表于 2019-5-15 20:34 | 只看该作者
这个怎么不出波形
回复

使用道具 举报

板凳
ID:539601 发表于 2019-5-16 09:52 | 只看该作者
厉害正是我要的 谢楼主了
回复

使用道具 举报

地板
ID:302158 发表于 2019-10-8 16:01 | 只看该作者
fpga对ad芯片采集到的数据怎么处理
回复

使用道具 举报

5#
ID:637023 发表于 2019-11-6 20:59 | 只看该作者
好东西啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表