打印
[CPLD]

CPLD驱动MAX7219的问题

[复制链接]
1697|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
比神乐|  楼主 | 2022-10-7 17:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用CPLD驱动MAX7219数码管显示,传送16位参数成功了。
可是传送8位参数则不成功。代码如下:
module MAX7219
                                (
                                        input clk_i,
                                        input rst_i,                                       
                                        //inout wire  sdo_i,//串行数据回读
                                        output reg sdin_o,//串行输出数据
                                        output reg sclk_o,//串行时钟
                                        output reg load_o//更新da寄存器
                                       
                                //        input wire [3:0]add,
                                        //input wire [15:0]segdata
                                       
                                 );



reg [7:0] olddata;
reg [22:0] currentstate;
parameter s1 = 23'b000_0000_0000_0000_0000_0001;
parameter s2 = 23'b000_0000_0000_0000_0000_0010;//s1和S2状态设置译码寄存器                 
parameter s3 = 23'b000_0000_0000_0000_0000_0100;
parameter s4 = 23'b000_0000_0000_0000_0000_1000;//S3和S4状态设置亮度寄存器
parameter s5 = 23'b000_0000_0000_0000_0001_0000;//
parameter s6 = 23'b000_0000_0000_0000_0010_0000;//S6和S5状态设置扫描限值寄存器
parameter s7 = 23'b000_0000_0000_0000_0100_0000;//
parameter s8 = 23'b000_0000_0000_0000_1000_0000; //S7和S8状态 设置正常显示模式
parameter s9 = 23'b000_0000_0000_0001_0000_0000; //S7和S8状态 设置正常显示模式
parameter s10 =23'b000_0000_0000_0010_0000_0000;//
parameter s11 =23'b000_0000_0000_0100_0000_0000;//s10和是1状态 送入显示的数据
parameter s12 = 23'b000_0000_0000_1000_0000_0000;
parameter s13 = 23'b000_0000_0001_0000_0000_0000;//s1和S2状态设置译码寄存器                 
parameter s14 = 23'b000_0000_0010_0000_0000_0000;
parameter s15 = 23'b000_0000_0100_0000_0000_0000;//S3和S4状态设置亮度寄存器
parameter s16 = 23'b000_0000_1000_0000_0000_0000;//
parameter s17 = 23'b000_0001_0000_0000_0000_0000;//S6和S5状态设置扫描限值寄存器
parameter s18 = 23'b000_0010_0000_0000_0000_0000;//
parameter s20 = 23'b000_1000_0000_0000_0000_0000; //S7和S8状态 设置正常显示模式
parameter s21 = 23'b001_0000_0000_0000_0000_0000; //S7和S8状态 设置正常显示模式
//parameter s21 =26'b00_0001_0000_0000_0000_0000_0000;//
//parameter s22 =26'b00_0010_0000_0000_0000_0000_0000;//s10和是1状态 送入显示的数据
//parameter s23 =26'b00_0100_0000_0000_0000_0000_0000;//
//parameter s24 =26'b00_1000_0000_0000_0000_0000_0000;//s10和是1状态 送入显示的数据
parameter Init=23'b010_0000_0000_0000_0000_0000;
parameter Init1=23'b100_0000_0000_0000_0000_0000;

//reg sclk_o;
reg [5:0]counter;

parameter       
                        seg1 = 8'h11,                                //1.
                        seg2 = 8'h81,                                //2
                        seg3 = 8'h12,                                //3
                        seg4 = 8'h02,                                //4
                        seg5 = 8'h13,                                //1.
                        seg6 = 8'h03,                                //2
                        seg7 = 8'h14,                                //3
                        seg8 = 8'h09;                                //4
reg [2:0]cnt;                       
parameter         tics=30;       
       
task delaydisp;
input[2:0] i;

        repeat(tics)
        begin
        i=1;
        i=2;
        i=3;
        end
endtask
        //产生时钟
