4021|1

2015

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

AD采样的FPGA程序书写 Verilog代码 [复制链接]

 

提供一段AD采样的FPGA程序
程序如下

Verilog源程序如下:

  1. //---------------------------------------------------------------------------
  2. //--        文件名                :        Ad_Module.v
  3. //--        作者                :        ZIRCON
  4. //--        描述                :        AD模块
  5. //---------------------------------------------------------------------------
  6.  
  7. `define AD_CLK_TIME                        10'd49        //1.1M, 909ns,909 / (1 / 50M) = 45 =0x2D
  8. `define AD_CLK_TIME_HALF        10'd24        //909ns / 2 = 454.5ns 45 / 2 = 22        
  9.  
  10. module Ad_Module
  11. (        
  12.         //Input
  13.         CLK_50M,RST_N,
  14.         //Output
  15.         AD_CS,AD_CLK,AD_DATA,data_out
  16. );
  17.         
  18. //---------------------------------------------------------------------------
  19. //--        外部端口声明
  20. //---------------------------------------------------------------------------
  21. input                                        CLK_50M;                                //时钟的端口,开发板用的50M晶振
  22. input                                        RST_N;                                //复位的端口,低电平复位
  23. input                                        AD_DATA;                                //AD数据端口
  24. output                                AD_CS;                                //AD片选端口
  25. output                                AD_CLK;                                //AD时钟端口,最大不超过1.1MHz
  26. output        [ 7:0]        data_out;                        //AD模数转换完成的数据输出
  27.  
  28.  
  29. //---------------------------------------------------------------------------
  30. //--        内部端口声明
  31. //---------------------------------------------------------------------------
  32. reg                                        AD_CS;                                //AD片选信号端口
  33. reg                                        AD_CS_N;                                //AD_CS的下一个状态
  34. reg                                        AD_CLK;                                //AD时钟,最大不超过1.1MHz
  35. reg                                        AD_CLK_N;                        //AD_CLK的下一个状态
  36.  
  37. reg                [ 2:0]        ad_fsm_cs;                        //状态机的当前状态
  38. reg                [ 2:0]        ad_fsm_ns;                        //状态机的下一个状态
  39.  
  40. reg                [ 5:0]        time_cnt;                        //用于记录一个时钟所用时间的定时器
  41. reg                [ 5:0]        time_cnt_n;                        //time_cnt的下一个状态
  42. reg                [ 5:0]        bit_cnt;                                //用来记录时钟周期个数的计数器
  43. reg                [ 5:0]        bit_cnt_n;                        //bit_cnt的下一个状态
  44.  
  45. reg                [ 7:0]        data_out;                        //用来保存稳定的AD数据
  46. reg                [ 7:0]        data_out_n;                        //data_out的下一个状态
  47. reg                [ 7:0]        ad_data_reg;                //用于保存数据的移位寄存器
  48. reg                [ 7:0]        ad_data_reg_n;                //ad_data_reg_n的下一个状态
  49.  
  50. parameter        FSM_IDLE                        = 3'h0;        //状态机的初始状态;
  51. parameter        FSM_READY                = 3'h1;        //满足CS有效时的第一个1.4us的延时状态
  52. parameter        FSM_DATA                        = 3'h2;        //读取8个数据状态
  53. parameter        FSM_WAIT_CONV        = 3'h3;        //等待转换状态,等待17us;
  54. parameter        FSM_END                        = 3'h4;        //结束的状态
  55.  
  56. //---------------------------------------------------------------------------
  57. //--        逻辑功能实现        
  58. //---------------------------------------------------------------------------
  59. //时序电路,用来给ad_fsm_cs寄存器赋值
  60. always @ (posedge CLK_50M or negedge RST_N)
  61. begin
  62.         if(!RST_N)                                                                //判断复位
  63.                 ad_fsm_cs <= 1'b0;                                //初始化ad_fsm_cs值
  64.         else
  65.                 ad_fsm_cs <= ad_fsm_ns;                        //用来给ad_fsm_ns赋值
  66. end
  67.  
  68. //组合电路,用来实现状态机
  69. always @ (*)
  70. begin
  71.         case(ad_fsm_cs)                                                //判断状态机的当前状态
  72.                 FSM_IDLE:
  73.                                                                                                 //3 x 0.909us = 2.727us用于初始化延时 
  74.                         if((bit_cnt == 6'd2 ) && (time_cnt == `AD_CLK_TIME))
  75.                                 ad_fsm_ns = FSM_READY;        //如果空闲状态完成就进入延时状态
  76.                         else
  77.                                 ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变
  78.                 FSM_READY:
  79.                                                                                                 //2 x 0.909us = 1.818us用于延迟1.4us
  80.                         if((bit_cnt == 6'd2 ) && (time_cnt == `AD_CLK_TIME))
  81.                                 ad_fsm_ns = FSM_DATA;        //如果延时状态完成就进入读取数据状态
  82.                         else
  83.                                 ad_fsm_ns = ad_fsm_cs;  //否则保持原状态不变 
  84.                 FSM_DATA:
  85.                                                                                                 //读取数据8位,1~8个时钟脉冲
  86.                         if((bit_cnt == 6'd8 ) && (time_cnt == `AD_CLK_TIME))
  87.                                 ad_fsm_ns = FSM_WAIT_CONV;//如果读取数据状态完成就进入等待状态
  88.                         else
  89.                                 ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变                
  90.                 FSM_WAIT_CONV:
  91.                                                                                                 //19 x 0.909us = 17.271us用于延迟17us
  92.                         if((bit_cnt == 6'd10) && (time_cnt == `AD_CLK_TIME))
  93.                                 ad_fsm_ns = FSM_END;                //如果等待状态完成就进入读取状态
  94.                         else
  95.                                 ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变  
  96.                 FSM_END:                                                                
  97.                         ad_fsm_ns = FSM_READY;                //完成一次数据转换,进入下一次转换
  98.                 default:ad_fsm_ns = FSM_IDLE;                                
  99.         endcase
  100. end
  101.  
  102. //时序电路,用来给time_cnt寄存器赋值
  103. always @ (posedge CLK_50M or negedge RST_N)
  104. begin
  105.         if(!RST_N)                                                                //判断复位
  106.                 time_cnt <= 6'h0;                                        //初始化time_cnt值
  107.         else
  108.                 time_cnt <= time_cnt_n;                        //用来给time_cnt赋值
  109. end
  110.  
  111. //组合电路,实现0.909us的定时计数器
  112. always @ (*)
  113. begin
  114.         if(time_cnt == `AD_CLK_TIME)                //判断0.909us时间
  115.                 time_cnt_n = 6'h0;                                //如果到达0.909us,定时器清零
  116.         else
  117.                 time_cnt_n = time_cnt + 6'h1;        //如果未到0.909us,定时器继续加1
  118. end
  119.  
  120. //时序电路,用来给bit_cnt寄存器赋值
  121. always @ (posedge CLK_50M or negedge RST_N)
  122. begin
  123.         if(!RST_N)                                                                //判断复位
  124.                 bit_cnt <= 6'h0;                                        //初始化bit_cnt值
  125.         else
  126.                 bit_cnt <= bit_cnt_n;                        //用来给bit_cnt赋值
  127. end
  128.  
  129. //组合电路,用来记录时钟周期个数的计数器
  130. always @ (*)
  131. begin
  132.         if(ad_fsm_cs != ad_fsm_ns)                        //判断状态机的当前状态
  133.                 bit_cnt_n = 6'h0;                                        //如果当前的状态不等于下一个状态,计时器就清零
  134.         else if(time_cnt == `AD_CLK_TIME_HALF)//判断0.4545us时间
  135.                 bit_cnt_n = bit_cnt + 6'h1;        //如果到达0.4545us,计数器就加1
  136.         else
  137.                 bit_cnt_n = bit_cnt;                                //否则计数器保持不变
  138. end
  139.  
  140. //时序电路,用来给AD_CLK寄存器赋值
  141. always @ (posedge CLK_50M or negedge RST_N)
  142. begin
  143.         if(!RST_N)                                                                //判断复位
  144.                 AD_CLK <= 1'h0;                                        //初始化AD_CLK值
  145.         else
  146.                 AD_CLK <= AD_CLK_N;                                //用来给AD_CLK赋值
  147. end
  148.  
  149. //组合电路,用来生成AD的时钟波形
  150. always @ (*)
  151. begin
  152.         if(ad_fsm_cs != FSM_DATA)                        //判断状态机的当前状态
  153.                 AD_CLK_N = 1'h0;                                        //如果当前的状态不等于读取数据状态,AD_CLK_N就置0
  154.         else if(time_cnt == `AD_CLK_TIME_HALF)//判断0.4545us时间
  155.                 AD_CLK_N = 1'h1;                                        //如果到达0.4545us,ADC_CLK_N就置1
  156.         else if(time_cnt == `AD_CLK_TIME)//判断0.909us时间
  157.                 AD_CLK_N = 1'h0;                                        //如果到达0.909us,AD_CLK_N就置0
  158.         else
  159.                 AD_CLK_N = AD_CLK;                                //否则保持不变
  160. end
  161.  
  162. //时序电路,用来给AD_CS寄存器赋值
  163. always @ (posedge CLK_50M or negedge RST_N)
  164. begin
  165.         if(!RST_N)                                                                //判断复位
  166.                 AD_CS <= 1'h0;                                                //初始化AD_CS值
  167.         else
  168.                 AD_CS <= AD_CS_N;                                        //用来给AD_CS赋值
  169. end
  170.  
  171. //组合电路,用来生成AD的片选波形
  172. always @ (*)
  173. begin
  174.         if((ad_fsm_cs == FSM_DATA) || (ad_fsm_cs == FSM_READY))//判断状态机的当前状态
  175.                 AD_CS_N = 1'h0;//如果当前的状态等于读取数据状态或等于延时1.4us状态,AD_CS_N就置0
  176.         else
  177.                 AD_CS_N = 1'h1;//如果当前的状态不等于读取数据状态或不等于延时1.4us状态,AD_CS_N就置1
  178. end
  179.  
  180. //时序电路,用来给ad_data_reg寄存器赋值
  181. always @ (posedge CLK_50M or negedge RST_N)
  182. begin
  183.         if(!RST_N)                                                                //判断复位
  184.                 ad_data_reg <= 8'h0;                                //初始化ad_data_reg值
  185.         else
  186.                 ad_data_reg <= ad_data_reg_n;        //用来给ad_data_reg赋值
  187. end
  188.  
  189. //组合电路,将AD线上的数据保存到移位寄存器中
  190. always @(*)
  191. begin
  192.         if((ad_fsm_cs == FSM_DATA) && (!AD_CLK) && (AD_CLK_N))//判断每一个时钟的上升沿
  193.                 ad_data_reg_n = {ad_data_reg[6:0],AD_DATA};//将数据存入移位寄存器中,高位优先
  194.         else
  195.                 ad_data_reg_n = ad_data_reg;        //否则保持不变
  196. end
  197.  
  198. //时序电路,用来给data_out寄存器赋值
  199. always @ (posedge CLK_50M or negedge RST_N)
  200. begin
  201.         if(!RST_N)                                                                //判断复位
  202.                 data_out <= 8'h0;                                        //初始化data_out值
  203.         else
  204.                 data_out <= data_out_n;                        //用来给data_out赋值
  205. end
  206.  
  207. //组合电路,将移位寄存器中的数据存入data_out中,可用于输出
  208. always @ (*)
  209. begin
  210.         if(ad_fsm_cs == FSM_END)                        //判断复位
  211.                 data_out_n = ad_data_reg;                //初始化data_out值
  212.         else
  213.                 data_out_n = data_out;                        //用来给data_out赋值
  214. end
  215.  
  216. endmodule

最新回复

楼主,这是哪个AD芯片的驱动哦   详情 回复 发表于 2019-10-16 20:45
 
点赞 关注

回复
举报

52

帖子

0

TA的资源

一粒金砂(中级)

沙发
 

楼主,这是哪个AD芯片的驱动哦

 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表