完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我写了一个利用 ds1302 显示时间的代码,但是一直没有时间输出,数码管显示的都是 0,请求帮助,代码如下,请大家帮忙看看,谢谢!
代码: module ds1302_driver(clk,nrst, srst,sclk,clk_sel, sdata,timeData,DateData ); input nrst; //外部复位 input clk; //输入时钟 20MHz output srst; //ds1302复位 output sclk; //ds1302时钟 inout sdata; //ds1302数据口 output clk_sel; output[23:0] TimeData; //时间数据 output[31:0] DateData; //日历数据 reg data; //sdata的缓存, reg isOut; //因为sdata是双向口,所以需要标志位isOut来管理数据的输入输出 parameter IDLE = 5'd0, Init_Time = 5'd1, WR_Sec = 5'd2, WR_Min = 5'd3, WR_Hour = 5'd4, WR_Week = 5'd5, WR_Day = 5'd6, WR_Mont = 5'd7, WR_Year = 5'd8; parameter RD_Sec = 5'd9, RD_Min = 5'd10, RD_Hour = 5'd11, RD_Week = 5'd12, RD_Day = 5'd13, RD_Mont = 5'd14, RD_Year = 5'd15, CLOSE_W = 5'd16; reg Rest_flag; //重新设置标志位 reg [23:0] TimeData_r; reg [31:0] DateData_r; reg RD_flag; //写任务的标志 reg WR_flag; //读任务标志 reg [7:0] CMD = 8'h00; //command reg [7:0] SEC = 8'h40; //时间/日历 reg [7:0] MIN = 8'h58; //分钟 reg [7:0] HOU = 8'h08; //小时 reg [7:0] DAY = 8'h31; //天 reg [7:0] Month = 8'h12; //月 reg [7:0] Week = 8'h04; //星期 reg [7:0] Year = 8'h12; //年 reg [7:0] register1; //command 写时间日期寄存器地址 reg [7:0] register3; // 存放读出时间日期数值 reg [7:0] register4; //读进数据寄存器 读时间日期寄存器地址 reg [4:0] state; //状态机 reg srst_r; reg[7:0] counter; reg clk_sta; //状态机的时钟8us/period always@(posedge clk or negedge nrst) begin //or negedge nrst) begin if(!nrst) begin counter <= 8'b0; clk_sta <= 1'b0; end else if(counter <= 9) counter <= counter + 8'b1; else begin clk_sta <= ~clk_sta; // 产生 1MHz counter <= 0; end end parameter time5us =4'd9; reg [3:0] count; reg [18:0] cnt; reg start_sig; reg [5:0] i; always @(posedge clk or negedge nrst) if (!nrst) begin i<=1'b0; count <= 4'd0; end else if (count== time5us) begin count <= 4'd0; if(i < 6'd32) i<= i + 1'b1; else i<=1'b0; end else if (start_sig) count <= count + 1'b1; else count <= 4'd0; reg sclk_r; always @(posedge clk_sta ) begin if(nrst == 0) begin //初始化操作时,isOut<=0;所以输出呈现高阻态 isOut <= 0; srst_r <= 0; sclk_r <= 1; data <= 0; //输出缓存器被清空 WR_flag <= 0; RD_flag <= 0; state <= IDLE; register1 <= 8'b10001110; //关闭写保护 // register3 <= 8'b00000000; register4 <= 8'b00000000; TimeData_r <= 24'd0; DateData_r <= 32'd0; cnt <= 19'd0; end else case(state) IDLE : begin if(cnt < 19'd 400_000) // 延迟 20ms,开始启动 start_sig begin cnt <= cnt + 1'd1; start_sig <= 1'd0; state <= IDLE; end else begin cnt <= cnt; start_sig <= 1'd1; state <= Init_Time; register1 <= 8'b10001110; //关闭写保护 isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; WR_flag <= 0; RD_flag <= 0; end end Init_Time : if(WR_flag == 1'b0) WR_SET(CMD); else if(i == 6'd32) begin isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; WR_flag <= 1'b0; register1 <= 8'b1000_0000; //写时钟/日历寄存器 state <= WR_Sec; end else state <= Init_Time; WR_Sec : begin if(WR_flag == 1'b0) WR_SET(SEC);//写秒 else if(i == 6'd32) begin state <= WR_Min; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; WR_flag <= 1'b0; register1 <= 8'b1000_0010; end else state <= WR_Sec; end WR_Min : begin if(WR_flag == 1'b0) WR_SET(MIN); else if(i == 6'd32) begin state <= WR_Hour; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; WR_flag <= 1'b0; register1 <= 8'b1000_0100; end else state <= WR_Min; end WR_Hour : begin if(WR_flag == 1'b0) WR_SET(HOU); else if(i == 6'd32) begin state <= WR_Week; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; WR_flag <= 1'b0; register1 <= 8'b1000_1010; end else state <= WR_Hour; end WR_Week : begin if(WR_flag == 1'b0) WR_SET(Week); else if(i == 6'd32) begin state <= WR_Day; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; WR_flag <= 1'b0; register1 <= 8'b1000_0110; end else state <= WR_Week; end WR_Day : begin if(WR_flag == 1'b0) WR_SET(DAY); else if(i == 6'd32) begin state <= WR_Mont; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; WR_flag <= 1'b0; register1 <= 8'b1000_1000; end else state <= WR_Day; end WR_Mont : begin if(WR_flag == 1'b0) WR_SET(Month); else if(i == 6'd32) begin state <= WR_Year; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; WR_flag <= 1'b0; register1 <= 8'b1000_1100; end else state <= WR_Mont; end WR_Year : begin if(WR_flag == 1'b0) WR_SET(Year); else if(i == 6'd32) begin state <= CLOSE_W; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; WR_flag <= 1'b0; register1 <= 8'b10001110; end else state <= WR_Year; end RD_Sec : begin if(RD_flag == 1'b0) RD_T; else if(i == 6'd32) begin TimeData_r[7:0] <= register3; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b1; RD_flag <= 1'b0; register4 <= 8'b1000_0011; state <= RD_Min; end else state <= RD_Sec; end RD_Min : begin if(RD_flag == 1'b0) RD_T; else if(i == 6'd32) begin TimeData_r[15:8] <= register3; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; RD_flag <= 1'b0; register4 <= 8'b1000_0101; state <= RD_Hour; end else state <= RD_Min; end RD_Hour : begin if(RD_flag == 1'b0) RD_T; else if(i == 6'd32) begin TimeData_r[23:16] <= register3; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; RD_flag <= 1'b0; register4 <= 8'b1000_1011; state <= RD_Week; end else state <= RD_Hour; end RD_Week : begin if(RD_flag == 1'b0) RD_T; else if(i == 6'd32) begin DateData_r[7:0] <= register3; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; RD_flag <= 1'b0; register4 <= 8'b1000_0111; state <= RD_Day; end else state <= RD_Week; end RD_Day : begin if(RD_flag == 1'b0) RD_T; else if(i == 6'd32) begin DateData_r[15:8] <= register3; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; RD_flag <= 1'b0; register4 <= 8'b1000_1001; state <= RD_Mont; end else state <= RD_Day; end RD_Mont : begin if(RD_flag == 1'b0) RD_T; else if(i == 6'd32) begin DateData_r[23:16] <= register3; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; RD_flag <= 1'b0; register4 <= 8'b1000_1101; state <= RD_Year; end else state <= RD_Mont; end RD_Year : begin if(RD_flag == 1'b0) RD_T; else if(i == 6'd32) begin DateData_r[31:24] <= register3; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; RD_flag <= 1'b0; register4 <= 8'b1000_0001; state <= RD_Sec; // RD_flaglag_initial<=0; end else state <= RD_Year; end CLOSE_W : begin if(WR_flag == 1'b0) WR_SET(8'h80); else if(i == 6'd32) begin state <= RD_Sec; isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b0; WR_flag <= 1'b0; RD_flag <= 1'b0; register4 <= 8'b1000_0001; //读任务的指令寄存器 end else state <= CLOSE_W; end default : begin isOut <= 1'b1; srst_r <= 1'b1; sclk_r <= 1'b1; data <= 1'b0; WR_flag <= 1'b0; RD_flag <= 1'b0; state <= RD_Sec; register3 <= 8'b0; //接受数据的寄存器 register4 <= 8'b1000_0001; //读任务的指令寄存器 CMD <= 8'b0; end endcase end task WR_SET; input [7:0]reg_store; begin case(i) 6'd0,6'd2,6'd4,6'd6,6'd8,6'd10,6'd12,6'd14: //准备数据 begin data <= register1[(i>>1)]; //i>>1 is equal to i/2 if (count==time5us) begin /* isOut <= 1'b1; srst_r <= 1'b1; */ sclk_r <= 1'b1; // data <= register1[(i>>1)]; //i>>1 is equal to i/2 // i<= i + 1'b1; end end 6'd1,6'd3,6'd5,6'd7,6'd9,6'd11,6'd13,6'd15: //spi发送数据 if (count==time5us) begin sclk_r <= 1'b0; // i<= i + 1'b1; end 6'd16,6'd18,6'd20,6'd22,6'd24,6'd26,6'd28,6'd30: //准备数据 begin data <= reg_store[(i>>1)-6'd8]; //i>>1 is equal to i/2 if (count==time5us) begin sclk_r <= 1'b1; // data <= reg_store[(i>>1)-6'd8]; //i>>1 is equal to i/2 // i<= i + 1'b1; end end 6'd17,6'd19,6'd21,6'd23,6'd25,6'd27,6'd29,6'd31: //spi发送数据 if (count==time5us) begin sclk_r <= 1'b0; // i<= i + 1'b1; end 6'd32: begin WR_flag <= 1'b1; isOut <= 0; srst_r <= 0; sclk_r <= 0; // i <=6'd0; end /* 6'd33: i <=6'd0; */ endcase end endtask task RD_T; begin case(i) 6'd0,6'd2,6'd4,6'd6,6'd8,6'd10,6'd12,6'd14: //准备数据 begin data <= register4[(i>>1)]; //i>>1 is equal to i/2 if (count==time5us) begin /* isOut <= 1'b1; srst_r <= 1'b1; */ sclk_r <= 1'b1; // data <= register4[(i>>1)]; //i>>1 is equal to i/2 // i<= i + 1'b1; end end 6'd1,6'd3,6'd5,6'd7,6'd9,6'd11,6'd13,6'd15: //spi发送数据 begin if (count==time5us) begin sclk_r <= 1'b0; // i<= i + 1'b1; end if (i == 6'd15 && count == 4'd8) isOut <= 1'b0; end 6'd16,6'd18,6'd20,6'd22,6'd24,6'd26,6'd28,6'd30: //准备数据 begin isOut <= 1'b0; if (count==time5us) begin // isOut <= 1'b0; sclk_r <= 1'b1; // i<= i + 1'b1; end register3[(i>>1)-6'd8] <= sdata; //i>>1 is equal to i/2 end 6'd17,6'd19,6'd21,6'd23,6'd25,6'd27,6'd29,6'd31: //spi发送数据 begin // register3[(i>>1)-6'd8] <= sdata; //i>>1 is equal to i/2 if (count==time5us) begin sclk_r <= 1'b0; // register3[(i>>1)-6'd8] <= sdata; //i>>1 is equal to i/2 // i<= i + 1'b1; end end 6'd32: begin RD_flag <= 1'b1; isOut <= 0; srst_r <= 0; sclk_r <= 0; // i <=6'd0; end /* 6'd33: i <=6'd0; */ endcase end endtask //----------------------END of TASK------------------------ assign TimeData = TimeData_r; assign DateData = DateData_r; assign srst = srst_r; assign sclk = sclk_r; assign clk_sel = clk_sta; assign sdata=(isOut)? data:1'bz; //isOut:1、输出;0、高阻 endmodule |
|
相关推荐
2 个讨论
|
|
只有小组成员才能发言,加入小组>>
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-4-2 19:42 , Processed in 0.606036 second(s), Total 46, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191