• 基于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,其结果还是比较接近实际值。

  • 相关阅读:
    bootstrap经典总结
    C#操作CAD-读取和修改数据
    C#操作CAD-调用winform
    C#操作CAD-初始化、引用dll
    oracle查询时间
    ArcGIS API for JavaScript开发环境搭建及第一个实例demo
    mysql命令大全
    第一次配置mysql5.6
    ExcelHelper
    excel常用函数
  • 原文地址:https://www.cnblogs.com/wen2376/p/3286109.html
Copyright © 2020-2023  润新知