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

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

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

基于Verilog HDL的ADC0809CCN数据采样

原理图:

基于Verilog HDL的ADC0809CCN数据采样

工作方式:

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为数字量输出线,可以得到状态图。

状态图:基于Verilog HDL的ADC0809CCN数据采样

 代码实现:

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 [7:0] data;
 20 
 21 output clk_adc;
 22 output ale;
 23 output start;
 24 output [2:0] address;
 25 output oe;
 26 output [7:0] seg_data;
 27 /*********************************************/
 28 parameter     IDLE         = 3'd0,
 29             ALE             = 3'd1,
 30             START_P     = 3'd2,
 31             START_N     = 3'd3,
 32             CHECK_EOC_P = 3'd4,
 33             CHECK_EOC_N = 3'd5,
 34             OE             = 3'd6,
 35             SEND_DATA   = 3'd7;
 36 /*********************************************/
 37 //产生500kHZ的频率
 38 reg clk_adc;
 39 reg [4:0] cnt;
 40 always @(posedge sys_clk or negedge rst_n)
 41 if(!rst_n) begin
 42     cnt  <= 5'd0;
 43     clk_adc <= 1'b0;
 44 end
 45 else if(cnt == 5'd26)
 46 begin
 47     cnt <= 5'd0;
 48     clk_adc <= ~clk_adc;
 49 end
 50 else
 51     cnt <= cnt + 1'b1;
 52 /*********************************************/
 53 reg start;
 54 reg ale;
 55 reg oe;
 56 reg [7:0] data_temp;
 57 reg [2:0] 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 <= 1'b0;
 62     ale <= 1'b0;
 63     oe <= 1'b0;
 64     data_temp <= 8'd0;
 65     state <= IDLE;
 66 end
 67 else 
 68     case(state)
 69     IDLE: begin
 70         ale <= 1'b0;
 71         start <= 1'b0;
 72         oe <= 1'b0;
 73         state <= ALE;
 74     end
 75     
 76     ALE: begin
 77         ale <= 1'b1;
 78         start <= 1'b0;
 79         state <= START_P;
 80     end
 81     
 82     START_P: begin
 83         ale <= 1'b0;//1
 84         start <= 1'b1;
 85         state <= START_N;
 86     end
 87     
 88     START_N: begin
 89         ale <= 1'b0;
 90         start <= 1'b0;
 91         state <= CHECK_EOC_P;
 92     end
 93     
 94     CHECK_EOC_P: begin
 95         if(eoc == 1'b1)
 96             state = CHECK_EOC_P;
 97         else
 98             state = CHECK_EOC_N;//检测到了低电平,说明开始转换
 99     end
100 
101     CHECK_EOC_N: begin
102         if(eoc == 1'b0)
103             state <= CHECK_EOC_N;//等待转换的结束
104         else
105             state <= OE;
106     end
107     
108     OE: begin
109         oe <= 1'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 <= 1'b0;
120         start <= 1'b0;
121         oe <= 1'b0;
122         state <= IDLE;
123     end
124     endcase
125 /*********************************************/
126 assign address = 3'b000;//选通IN0    
127 assign seg_data = data_temp;
128 /*********************************************/
129 endmodule
View Code

相关文章: