这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » fpga学习--点滴记录

共5条 1/1 1 跳转至

fpga学习--点滴记录

菜鸟
2015-01-08 09:50:57     打赏

新手一枚,感觉有时候太懒,学习动力不足。只有发帖,让大家监督一下。同时,有问题的,希望各位eepw论坛的网友可以指正一下,最终,共同进步!

1月8日

按键消抖实验。(用按键来控制led灯的亮灭)

原理:

1、下降沿检测。

2、下降沿检测后计时20ms(消抖)

3、到达20ms后,再来检测按键是否仍是按下。

4、通过按键来控制led灯的亮灭。


module key(
sys_clk,
sys_rstn,
key,
led
);


input sys_clk;   //50Mhz
input sys_rstn;
input key;
output led;


//下降沿检测
reg key_first;
reg key_second;
wire neg_key;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
begin
key_first <= 1'b1;  //下降沿检测 初始值为高电平
key_second <= 1'b1; 
end
else 
begin
key_second <= key_first;
key_first <= key;
end
end 
assign neg_key = key_second & (~key_first);    //只有下降沿才是1 其他的就是0了


//20ms 计数  20ms/20ns = 1000_000  20位  0--1000_000
reg [19:0]cnt;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
cnt <= 20'd1000_000;
else if(cnt==20'd1000_000 && neg_key)
cnt <= 20'h0;
else if(cnt<20'd1000_000)
cnt <= cnt + 1'b1;
end


//20ms后再来检测按键是否按下
reg key_en; //1为按下 0为非按下
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
key_en <= 1'b0;
else if(cnt==20'd999999 && !key)  //20ms 和 还是低电平
key_en <= 1'b1;
else key_en <= 1'b0;
end


//led灯
reg led_r;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
led_r <= 1'b0;
else if(key_en)
led_r <= ~led_r;
else led_r <= led_r;
end
assign led = led_r;


endmodule


key.rar





院士
2015-01-08 11:23:56     打赏
2楼
这个是好习惯,问题是怎么监督你?一天不来我可就踹你家门去了

菜鸟
2015-01-08 14:55:49     打赏
3楼
哈哈  你找到我再说吧  年底了  公司也不忙  学点东西吧 虽然不知道有无机会从事这方面的。

菜鸟
2015-01-08 15:15:45     打赏
4楼

1月8日

按键与灯的配合实验

功能描述:按键1,控制流水灯静止或者移动; 按键2,控制流水灯向左移动;按键3,控制流水灯向右移动;

原理:

1、利用上例的key程序 建立一个模块。

2、由于有3个key 我创建了3个这样的模块。

3、key产生的按下信号 作为输入  写led程序。


主模块:


module key_led(
sys_clk,
sys_rstn,
key,
led
);

input sys_clk;
input sys_rstn;
input [2:0]key;
output [7:0]led;


wire [2:0]key_en;
key key0(
.sys_clk(sys_clk),
.sys_rstn(sys_rstn),
.key(key[0]),
.key_en(key_en[0])
);

key key1(
.sys_clk(sys_clk),
.sys_rstn(sys_rstn),
.key(key[1]),
.key_en(key_en[1])
);


key key2(
.sys_clk(sys_clk),
.sys_rstn(sys_rstn),
.key(key[2]),
.key_en(key_en[2])
);


led led0(
.key_en(key_en),
.sys_clk(sys_clk),
.sys_rstn(sys_rstn),
.led(led)
);

endmodule

 

key模块:
module key(
sys_clk,
sys_rstn,
key,
key_en
);


input sys_clk;
input sys_rstn;
input key;
output key_en;


//下降沿检测
reg key_first;
reg key_second;
wire neg_key;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
begin
key_first <= 1'b1;  //下降沿检测 初始值为高电平
key_second <= 1'b1; 
end
else 
begin
key_second <= key_first;
key_first <= key;
end
end 
assign neg_key = key_second & (~key_first);    //只有下降沿才是1 其他的就是0了


//20ms 计数  20ms/20ns = 1000_000  20位  0--1000_000
reg [19:0]cnt;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
cnt <= 20'd1000_000;
else if(cnt==20'd1000_000 && neg_key)
cnt <= 20'h0;
else if(cnt<20'd1000_000)
cnt <= cnt + 1'b1;
end


//20ms后再来检测按键是否按下
reg key_en_r; //1为按下 0为非按下
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
key_en_r <= 1'b0;
else if(cnt==20'd999999 && !key)  //20ms 和 还是低电平
key_en_r <= 1'b1;
else key_en_r <= 1'b0;
end
assign key_en = key_en_r;


endmodule

 


led模块:

module led(
key_en,
sys_clk,
sys_rstn,
led
);


input [2:0]key_en;
input sys_clk;
input sys_rstn;
output [7:0]led;


//500ms 计数
//500ms/20ns/2=12500_000    0--12499_999
reg clk_500ms;
reg [23:0]cnt;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
begin
clk_500ms <= 1'b0;
cnt <= 24'b0;
end
else if(cnt==12499_999)
begin
clk_500ms <= ~clk_500ms;
cnt <= 24'b0;
end
else cnt <= cnt + 1'b1;
end


//记录按键情况
reg move;   //是否要灯移动
reg flag;  //  0为左移动 1为右移动
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
begin
flag <= 1'b0;
move <= 1'b0;
end
else if(key_en[0])
move <= ~move;
else if(key_en[1])
flag <= 1'd0;
else if(key_en[2])
flag <= 1'd1;
else
begin
flag <= flag;
move <= move;
end
end


reg [7:0]led_r;
always @(posedge clk_500ms or negedge sys_rstn)
begin
if(!sys_rstn)
begin
led_r <= 8'b0000_0001;
end
else if(!move)   //优先级最高
led_r <= led_r;   //灯的开关
else if(flag)
led_r <= {led_r[6:0],led_r[7]};  //右移
else 
led_r <= {led_r[0],led_r[7:1]};   //左移
end
assign led = led_r;


endmodule

 



验证了能正常工作。


key_led.rar




菜鸟
2015-01-09 10:57:15     打赏
5楼

1月9日

实验:静态数码管

功能描述:实现4个数码管以1s时间同时从0-f循环递增  

思路:

    1、产生1s的时钟;

    2、在1s的时钟下计数 0--f;

    3、译码;


module shumaguan(
sys_clk,
sys_rstn,
cc,
seg
);

input sys_clk; //50mhz
input sys_rstn;
output [3:0]cc; //四位数码管  位选  低电平有效
output [7:0]seg; //段选 共阳极

//静态显示 4个数码管都打开
assign cc = 4'b0000;

//1s的时钟产生
//500ms翻转一次就是1s了  500ms/20ns = 25000_000
reg clk_1s;
reg [24:0]cnt;
always @(posedge sys_clk or negedge sys_rstn)
begin
	if(!sys_rstn)
	begin
		cnt <= 25'b1;
		clk_1s <= 1'b0;
	end
	else if(cnt==25000_000)   //计算到25000000时候翻转
	begin
		cnt <= 25'b1;
		clk_1s <= ~clk_1s;	
	end
	else cnt <= cnt + 1'b1;
end

//在1s的时钟下0-f计数
reg [3:0]count;
always @(posedge clk_1s or negedge sys_rstn)
begin
	if(!sys_rstn)
		count <= 4'b0;
	else 
		count <= count + 1'b1;
end

//译码
reg [7:0]seg;
always @(count)
begin
	case (count)
		4'h0: seg <= 8'hc0;    
		4'h1: seg <= 8'hf9;
		4'h2: seg <= 8'ha4;
		4'h3: seg <= 8'hb0;
		4'h4: seg <= 8'h99;
		4'h5: seg <= 8'h92;
		4'h6: seg <= 8'h82;
		4'h7: seg <= 8'hf8;
		4'h8: seg <= 8'h80;
		4'h9: seg <= 8'h90;
		4'ha: seg <= 8'h88;
		4'hb: seg <= 8'h83;
		4'hc: seg <= 8'hc6;
		4'hd: seg <= 8'ha1;
		4'he: seg <= 8'h86;
		4'hf: seg <= 8'h8e;
		default:;
	endcase
end

endmodule

 shumaguan.rar


共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]