always @(posedge clk_i)
begin
  if(!rst_i) begin
                counter<=6'd0;
                sclk_o <= 1'b1;
    end
  else begin
    if(counter==6'd9) begin
      sclk_o <= ~sclk_o;
      counter<=6'd0;
      end
    else counter<=counter+6'd1;
    end
end

reg [2:0] sclk_cnt;//同步时钟计数器,7
always @(posedge sclk_o or negedge rst_i)
begin
        if(!rst_i) sclk_cnt <= 1'b0;
        else
        case(currentstate)
                Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21:
                        if(3'd7  == sclk_cnt)
                                        sclk_cnt <= 1'b0;
                        else         sclk_cnt <= sclk_cnt + 1'b1;
                default: sclk_cnt <= 1'b0;
        endcase
end
//主状态机
always @(posedge sclk_o or negedge rst_i)
begin
        if(!rst_i) begin currentstate <=Init; cnt = 3'b0; end
        else
        case(currentstate)
        Init:currentstate <=Init1;
        Init1:begin
                        if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
                                currentstate <= s1;
                        else
                                currentstate <= Init1;
                end
        s1: currentstate <= s2;  //s1和S2状态设置译码寄存器       
        s2:begin
                        if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
                                currentstate <= s3;
                        else
                                currentstate <= s2;
                end
        s3: currentstate <= s4;//S3和S4状态设置亮度寄存器
        s4: begin
                        if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
                                currentstate <= s5;
                        else
                                currentstate <= s4;       
                end       
        s5: currentstate <= s6;//        S6和S5状态设置扫描限值寄存器
        s6: begin
                        if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
                                currentstate <= s7;
                        else
                   currentstate <= s6;
                end
        s7: currentstate <= s8;//        S7和S8状态 设置正常显示模式
        s8: begin
                        if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
                                currentstate <= s9;
                        else
                   currentstate <= s8;
                end
        s9: currentstate <= s10;//        S7和S8状态 设置正常显示模式
        s10: begin
                        if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
                                currentstate <= s11;
                        else
                   currentstate <= s10;
                end
        s11: currentstate <= s12;//        S7和S8状态 设置正常显示模式
        s12: begin
                        if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
                                currentstate <= s13;
                        else
                   currentstate <= s12;
                end
        s13: currentstate <= s14;//        S7和S8状态 设置正常显示模式
        s14: begin
                        if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
                                currentstate <= s15;
                        else
                   currentstate <= s14;
                end
        s15: currentstate <= s16;//        S7和S8状态 设置正常显示模式
        s16: begin
                        if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
                                currentstate <= s17;
                        else
                   currentstate <= s16;
                end
        s17: currentstate <= s18;//        S7和S8状态 设置正常显示模式
        s18: begin
                        if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
                                currentstate <= s20;
                        else
                   currentstate <= s18;
                end
       
        //初始化完成         
        s20: if(olddata != data)
                                currentstate <= s21;//        正常送数据显示
                  else
                                currentstate <= s20;
        s21: begin
                        if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
                                begin
                                        currentstate <= s20;
                                        cnt = cnt + 1'b1;
                                end       
                        else
                   currentstate <= s21;
                end         
        endcase
end
//各状态的处理
reg [7:0] data;
always @(posedge sclk_o or negedge rst_i)
begin
        if(!rst_i)begin  data <= 8'h00; olddata <= 8'h00; end
        else case(currentstate)
                Init:begin data <= 8'h0a;delaydisp(20); end
                s1:begin  data <= 8'h04;delaydisp(20); end  //正常显示模式
                s3:begin  data <= 8'h0c;delaydisp(20);        end//编码寄存器 ALL CODE B DECODE
           s5:begin  data <= 8'h01;delaydisp(20);        end//亮度寄存器 ALL max on
                s7:begin  data <= 8'h09;delaydisp(20); end  //扫描限值寄存器 ALL on
                s9:begin  data <= 8'hff;delaydisp(20); end  //正常显示模式
                s11:begin  data <= 8'h0f;delaydisp(20); end        //编码寄存器 ALL CODE B DECODE
           s13:begin  data <= 8'h01;delaydisp(20); end        //亮度寄存器 ALL max on
                s15:begin  data <= 8'h0b;delaydisp(20); end  //扫描限值寄存器 ALL on
                s17:begin  data <= 8'h07;delaydisp(20); end  //扫描限值寄存器 ALL on
                s20: begin
                        case(cnt)
                        3'd0: begin data <= seg1;delaydisp(20);  end
                        3'd1: begin data <= seg2;delaydisp(20); end
                        3'd2: begin data <= seg3;delaydisp(20); end
                        3'd3: begin data <= seg4;delaydisp(20); end
                        3'd4: begin data <= seg5;delaydisp(20); end
                        3'd5: begin data <= seg6;delaydisp(20); end
                        3'd6: begin data <= seg7;delaydisp(20); end
                        3'd7: begin data <= seg8;delaydisp(20); end
                        endcase

                        olddata <= data;
                end //待显示的数据
                Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21: begin data <= data << 1;        olddata <= olddata; end//循环移位 将高位送出
                default: begin data <= 8'h00; olddata <= olddata; end
        endcase
end
//----------数据串行---------
always @(posedge sclk_o or negedge rst_i)
begin
        if(!rst_i) sdin_o <= 1'b0;
        else case(currentstate)
                Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21: sdin_o <= data[7];
                default: sdin_o <= 1'b0;
        endcase
end
//----------串行数据写有效LOAD----------
always @(posedge sclk_o or negedge rst_i)
begin
        if(!rst_i) load_o <= 1'b1;
        else case(currentstate)
                Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21: begin  load_o <= 1'b0; delaydisp(20); end //送数的时候处于低
                default: load_o <= 1'b1; //非送数时候,拉高 锁存数据
        endcase
end


endmodule
我刻意加了延时函数,还是不行。
大侠看看,哪里有问题?谢谢!

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

337

主题

3057

帖子

7

粉丝