收藏 分销(赏)

ISE实现多功能数字钟设计.docx

上传人:快乐****生活 文档编号:10921330 上传时间:2025-06-21 格式:DOCX 页数:27 大小:198.73KB 下载积分:10 金币
下载 相关 举报
ISE实现多功能数字钟设计.docx_第1页
第1页 / 共27页
ISE实现多功能数字钟设计.docx_第2页
第2页 / 共27页


点击查看更多>>
资源描述
ISE实现多功能数字钟设计 一、 任务要求 用FPGA器件和EDA技术实现多功能数字钟的设计。 基本功能要求:能显示小时、分钟、秒钟(时、分用7段LED显示器,秒用LED灯)。 小时计数器为同步24进制; 要求手动校时、校分。 扩展功能要求:任意时刻闹钟; 小时显示(12/24)切换电路 自动报整点时数。 二、 建立工程 在ISE 14,9软件中建立名为clock 的工程文件。芯片系列选择Spatan3E,具体芯片型号选择XC3S100E,封装类型选择CP132,速度信息选择-5。 三、 原理设计 四、 顶层模块设计 创建名为top_clock的文件,本设计中顶层模块用于调用各个子模块,以与将闹钟与整点报时模块综合在内,顶层源码如下: module top_clock( input Hchange, //24小时,12小时切换信号 input Change, //用来进行时分和秒的显示切换 input CLK_50, //50MHz时钟 input nCR,EN,Clock_EN, input Adj_Min,Adj_Hour,Adj_Clock, //使能信号,小时分钟调时允许信号,闹钟使能信号(拨钮开关) output [6:0] HEX0, output reg Led_Alarm, output reg [3:0] HEX //共阳极数码管对应端 ); reg Alarm; wire ENM_L,ENM_H,ENH; wire [7:0] Hour_24,TMinute,TSecond,CHour,CMinute;//中间变量声明,正常时钟变量和闹钟时钟变量 wire [7:0] Hour_12,Display_HourT,Display_HourAdjust; reg [3:0] bcd=4'b0000; //记载数码管所要显示的数据 reg [7:0] Display_Hour,Minute; reg LD_6_RADIO; reg [7:0] sum,counter; supply1 Vdd; wire CP_1Hz; //===========分频============= Divider50MHz U0(.CLK_50M(CLK_50), .nCLR(nCR), .CLK_1HzOut(CP_1Hz));//用以时钟计数的CP defparam U0.N = 25, U0.CLK_Freq = 50000000, U0.OUT_Freq = 1; Divider50MHz U1(.CLK_50M(CLK_50), .nCLR(nCR), .CLK_1HzOut(CP_200Hz));//用以动态扫描的CP,供给数码管 defparam U1.N = 18, U1.CLK_Freq = 50000000, U1.OUT_Freq = 200; //===========60进制秒计数器========= Scounter10 S0(TSecond[3:0],nCR,EN,CP_1Hz);//秒:个位 Scounter6 S1(TSecond[7:4],nCR,(TSecond[3:0]==4'h9),CP_1Hz);//秒:十位 //===========60进制分计数器========= Mcounter10 M0(TMinute[3:0],nCR,ENM_L,EN,CP_1Hz);//分:个位 Mcounter6 M1(TMinute[7:4],nCR,ENM_H,EN,CP_1Hz);//分:十位 assign ENM_L=Adj_Min?Vdd:(TSecond==8'h59);//分钟按书上CP调时 assign ENM_H=(Adj_Min&&(TMinute[3:0]==4'h9))||(TMinute[3:0]==4'h9)&&(TSecond==8'h59); //24小时制 counter24 H0(Hour_24[7:4],Hour_24[3:0],nCR,ENH,EN,CP_1Hz); assign ENH = Adj_Hour?Vdd:((TMinute==8'h59)&&(TSecond==8'h59)); //===========12小时与24小时进制切换控制========== assign Display_HourAdjust=((Hour_24==8'h20)||(Hour_24==8'h21))?(Hour_24-24):(Hour_24-18); assign Hour_12 = (Hour_24<8'h13)?Hour_24:Display_HourAdjust; assign Display_HourT = Hchange?Hour_12:Hour_24; //===========闹钟============ //----------时钟秒--------- //counter60 CCS(nCR,CP_1Hz,EN,CSecond[7:4],CSecond[3:0]); //----------时钟分--------- counter60 CCM(nCR,CP_1Hz,CMin_EN,CMinute[7:4],CMinute[3:0]); //--产生分使能信号-- assign CMin_EN = (!EN && Adj_Clock && Adj_Min); //----------时钟时--------- Counter24C CCH(nCR,CP_1Hz,CHour_EN,CHour[7:4],CHour[3:0]); //--产生时使能信号-- assign CHour_EN = (!EN && Adj_Clock && Adj_Hour); //--闹钟响-- always@(EN or Clock_EN) //闹钟开关 begin if(EN && Clock_EN && (CHour == Display_HourT) && (CMinute == TMinute))Alarm <= 1; else Alarm <= 0; end always@(posedge CLK_50 or negedge EN or negedge Alarm) //表示闹钟的LED begin if(~EN) Led_Alarm <= 0; else begin if(~Alarm) Led_Alarm <= 0; else Led_Alarm <= ~Led_Alarm; end end //alarm_clock AL0(Hour24,Minute,CP_1Hz,Set_Alarm,Close_clock,nCR,KeySet_Hour_ev,KeySet_Minute_ev,LD_7,Alarm_Hour,Alarm_Minute); //===========数码显示========= always@(Adj_Clock)//确定数码管显示闹钟还是正常时钟 begin if(Adj_Clock) begin Display_Hour <= CHour;Minute <= CMinute;end else begin Display_Hour <= Display_HourT;Minute <= TMinute;end end always@(posedge CP_200Hz) begin if(Change==1) //数码管进行时分显示 begin case(HEX) 4'b1110: begin HEX<=4'b0111; bcd<= Display_Hour [7:4]; end //第一根数码管显示小时十位 4'b0111: begin HEX<=4'b1011; bcd<= Display_Hour [3:0]; end //第二根显示小时个位 4'b1011: begin HEX<=4'b1101; bcd<= Minute [7:4]; end //第三根显示分钟十位 4'b1101: begin HEX<=4'b1110; bcd<= Minute [3:0]; end //第四根显示分钟个位 default: begin HEX<=0111; bcd<=Display_Hour [7:4]; end endcase end else //数码管进行秒显示,change为低电平时显示秒 begin case(HEX) 4'b1110: begin HEX<=4'b1101; bcd<= TSecond [7:4]; end //第三根显示秒十位 4'b1101: begin HEX<=4'b1110; bcd<= TSecond [3:0]; end //第四根显示秒个位 default: begin HEX<=1101; bcd<= TSecond [7:4]; end endcase end end SEG7_LUT L0(HEX0,bcd); //调用数码管子函数 //======整点报时========== assign LD_6 = LD_6_RADIO; always@(CP_1Hz) begin if((Minute[7:0] == 8'h00) && (counter[7:0] < (Hour_24[7:4]*10 + Hour_24[3:0]))) begin LD_6_RADIO <= CP_1Hz; end else begin LD_6_RADIO <= 0; end end always@(posedge CP_1Hz) if(Minute[7:0]==8'h00) begin counter[7:0]<=counter[7:0]+1'b1; end else begin counter[7:0]<=8'h00; end endmodule 五、 顶层模块设计图 六、 子模块设计 1、 50MHz分频器 module Divider50MHz(CLK_50M,nCLR,CLK_1HzOut); parameter N = 25; //位宽 parameter CLK_Freq = 50000000; //50MHz时钟输入 parameter OUT_Freq = 1; //1Hz时钟输出 input nCLR,CLK_50M; //输入端口说明 output reg CLK_1HzOut; //输出端口说明 reg [N-1:0] Count_DIV; //内部节点,存放计数器的输出值 always@(posedge CLK_50M or negedge nCLR) begin if(!nCLR) begin CLK_1HzOut <= 0; Count_DIV <= 0; end else begin if(Count_DIV <(CLK_Freq/(2*OUT_Freq)-1))//计数器模 Count_DIV <= Count_DIV + 1'b1; //分频器计数加1 else begin Count_DIV <= 0; //分频器输出清零 CLK_1HzOut <= ~CLK_1HzOut; //输出信号取反 end end end endmodule 2、 秒模10计数器 module Scounter10(Q,nCR,EN,CP); input CP,nCR,EN; output Q; reg [3:0] Q; always @(posedge CP or negedge nCR) begin if(~nCR) Q <= 4'b0000;//异步清零 else if(~EN) Q <= Q; //暂停计数 else if(Q==4'b1001) Q <= 4'b0000; else Q <= Q + 1'b1; end 3、 秒模6计数器 module Scounter6(Q,nCR,EN,CP); input CP,nCR,EN; output Q; reg [3:0] Q; always @(posedge CP or negedge nCR) begin if(~nCR) Q <= 4'b0000;//异步清零 else if(~EN) Q <= Q; //暂停计数 else if(Q==4'b0101) Q <= 4'b0000; else Q <= Q + 1'b1; end 4、 分模10计数器 module Mcounter10(Q,nCR,EN1,EN2,CP); input CP,nCR,EN1,EN2; output Q; reg [3:0] Q; always @(posedge CP or negedge nCR) begin if(~nCR) Q <= 4'b0000;//异步清零 else if(~EN1||!EN2) Q <= Q; //暂停计数 else if(Q==4'b1001) Q <= 4'b0000; else Q <= Q + 1'b1; end 5、 分模6计数器 module Mcounter6(Q,nCR,EN1,EN2,CP); input CP,nCR,EN1,EN2; output Q; reg [3:0] Q; always @(posedge CP or negedge nCR) begin if(~nCR) Q <= 4'b0000;//异步清零 else if(~EN1||~EN2) Q <= Q; //暂停计数 else if(Q==4'b0101) Q <= 4'b0000; else Q <= Q + 1'b1; end 6、 模24计数器 module counter24(CntH,CntL,nCR,EN1,EN2,CP); input CP,nCR,EN1,EN2; output reg [3:0] CntH,CntL;//小时的十位和个位输出 always@(posedge CP or negedge nCR) begin if(~nCR) {CntH,CntL} <= 8'h00; //异步清零 else if(~EN1||~EN2) {CntH,CntL} <= {CntH,CntL};//暂停计数 else if((CntH)>2||(CntL>9)||(CntH)==2&&(CntL)>=3) {CntH,CntL} <= 8'h00; //对小时计数器出错时的处理 else if((CntH)==2&&(CntL)<3) //进行20~23计数 begin CntH <=CntH; CntL <= CntL + 1'b1; end else if(CntL==9) //小时十位的计数 begin CntH <=CntH + 1'b1; CntL <= 4'b0000; end else begin CntH <= CntH; CntL <= CntL + 1'b1; end end endmodule 7、 模60计数器 module counter60(nCLR,Clk,EN,CntH,CntL); input nCLR,Clk,EN; output reg [3:0] CntH,CntL; always@(posedge Clk or negedge nCLR) begin if(~nCLR) {CntH,CntL} <= 0; //异步清零 else if(~EN) {CntH,CntL} <= {CntH,CntL}; //暂停信号 else if(((CntH > 5)||(CntL > 9))||((CntH == 5)&&(CntL == 9))) {CntH,CntL} <= 8'h00; //异常处理 else if(CntL == 9) begin CntH <= CntH + 1'b1;CntL <= 0;end //十位计数 else begin CntH <= CntH;CntL <= CntL + 1'b1;end //个位计数 end endmodule 8、 数码管显示 module SEG7_LUT(oSEG,iDIG); input [3:0] iDIG; //二进制输入 output reg [6:0] oSEG; //7段码输出 always@(iDIG) begin case(iDIG) 4'h0: oSEG = 7'b000_0001; 4'h1: oSEG = 7'b100_1111; 4'h2: oSEG = 7'b001_0010; 4'h3: oSEG = 7'b000_0110; 4'h4: oSEG = 7'b100_1100; 4'h5: oSEG = 7'b010_0100; 4'h6: oSEG = 7'b010_0000; 4'h7: oSEG = 7'b000_1111; 4'h8: oSEG = 7'b000_0000; 4'h9: oSEG = 7'b000_0100; default: oSEG=7'b1111111; endcase end endmodule 七、 各模块仿真 1、 模10计数器 测试代码: // Inputs reg nCR; reg EN; reg CP; // Outputs wire [3:0] Q; // Instantiate the Unit Under Test (UUT) counter10 uut ( .Q(Q), .nCR(nCR), .EN(EN), .CP(CP) ); parameter PERIOD =40;//时钟信号周期设置为40ns always begin CP=1'b0; #(PERIOD/2) CP=1'b1; #(PERIOD/2); end initial begin // Initialize Inputs nCR = 0; EN = 1; CP = 1; // Wait 100 ns for global reset to finish #100; nCR=1; // Add stimulus here end endmodule 2、 模6计数器 测试代码: // Inputs reg nCR; reg EN; reg CP; // Outputs wire [3:0] Q; // Instantiate the Unit Under Test (UUT) counter6 uut ( .Q(Q), .nCR(nCR), .EN(EN), .CP(CP) ); parameter PERIOD =40;//时钟信号周期设置为40ns always begin CP=1'b0; #(PERIOD/2) CP=1'b1; #(PERIOD/2); end initial begin // Initialize Inputs nCR = 0; EN = 1; CP = 1; // Wait 100 ns for global reset to finish #100; nCR =1; // Add stimulus here end endmodule 3、 模24计数器 测试代码: // Inputs reg nCR; reg EN; reg CP; // Outputs wire [3:0] CntH; wire [3:0] CntL; // Instantiate the Unit Under Test (UUT) counter24 uut ( .CntH(CntH), .CntL(CntL), .nCR(nCR), .EN(EN), .CP(CP) ); parameter PERIOD =40;//时钟信号周期设置为40ns always begin CP=1'b0; #(PERIOD/2) CP=1'b1; #(PERIOD/2); end initial begin // Initialize Inputs nCR = 0; EN = 1; CP = 1; // Wait 100 ns for global reset to finish #100; nCR=1; // Add stimulus here end endmodule 4、 模60计数器 测试代码: // Inputs reg nCLR; reg Clk; reg EN; // Outputs wire [3:0] CntH; wire [3:0] CntL; // Instantiate the Unit Under Test (UUT) counter60 uut ( .nCLR(nCLR), .Clk(Clk), .EN(EN), .CntH(CntH), .CntL(CntL) ); parameter PERIOD =40;//时钟信号周期设置为40ns always begin Clk=1'b0; #(PERIOD/2) Clk=1'b1; #(PERIOD/2); end initial begin // Initialize Inputs nCLR = 0; Clk = 1; EN = 1; // Wait 100 ns for global reset to finish #100; nCLR=1; // Add stimulus here end endmodule 八、 引脚分配 NET "CLK_50" TNM_NET = CLK_50; TIMESPEC TS_CLK_50 = PERIOD "CLK_50" 20 ns HIGH 50%; NET "CLK_50" LOC = B8; NET "nCR" LOC = P11; NET "EN" LOC = L3; NET "Adj_Min" LOC = K3; NET "Adj_Hour" LOC = B4; NET "Change" LOC = G3; NET "Led_Alarm" LOC = N4; NET "Adj_Clock" LOC = E2; NET "Clock_EN" LOC = N3; NET "HEX0[6]" LOC = L14; NET "HEX0[5]" LOC = H12; NET "HEX0[4]" LOC = N14; NET "HEX0[3]" LOC = N11; NET "HEX0[2]" LOC = P12; NET "HEX0[1]" LOC = L13; NET "HEX0[0]" LOC = M12; NET "HEX[0]" LOC = F12; NET "HEX[1]" LOC = J12; NET "HEX[2]" LOC = M13; NET "HEX[3]" LOC = K14; NET "Hchange" LOC = F3; NET "CLK_50" SLEW = FAST; NET "LD_6" LOC = G1; 九、 设计实现 1. 运行Implement Design选项,进行转换、映射、布局布线操作。 2. 选择Manage Configuration Project选项 l 选择Boundary Scan,在窗口空白处点击鼠标右键,选中Initialize Chain选项. l 将clock.bit文件导入至xc3s5001中 l 右击xc3s5001,选择program选项,将程序烧录至FPGA实验板中 3. 观察运行情况 1) 测试基本功能: 打开使能开关L3,数码管可以正常显示分和时,拨动时分和秒的切换显示开关G3,数码管可以切换显示秒。拨动K3和B4,可以实现校时功能。拨动清零开关P11,可以实现清零功能。当时间到23:59时,能运行至00:00。 2) 测试扩展功能: 拨动F3,可实现24小时与12小时的切换。当时间为整点时,LED灯G1会根据当前整点时数闪烁对应次数,拨动N3,闹钟使能。拨动E2,进入闹钟设置状态,此时设置闹钟时间。当正常时间跳到闹钟设置时刻时,闹钟对应LED灯N4会常亮,表示闹钟响。当正常时间已经越过闹钟设置时间时,N4会熄灭。闹钟响时关闭闹钟使能端N3时,N4也会熄灭。 十、 实验总结 本次实验是一个中等规模的设计实验,相比步进电机实验,难度明显上升,这就对我们的分析和设计能力有了更高的要求。要实现这个多功能的数字钟,关键要做到思路清晰,先构思好顶层架构,再一一考虑需要调用的模块,最后依次编写各个模块。在调试的时候,先要做到各子模块调试无误,再通过整机联调观察出现的不正常结果,列出可能的错误,再去对应的位置进行改正。 本次实验中,不可避免地出现了若干错误之处,例如在实现24进制和12进制转换时,没有发现代码中的计算方式是以8421BCD码来进行计算的,于是在最后的12进制显示中出现了很多不正常状态,花费了一些时间才找到解决办法。这也提醒我在之后的学习过程中要保持细心的态度,不断学习纠正错误的方法,提高效率。 27 / 27
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服