huang518489 发表于 2012-5-4 21:06:35

求助Verilog语言的74HC595程序,这个写的不知道哪错了

module seg_595(
   clk,rst_n,
   ds_stcp,ds_shcp,ds_data
);

input clk; //25M输入时钟信号
input rst_n; //复位信号输入,低有效

output ds_stcp;//74HC595的并行时钟输入,上升沿将当前串行输入数据并行输出
output ds_shcp;//74HC595的串行时钟输入,上升沿锁存当前串行输入数据
output ds_data;//74HC595的串行数据输入


//-------------------------------------------------
//参数定义

//数码管显示 0~F 对应段选输出
parameterSEG_NUM0= 8'hc0,//c0,
   SEG_NUM1= 8'hf9,//f9,
   SEG_NUM2= 8'ha4,//a4,
   SEG_NUM3= 8'hb0,//b0,
   SEG_NUM4= 8'h99,//99,
   SEG_NUM5= 8'h92,//92,
   SEG_NUM6= 8'h82,//82,
   SEG_NUM7= 8'hF8,//F8,
   SEG_NUM8= 8'h80,//80,
   SEG_NUM9= 8'h90,//90,
   SEG_NUMA= 8'h88,//88,
   SEG_NUMB= 8'h83,//83,
   SEG_NUMC= 8'hc6,//c6,
   SEG_NUMD= 8'ha1,//a1,
   SEG_NUME= 8'h86,//86,
   SEG_NUMF= 8'h8e;//8e;

//数码管位选 0~3 对应输出
parameter
   SEG_WE0= 8'b0000_0001,
   SEG_WE1= 8'b0000_0010,
   SEG_WE2= 8'b0000_0100,
   SEG_WE3= 8'b0000_1000,
       
        SEG_WE4= 8'b0001_0000,
   SEG_WE5= 8'b0010_0000,
        SEG_WE6= 8'b0100_0000,
   SEG_WE7= 8'b1000_0000;

//-------------------------------------------------
//分时显示数据控制单元
reg seg_num; //当前显示数据
reg seg_duan; //7段数码管段选信号(包括小数点为8段)
reg seg_wei; //7段数码管位选信号

reg cnt_4;//分时计数器

//分时计数器

always @(posedge clk or negedge rst_n)
if(!rst_n) cnt_4 <= 8'd0;
else cnt_4 <= cnt_4+1'b1;

//显示数据
always @(posedge clk or negedge rst_n)
if(!rst_n) seg_num <= 8'h00;
else

case(cnt_4)
    3'b000: seg_num <= 4'h1;
    3'b001: seg_num <= 4'h2;
    3'b010: seg_num <= 4'h3;
    3'b011: seg_num <= 4'h4;
       
       3'b100: seg_num <= 4'h5;
       3'b101: seg_num <= 4'h6;
       3'b110: seg_num <= 4'h7;
       3'b111: seg_num <= 4'h8;
   default:seg_num <= 4'h0;
       
       
   endcase

//段选数据译码
always @(posedge clk or negedge rst_n)
if(!rst_n) seg_duan <= 8'h00;
else
case(seg_num)
   4'h0: seg_duan <= SEG_NUM0;
   4'h1: seg_duan <= SEG_NUM1;
   4'h2: seg_duan <= SEG_NUM2;
   4'h3: seg_duan <= SEG_NUM3;
   4'h4: seg_duan <= SEG_NUM4;
   4'h5: seg_duan <= SEG_NUM5;
   4'h6: seg_duan <= SEG_NUM6;
   4'h7: seg_duan <= SEG_NUM7;
   4'h8: seg_duan <= SEG_NUM8;
   4'h9: seg_duan <= SEG_NUM9;
   4'ha: seg_duan <= SEG_NUMA;
   4'hb: seg_duan <= SEG_NUMB;
   4'hc: seg_duan <= SEG_NUMC;
   4'hd: seg_duan <= SEG_NUMD;
   4'he: seg_duan <= SEG_NUME;
   4'hf: seg_duan <= SEG_NUMF;
default:;
endcase

//位选译码
always @(cnt_4)
case(cnt_4)

    3'b000: seg_wei <= SEG_WE0;
    3'b001: seg_wei <= SEG_WE1;
    3'b010: seg_wei <= SEG_WE2;
    3'b011: seg_wei <= SEG_WE3;
       3'b100: seg_wei <= SEG_WE4;
       3'b101: seg_wei <= SEG_WE5;
       3'b110: seg_wei <= SEG_WE6;
       3'b111: seg_wei <= SEG_WE7;
       
       
default:seg_wei <= 8'b0000_0000;
endcase

//-------------------------------------------------
//74HC95驱动译码   
reg ds_stcpr; //74HC595的并行时钟输入,上升沿将当前串行输入数据并行输出
reg ds_shcpr; //74HC595的串行时钟输入,上升沿锁存当前串行输入数据
reg ds_datar; //74HC595的串行数据输入
   
//串行移位时钟产生
always @(posedge clk or negedge rst_n)   
if(!rst_n) ds_shcpr <= 1'b0;

else if((cnt_4 > 8'h02 && cnt_4 <= 8'h22) || (cnt_4 > 8'h42 && cnt_4 <= 8'h62)
   || (cnt_4 > 8'h82 && cnt_4 <= 8'ha2) || (cnt_4 > 8'hc2 && cnt_4 <= 8'he2))
ds_shcpr <= ~ds_shcpr;



//串行移位数据产生
always @(posedge clk or negedge rst_n)   
if(!rst_n) ds_datar <= 1'b0;
else

case(cnt_4)

   8'h02,8'h42,8'h82,8'hc2: ds_datar <= seg_wei;
   8'h04,8'h44,8'h84,8'hc4: ds_datar <= seg_wei;
   8'h06,8'h46,8'h86,8'hc6: ds_datar <= seg_wei;
   8'h08,8'h48,8'h88,8'hc8: ds_datar <= seg_wei;
       
        8'h0a,8'h4a,8'h8a,8'hca: ds_datar <= seg_wei;
   8'h0c,8'h4c,8'h8c,8'hcc: ds_datar <= seg_wei;
   8'h0e,8'h4e,8'h8e,8'hce: ds_datar <= seg_wei;
   8'h10,8'h50,8'h90,8'hd0: ds_datar <= seg_wei;
       
        8'h12,8'h52,8'h92,8'hd2: ds_datar <=seg_duan; //可用
   8'h14,8'h54,8'h94,8'hd4: ds_datar <=seg_duan;
   8'h16,8'h56,8'h96,8'hd6: ds_datar <=seg_duan;
   8'h18,8'h58,8'h98,8'hd8: ds_datar <=seg_duan;
       
   8'h1a,8'h5a,8'h9a,8'hda: ds_datar <=seg_duan;       
   8'h1c,8'h5c,8'h9c,8'hdc: ds_datar <=seg_duan;
        8'h1e,8'h5e,8'h9e,8'hde: ds_datar <=seg_duan;
        8'h20,8'h60,8'ha0,8'he0: ds_datar <=seg_duan;
   default: ;
   endcase
       
       
//并行移位时钟产生
always @(posedge clk or negedge rst_n)   
if(!rst_n) ds_stcpr <= 1'b0;

else if((cnt_4 == 8'h02)|| (cnt_4 == 8'h42) || (cnt_4 == 8'h82) || (cnt_4 == 8'hc2)) ds_stcpr <= 1'b0;
else if((cnt_4 == 8'h23) || (cnt_4 == 8'h63) || (cnt_4 == 8'ha3) || (cnt_4 == 8'he3)) ds_stcpr <= 1'b1;


wire ds_stcp = ds_stcpr;
wire ds_shcp = ds_shcpr;
wire ds_data = ds_datar;   

endmodule

wye11083 发表于 2012-5-4 21:32:11

又是一个无厘头。我看那图上好好的。

huang518489 发表于 2012-5-4 21:43:03

wye11083 发表于 2012-5-4 21:32 static/image/common/back.gif
又是一个无厘头。我看那图上好好的。

{:sweat:} 我程序写的是显示的是八位,实际只显示4位的

huang518489 发表于 2012-5-4 21:45:22

忘了说错误了,我程序写的是显示的是八位,实际只显示4位的

huang518489 发表于 2012-5-5 17:21:57

自己解决好了,是计数触发冲突

wangshaosh123 发表于 2012-5-5 17:57:31

说白了就是SPI接口!!!!!
你看下高手怎么写的http://www.ourdev.cn/forum.php?mod=viewthread&tid=4243168&highlight=SPI%2B10
自己用示波器观察下时序,很容易就找到问题所在了
页: [1]
查看完整版本: 求助Verilog语言的74HC595程序,这个写的不知道哪错了