时间的单位换算
首先掌握秒的单位换算,这里总结一些。因为笔者目前用的大多为50MHz,所以介绍以此为例。但关于秒的转换全世界都是一样的。
1MHz = 1,000kHz = 1,000,000Hz
频率:是用单位时间内完成的周期性变化的次数,是描述周期运动频繁程度的量。
因此结合以上内容,50MHz,就是说,(两个相邻时钟上升沿算一个周期)1s内有50,000,000Hz个时钟上升沿。所以一个周期有多久就可以计算出来了1/50,000,000 = 0.000,000,02s
而常见的时间单位换算
1s = 1,000ms毫秒
1s = 1,000ms = 1,000,000us 微秒 1ms = 1,000us
1s = 1,000ms = 1,000,000us = 1,000,000,000ns 纳秒 1us = 1,000ns
下面还有皮秒和飞秒。进制都是1,000
所以可得,50MHz时钟频率下的一个周期是20ns!!!
呼吸灯设计原理
原理就我理解,总的来说,就是先分频,再控制占空比。通过控制led的亮灯时间来实现呼吸功能。
功能就是让led灯2s为从暗到亮,下一个2s从亮到暗。
具体实现为将2s分为1000份。在这1000份里边,依次增加亮灯的时间。2s的1000份就是2ms
所以将2ms再分为1000份,就是2us。第一个2ms,亮led2us 第二个2ms,亮led4us......
然后依次增加。
仿真截图
由于分的太细,,可能看的不是很清楚。
代码
module pwm_led(clk,rst_n,pwm_led);
input clk;
input rst_n;output pwm_led;//两秒计时器
reg time_2s;
reg [27:0] cnt_2s;
always@(posedge clk or negedge rst_n)
beginif(!rst_n)begin cnt_2s <= 28'd0;time_2s <= 1'b0;endelse if(cnt_2s == 28'd50_000_000 - 1'b1)begincnt_2s <= 28'd0;time_2s <= 1'b1;endelse begincnt_2s <= cnt_2s + 1'b1;time_2s <= 1'b0;end
end//2ms计时器
reg time_2ms;
reg [16:0] cnt_2ms;
always@(posedge clk or negedge rst_n)
beginif(!rst_n)begin cnt_2ms <= 17'd0;time_2ms <= 1'b0;endelse if(cnt_2ms == 17'd100_000 - 1'b1)begincnt_2ms <= 17'd0;time_2ms <= 1'b1;endelse begincnt_2ms <= cnt_2ms + 1'b1;time_2ms <= 1'b0;end
end
//计数是第几个2ms
reg [9:0] number_2ms;
always@(posedge clk or negedge rst_n)
beginif(!rst_n)number_2ms <= 10'd0;else if( number_2ms == 10'd999 )number_2ms <= 10'd0;else if(time_2ms)number_2ms <= number_2ms + 1'b1;else number_2ms <= number_2ms;
end//2us计时器
reg time_2us;
reg [6:0] cnt_2us;
always@(posedge clk or negedge rst_n)
beginif(!rst_n)begin cnt_2us <= 7'd0;time_2us <= 1'b0;endelse if(cnt_2us == 7'd100 - 1'b1)begincnt_2us <= 7'd0;time_2us <= 1'b1;endelse begincnt_2us <= cnt_2us + 1'b1;time_2us <= 1'b0;end
end//计数2us,数是第几个2us
reg [9:0] number_2us;
always@(posedge clk or negedge rst_n)
beginif(!rst_n)number_2us <= 10'd0;else if(number_2us == 10'd999 )number_2us <= 10'd0;else if(time_2us)number_2us <= number_2us + 1'b1;else number_2us <= number_2us;
endwire led_flag0;//暗到亮
wire led_flag1;//亮到暗
assign led_flag0 = (number_2us < number_2ms) ? 1 : 0;
assign led_flag1 = (number_2us < number_2ms) ? 0 : 1;reg led_flag;
always@(posedge clk or negedge rst_n)
beginif(!rst_n)led_flag <= 1'b1;else if(time_2s)led_flag <= ~led_flag;else led_flag <= led_flag;
endassign pwm_led = (led_flag) ? led_flag0 : led_flag1;endmodule
代码经验证可以实现功能,还是很好玩的。