当前位置: 首页> 娱乐> 明星 > 二维码生成器在线制作方法_哈尔滨政府工程招标网_企业公司网站建设_网站seo排名优化方法

二维码生成器在线制作方法_哈尔滨政府工程招标网_企业公司网站建设_网站seo排名优化方法

时间:2025/7/9 7:35:41来源:https://blog.csdn.net/TommiWei/article/details/147062525 浏览次数:0次
二维码生成器在线制作方法_哈尔滨政府工程招标网_企业公司网站建设_网站seo排名优化方法

 完整代码如下所示:

`timescale 1ns / 1ps// Company: 
// Engineer:		 特权
//
// Create Date:  
// Design Name:    
// Module Name: 
// Project Name:   
// Target Device:  
// Tool versions:  
// Description:
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 欢迎加入EDN的FPGA/CPLD助学小组一起讨论:http://group.ednchina.com/1375///说明:当三个独立按键的某一个被按下后,相应的LED被点亮;
//		再次按下后,LED熄灭,按键控制LED亮灭
/*****************************************************************************************************************/
module sw_debounce(clk,rst_n,sw1_n,sw2_n,sw3_n,led_d1,led_d2,led_d3);input   clk;	//主时钟信号,50MHz
input   rst_n;	//复位信号,低有效
input   sw1_n,sw2_n,sw3_n; 	//三个独立按键,低表示按下
output  led_d1,led_d2,led_d3;	//发光二极管,分别由按键控制//--------------------------------------------------------------------------------------------------------------------reg[2:0] key_rst;  // 20ms滤除抖动always @(posedge clk  or negedge rst_n)if (!rst_n) key_rst <= 3'b111;else key_rst <= {sw3_n,sw2_n,sw1_n};reg[2:0] key_rst_r;       //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中always @ ( posedge clk  or negedge rst_n )if (!rst_n) key_rst_r <= 3'b111;else key_rst_r <= key_rst;//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期 
wire[2:0] key_an ;
assign key_an = key_rst_r & (~key_rst);
/*
key_rst     1 1 1 0 0 1 
~key_rst    0 0 0 1 1 0
key_rst_n   _ 1 1 1 0 0 1
key_an        0 0 1 0 0
*/
//-------------------------------------------------------------------------------------------------------------------------reg[19:0]  cnt;	//计数寄存器always @ (posedge clk  or negedge rst_n)if (!rst_n) cnt <= 20'd0;	//异步复位else if(key_an) cnt <=20'd0;// 按键消抖代码核心else cnt <= cnt + 1'b1;reg[2:0] low_sw;always @(posedge clk  or negedge rst_n)if (!rst_n) low_sw <= 3'b111;else if (cnt == 20'hfffff) 	//满20ms,将按键值锁存到寄存器low_sw中	 cnt == 20'hfffff,之所以这样设计,人按下按键通常至少也要几百毫秒的时间,这20ms的时间窗口内,什么也不需要做。low_sw <= {sw3_n,sw2_n,sw1_n};//---------------------------------------------------------------------------
reg  [2:0] low_sw_r;       //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中always @ ( posedge clk  or negedge rst_n )if (!rst_n) low_sw_r <= 3'b111;else low_sw_r <= low_sw;
/*
low_sw		111 111 111 110 110 110  
~low_sw     000 000 000 001 001 001
low_sw_r        111 111 111 110 110 110led_ctrl	000 000 000 001 000 000 */
//当寄存器low_sw由1变为0时,led_ctrl的值变为高,维持一个时钟周期 
wire[2:0] led_ctrl =  low_sw_r[2:0] & ( ~low_sw[2:0]);reg d1;
reg d2;
reg d3;always @ (posedge clk or negedge rst_n)if (!rst_n) begind1 <= 1'b0;d2 <= 1'b0;d3 <= 1'b0;endelse begin		//某个按键值变化时,LED将做亮灭翻转if ( led_ctrl[0] ) d1 <= ~d1;	if ( led_ctrl[1] ) d2 <= ~d2;if ( led_ctrl[2] ) d3 <= ~d3;endassign led_d3 = d1 ? 1'b1 : 1'b0;		//LED翻转输出
assign led_d2 = d2 ? 1'b1 : 1'b0;
assign led_d1 = d3 ? 1'b1 : 1'b0;endmodule

边沿检测

always @(posedge clk  or negedge rst_n)if (!rst_n) key_rst <= 3'b111;else key_rst <= {sw3_n,sw2_n,sw1_n};reg[2:0] key_rst_r;       //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中always @ ( posedge clk  or negedge rst_n )if (!rst_n) key_rst_r <= 3'b111;else key_rst_r <= key_rst;//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期 
wire[2:0] key_an ;
assign key_an = key_rst_r & (~key_rst);
/*
key_rst     1 1 1 0 0 1 
~key_rst    0 0 0 1 1 0
key_rst_n   _ 1 1 1 0 0 1
key_an        0 0 1 0 0
*/

key_rst_n的数据延迟了一个时钟周期。

知识点1:

按位与(&):

2个多位操作数按位进行与运算,各位的结果按顺序组成一个新的多位数。例如,a=2’b10,b=2’b11,则a&b的结果为2’b10;[1]

知识点2:

 设置两个寄存器,对前一状态和后一状态进行寄存,若前后两个状态不同,则检测到了边沿。对于上升沿和下降沿的确定可以用组合逻辑比较来确定。若前一状态D[1]为高电平,后一状态D[0]为低电平,则为下降沿,反之为上升沿。[2]

当然,TQ老师用的方法不一样,道理是相同的。个人推荐文献2中提到的办法。要注意的是,后者是双边沿检测。

//设置两个寄存器,实现前后电平状态的寄存
//相当于对dat_i 打两拍always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginD <= 2'b00;endelse beginD <= {D[0], data};  	//D[1]表示前一状态,D[0]表示后一状态(新数据) endend//组合逻辑进行边沿检测assign  pos_edge = ~D[1] & D[0];assign  neg_edge = D[1] & ~D[0];assign  data_edge = pos_edge | neg_edge;

接下来是核心代码。按键按下了,计数器清零,等待20ms,然后再把按键值输出给led灯。

//-------------------------------------------------------------------------------------------------------------------------reg[19:0]  cnt;	//计数寄存器always @ (posedge clk  or negedge rst_n)if (!rst_n) cnt <= 20'd0;	//异步复位else if(key_an) cnt <=20'd0;// 按键消抖代码核心else cnt <= cnt + 1'b1;reg[2:0] low_sw;always @(posedge clk  or negedge rst_n)if (!rst_n) low_sw <= 3'b111;else if (cnt == 20'hfffff) 	//满20ms,将按键值锁存到寄存器low_sw中	 cnt == 20'hfffff,之所以这样设计,人按下按键通常至少也要几百毫秒的时间,这20ms的时间窗口内,什么也不需要做。low_sw <= {sw3_n,sw2_n,sw1_n};//---------------------------------------------------------------------------

reg d1;
reg d2;
reg d3;always @ (posedge clk or negedge rst_n)if (!rst_n) begind1 <= 1'b0;d2 <= 1'b0;d3 <= 1'b0;endelse begin		//某个按键值变化时,LED将做亮灭翻转if ( led_ctrl[0] ) d1 <= ~d1;	if ( led_ctrl[1] ) d2 <= ~d2;if ( led_ctrl[2] ) d3 <= ~d3;endassign led_d3 = d1 ? 1'b1 : 1'b0;		//LED翻转输出
assign led_d2 = d2 ? 1'b1 : 1'b0;
assign led_d1 = d3 ? 1'b1 : 1'b0;

参考文献

[1]FPGA_Verilog基础篇:verilog基本逻辑运算_verilog两组多位宽信号相与-CSDN博客

[2]FPGA基础学习——Verilog实现的边沿检测(上升沿下降沿检测)及Modelsim仿真_verilog 上升沿检测-CSDN博客 

关键字:二维码生成器在线制作方法_哈尔滨政府工程招标网_企业公司网站建设_网站seo排名优化方法

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: