zoukankan      html  css  js  c++  java
  • 基于Verilog HDL 的数字电压表设计

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

      ADC0809的8位数数据BCD编码方式,低四位与高四位分开进行编码,其对应值我也是从网上得来的,具体对应值请看代码,编完码得到12位宽的数据后,对两个编码进行相加,如代码中的cout[11:0] = L[11:0] + H[11:0],这里注意,高四位[11:8]、中四位[7:4]、低四位[3:0]。

    假如ADC0809得到的数据是8'hb4,从代码中可以看到,低四位4'h4:  L <= 12'h008;高四位4'hb:  H <= 12'h352;,H+L = 12’h35A,低位为A,大于9,向中位产生进位C0= 1,其低位得加6得到0,故cout[11:0]=12'h360,电压也就是3.60V,然后把360送给数码管进行显示。同理如果中位相加大于9也得向高位进位C1,此时的中位要变为加6后的值。

    代码实现:

    display_control.v

      1 module  display_control(
      2                         //input
      3                         sys_clk,//27MHZ
      4                         rst_n,
      5                         seg_data,//ADC0809传送进来的数据
      6                         
      7                         //output
      8                         slec_wei,
      9                         slec_duan
     10                     );
     11 input rst_n;
     12 input [7:0] seg_data;
     13 input sys_clk;
     14 
     15 output [3:0] slec_wei;
     16 output [6:0] slec_duan;
     17 
     18 /*****************************************/
     19 parameter     SEG_NUM0     = 7'h3f,
     20             SEG_NUM1     = 7'h06,
     21             SEG_NUM2     = 7'h5b,
     22             SEG_NUM3     = 7'h4f,
     23             SEG_NUM4     = 7'h66,
     24             SEG_NUM5     = 7'h6d,
     25             SEG_NUM6     = 7'h7d,
     26             SEG_NUM7     = 7'h07,
     27             SEG_NUM8     = 7'h7f,
     28             SEG_NUM9     = 7'h6f,
     29             SEG_NUMa    = 7'h77,
     30             SEG_NUMb    = 7'h7c,
     31             SEG_NUMc    = 7'h39,
     32             SEG_NUMd    = 7'h5e,
     33             SEG_NUMe    = 7'h79,
     34             SEG_NUMf    = 7'h71;
     35 parameter   T5MS         = 18'd134_999;
     36 /************************************/
     37 //低四位BCD编码
     38 reg [11:0] L;
     39 always @ (posedge sys_clk)
     40     case(seg_data[3:0]) //L = n * 12'h002(n=1、2、3、、f)
     41         4'h1:        L <= 12'h002;
     42         4'h2:        L <= 12'h004;
     43         4'h3:        L <= 12'h006;
     44         4'h4:        L <= 12'h008;
     45         4'h5:        L <= 12'h010;
     46         4'h6:        L <= 12'h012;
     47         4'h7:        L <= 12'h014;
     48         4'h8:        L <= 12'h016;
     49         4'h9:        L <= 12'h018;
     50         4'ha:        L <= 12'h020;
     51         4'hb:        L <= 12'h022;
     52         4'hc:        L <= 12'h024;
     53         4'hd:        L <= 12'h026;
     54         4'he:        L <= 12'h028;
     55         4'hf:        L <= 12'h030;
     56         default :    L <= 12'h000;
     57     endcase
     58 /************************************/
     59 //高四位BCD编码
     60 reg [11:0] H;
     61 always @ (posedge sys_clk)
     62     case(seg_data[7:4])  //H = n * 12'h032(n=1、2、3、、f)
     63         4'h1:        H <= 12'h032;  //12'b0000_0011_0010;
     64         4'h2:        H <= 12'h064;  //12'b0000_0110_0100;
     65         4'h3:        H <= 12'h096;  //12'b0000_1001_0110;
     66         4'h4:        H <= 12'h128;  //12'b0001_0010_1000;
     67         4'h5:        H <= 12'h160;  //12'b0001_0110_0000;
     68         4'h6:        H <= 12'h192;  //12'b0001_1001_0010;
     69         4'h7:        H <= 12'h224;  //12'b0010_0010_0100;
     70         4'h8:        H <= 12'h256;  //12'b0010_0101_0110;
     71         4'h9:        H <= 12'h288;  //12'b0010_1000_1000;
     72         4'ha:        H <= 12'h320;  //12'b0011_0010_0000;
     73         4'hb:        H <= 12'h352;  //12'b0011_0101_0010;
     74         4'hc:        H <= 12'h384;  //12'b0011_1000_0100;
     75         4'hd:        H <= 12'h416;  //12'b0100_0001_0110;
     76         4'he:        H <= 12'h448;  //12'b0100_0100_1000;
     77         4'hf:        H <= 12'h480;  //12'b0100_1000_0000;
     78         default :     H <= 12'h000;  //12'b0000_0000_0000;
     79     endcase
     80 /************************************/
     81 //判断低四位是否大于9并进位
     82 reg c0;
     83 always @ (posedge sys_clk)
     84 begin
     85     if(H[3:0] + L[3:0] > 4'd9) 
     86         c0 <= 1;
     87     else
     88         c0 <= 0;
     89 end
     90 /************************************/
     91 //判断中间四位是否大于9并进位
     92 reg c1;
     93 always @(posedge sys_clk) 
     94 begin
     95     if(H[7:4] + L[7:4] > 4'd9) 
     96         c1 <= 1;
     97     else
     98         c1 <= 0;
     99 end
    100 /***********************************************/
    101 //对进位进行计算,中四位减去2,低四位加上1,是为了校准显示电压与实测电压更为接近,根据情况而定
    102 reg [11:0] cout; 
    103 always @(c1 or c0)
    104 begin
    105     case({c1,c0})
    106         2'b00: begin 
    107             cout[11:8] <= H[11:8] + L[11:8];
    108             cout[7:4] <= H[7:4] + L[7:4] - 4'd2;//减去4'd2是为了校准显示电压,与实际测试更为接近
    109             cout[3:0] <= H[3:0] + L[3:0] + 1'd1;//减去1'd1是为了校准显示电压,与实际测试更为接近
    110         end 
    111         
    112         2'b01: begin 
    113             if((H[7:4] + L[7:4] + 4'b0001) > 9) begin  
    114                 cout[11:8] <= H[11:8] + L[11:8] + 4'b0001;
    115                 cout[7:4] <= H[7:4] + L[7:4] + 4'b0111 - 4'd2;//加上6并加上来自低位上的进位
    116                 cout[3:0] <= H[3:0] + L[3:0]+ 4'b0110 + 1'd1;//加上6
    117             end
    118             else begin 
    119                 cout[11:8] <= H[11:8] + L[11:8];
    120                 cout[7:4] <= H[7:4] + L[7:4] + 4'b0001 - 4'd2;
    121                 cout[3:0] <= H[3:0] + L[3:0] + 4'b0110 + 1'd1;
    122             end 
    123         end
    124         
    125         2'b10:begin 
    126             cout[11:8] <= H[11:8] + L[11:8] + 4'b0001;
    127             cout[7:4] <= H[7:4] + L[7:4] + 4'b0110 - 4'd2;
    128             cout[3:0] <= H[3:0] + L[3:0] + 1'd1;
    129         end  
    130         
    131         2'b11:begin 
    132             cout[11:8] <= H[11:8] + L[11:8] + 4'b0001;
    133             cout[7:4] <= H[7:4] + L[7:4] + 4'b0110 - 4'd2;
    134             cout[3:0] <= H[3:0] + L[3:0] + 4'b0110 + 1'd1;
    135         end 
    136     endcase
    137 end
    138 
    139 /**********************************************/
    140 //5ms计数器
    141 reg [17:0] cnt; 
    142 always @(posedge sys_clk or negedge rst_n)
    143 if(!rst_n) 
    144     cnt <= 18'd0;
    145 else if(cnt == T5MS) 
    146     cnt <= 18'd0;
    147 else
    148     cnt <= cnt + 1'b1;
    149 /**********************************************/    
    150 //通过移位方式进行流水工作,定时开关
    151 reg [2:0] slec_wei_temp;
    152 always @(posedge sys_clk or negedge rst_n)
    153     if(!rst_n) begin
    154         slec_wei_temp <= 3'd011;
    155     end
    156     else if(cnt == T5MS) begin
    157         if(slec_wei_temp == 3'b110)
    158             slec_wei_temp <= 3'b011;
    159         else
    160             slec_wei_temp <= {1'b1,slec_wei_temp[2:1]};
    161     end
    162 
    163 assign slec_wei = {1'b1,slec_wei_temp};
    164 /*****************************************/    
    165 reg [6:0] data0;
    166 always @ (posedge sys_clk)
    167 case(cout[11:8])    //进行编码 高
    168     4'h0: data0 <= SEG_NUM0;
    169     4'h1: data0 <= SEG_NUM1;
    170     4'h2: data0 <= SEG_NUM2;
    171     4'h3: data0 <= SEG_NUM3;
    172     4'h4: data0 <= SEG_NUM4;
    173     4'h5: data0 <= SEG_NUM5;
    174     4'h6: data0 <= SEG_NUM6;
    175     4'h7: data0 <= SEG_NUM7;
    176     4'h8: data0 <= SEG_NUM8;
    177     4'h9: data0 <= SEG_NUM9;
    178     default:data0 <= SEG_NUM0;
    179 endcase
    180 /*****************************************/    
    181 reg [6:0] data1;
    182 always @ (posedge sys_clk)
    183 case(cout[7:4])    //进行编码  中
    184     4'h0: data1 <= SEG_NUM0;
    185     4'h1: data1 <= SEG_NUM1;
    186     4'h2: data1 <= SEG_NUM2;
    187     4'h3: data1 <= SEG_NUM3;
    188     4'h4: data1 <= SEG_NUM4;
    189     4'h5: data1 <= SEG_NUM5;
    
    190     4'h6: data1 <= SEG_NUM6;
    191     4'h7: data1 <= SEG_NUM7;
    192     4'h8: data1 <= SEG_NUM8;
    193     4'h9: data1 <= SEG_NUM9;
    194     default:data1 <= SEG_NUM0;
    195 endcase
    196 /*****************************************/    
    197 reg [6:0] data2;
    198 always @ (posedge sys_clk)
    199 case(cout[3:0])    //进行编码  低
    200     4'h0: data2 <= SEG_NUM0;
    201     4'h1: data2 <= SEG_NUM1;
    202     4'h2: data2 <= SEG_NUM2;
    203     4'h3: data2 <= SEG_NUM3;
    204     4'h4: data2 <= SEG_NUM4;
    205     4'h5: data2 <= SEG_NUM5;
    206     4'h6: data2 <= SEG_NUM6;
    207     4'h7: data2 <= SEG_NUM7;
    208     4'h8: data2 <= SEG_NUM8;
    209     4'h9: data2 <= SEG_NUM9;
    210     default:data2 <= SEG_NUM0;
    211 endcase
    212 /***********************************************/
    213 reg [1:0] num;
    214 always @ (posedge sys_clk or negedge rst_n)
    215 if(!rst_n)
    216     num <= 2'd0;
    217 else if(cnt == T5MS)
    218     num <= num + 1'b1;
    219 else if(num == 2'd3)
    220     num <= 2'd0;
    221 /***********************************************/    
    222 reg [6:0] slec_duan;
    223 always @ (posedge sys_clk)
    224 case(num)
    225     2'd0: slec_duan <= data0;
    226     2'd1: slec_duan <= data1;
    227     2'd2: slec_duan <= data2;
    228 endcase
    229 
    230 endmodule 
    View Code

    adc0809_control.v模块和adc0809_top模块请看基于Verilog HDL的ADC0809CCN数据采样中的代码。

    当代码写完之后,发现显示的数据与实际电压有点偏差,高了0.2V左右,后来我测试了一下ADC0809的工作电压是4.8V,不是5V,我想可能是因为跟这个参考电压有关,为了让显示的数据与实际测试尽量接近,可以在代码中进行校准,我在中四位cout[7:4]减2,低cout[3:0]加1,其结果还是比较接近实际值。

  • 相关阅读:
    流处理 —— Spark Streaming中的Window操作
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.8 提供带注解的限定符元数据
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.7 为自动检测组件提供作用域
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.6 给自动检测组件命名
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.5 在组件中定义bean的元数据
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.4 使用过滤器自定义扫描
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.3 自动检测类和注册bean的定义
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.2 元注解
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.1 @Component和深层的构造型注解
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10 类路径扫描和被管理的组件
  • 原文地址:https://www.cnblogs.com/wen2376/p/3286109.html
Copyright © 2011-2022 走看看