ad7928

module    ad_pro(
        clk,rst_n,
        smg1,smg2,smg3,
        dout,cs_n,din,clk_50k//12.5M
);
input        clk;
input        rst_n;
input        dout;
output    reg    [7:0]        smg1;
output    reg    [7:0]        smg2;
output    reg    [7:0]        smg3;
output    reg        cs_n;
output    reg        din;
output    reg        clk_50k;

//50K时钟
reg        [8:0]        cnt_50k;
always@(negedge clk or negedge rst_n)
    if(!rst_n)begin
        cnt_50k <= 'd0;
        clk_50k <= 'd0;
    end
    else if(cnt_50k == 2'd2)begin        //12.5M
        cnt_50k <= 'd0;
        clk_50k =~ clk_50k;
    end
    else
        cnt_50k <= cnt_50k + 1'b1;
        
        
//fsm
parameter    din_regis = 16'b100_001_110_001_0000;
reg        [3:0]        state;
reg        [15:0]    ad_buffer;
reg        [9:0]        ad_buffer1;
reg        [3:0]        num_din;
reg        [3:0]        num_dout;
reg        [15:0]    temp;    
always @(posedge clk_50k or negedge rst_n)
    if(!rst_n)begin
        cs_n <= 1'd1;
        din <= 1'd1;
        state <= 'd0;
        num_din <= 4'd15;
        num_dout <= 'd0;
        ad_buffer <= 'd0;
        ad_buffer1 <= 'd0;
    end
    else
    case(state)
    4'd0:begin
            cs_n <= 1'd1;
            state <= state + 1'b1;
            num_din <= 4'd15;
            num_dout <= 4'd0;
            ad_buffer <= 'd0;
            //ad_buffer1 <= 'd0;
        end
    4'd1:begin
            //cs_n <= 1'd0;
            //din <= 1'd1;
            state <= state + 1'b1;
        end
    4'd2:begin   //写寄存器
            cs_n <= 1'd0;
            din <= (din_regis >> num_din) & 1;
            num_din <= num_din - 1'b1;
            ad_buffer <= (ad_buffer << 1) | dout;
            num_dout <= num_dout + 1'b1;
            if(num_dout == 4'd15 && num_din == 4'd0)
                state <= state + 1'b1;
            else
                state <= state;
        end
    4'd3:begin
            ad_buffer1 <= (ad_buffer[11:4]*100/51);
            cs_n <= 1'd1;
            state <= 1'd0;
        end
    endcase
//smg display
//0~9的键值  共阴极
parameter _0=8'hc0,_1=8'hf9,_2=8'ha4,_3=8'hb0,_4=8'h99,
             _5=8'h92,_6=8'h82,_7=8'hf8,_8=8'h80,_9=8'h90;
always @(posedge clk or negedge rst_n)
    if(!rst_n)begin
        smg1 <= 8'h0;
    end
    else 
    case(ad_buffer1/100)
    4'd0:smg1 <= _0;
    4'd1:smg1 <= _1;
    4'd2:smg1 <= _2;
    4'd3:smg1 <= _3;
    4'd4:smg1 <= _4;
    4'd5:smg1 <= _5;
    4'd6:smg1 <= _6;
    4'd7:smg1 <= _7;
    4'd8:smg1 <= _8;
    4'd9:smg1 <= _9;
    endcase
    
always @(posedge clk or negedge rst_n)
    if(!rst_n)begin
        smg2 <= 8'h0;
    end
    else 
    case(ad_buffer1%100/10)
    4'd0:smg2 <= _0;
    4'd1:smg2 <= _1;
    4'd2:smg2 <= _2;
    4'd3:smg2 <= _3;
    4'd4:smg2 <= _4;
    4'd5:smg2 <= _5;
    4'd6:smg2 <= _6;
    4'd7:smg2 <= _7;
    4'd8:smg2 <= _8;
    4'd9:smg2 <= _9;
    endcase

always @(posedge clk or negedge rst_n)
    if(!rst_n)begin
        smg3 <= 8'h0;
    end
    else 
    case(ad_buffer1%10)
    4'd0:smg3 <= _0;
    4'd1:smg3 <= _1;
    4'd2:smg3 <= _2;
    4'd3:smg3 <= _3;
    4'd4:smg3 <= _4;
    4'd5:smg3 <= _5;
    4'd6:smg3 <= _6;
    4'd7:smg3 <= _7;
    4'd8:smg3 <= _8;
    4'd9:smg3 <= _9;
    endcase




endmodule

这次有待解决的问题是如何把八位数据通过移位的方法变成小数形式

总结:fpga会自动舍弃小数部分,所以要乘一个数来增加精确度

   注意位宽因为定义尾位宽不够,所以buffer1出来的数据不准确

   注意datasheet给定的时钟,刚开始因为时钟频率过小,导致数字有的点闪

原文地址:https://www.cnblogs.com/bixiaopengblog/p/6443949.html