357482894的进程贴-预习篇
10.7 第一个实验——LED闪烁灯
控制LED闪烁,每一秒闪烁一次
程序:
module led_1
(
clk,rst,led
);
input clk,rst;
output led;
parameter T10ms=26'd50_000_000;
reg [25:0]count;
reg led_f;
always @ (posedge clk or negedge rst)
if(!rst)
count<=26'd0;
else if(count==T10ms)
count<=26'd0;
else
count<=count+1'd1;
always @ (posedge clk or negedge rst)
if(!rst)
led_f<=1'b1;
else if(count<25'd25_000_000)
led_f<=1'b0;
else
led_f<=1'b1;
assign led=led_f;
endmodule
现象是LED1每个一秒闪烁一次。
实验过程中的问题:
第一次下载后,其余未使用的LED和数码管全亮,编译时提示所有未用输出引脚默认置低。这时需要修改工程配置,Assignments-Device-Device and Pin Options-Unused Pins,改成三态模式就可以了。
D1-D8每隔一秒变动一次,D11每隔一秒闪烁一次,视频演示:
源代码:
module led_3(
clk,rst_n,led1,led2
);
input clk,rst_n;
output led1;
output [7:0]led2;
reg led1_f;
reg [7:0]led2_f;
reg [24:0]count;
parameter T0s5=25'd25_000_000;
parameter T0s25=24'd12_500_000;
always @ (posedge clk or negedge rst_n)
if(~rst_n)
count<=25'd0;
else if(count==T0s5)
count<=25'd0;
else
count<=count+1'b1;
always @ (posedge clk or negedge rst_n)
if(~rst_n)
begin
led1_f<=1'b1;
led2_f<=8'b1111_1111;
end
else if(count==T0s25||count==T0s5)
begin
led1_f<=~led1_f;
if(count==T0s5)
if(led2_f==8'b1111_1111)
led2_f<=8'b1111_1110;
else
led2_f<={led2_f[6:0],1'b1};
end
assign led1=led1_f;
assign led2=led2_f;
endmodule
10.14 LED跑马灯+流水灯
利用板上的11个LED实现的多种方式的组合,效果:
代码;
module led_4(rstn,clk,led1,led10);
input rstn,clk;
output [9:0]led10;
output led1;
reg [9:0]led10_f;
reg led1_f;
reg [2:0]state;
reg [25:0]count;
always @ (posedge clk or negedge rstn)
if(~rstn)
begin
count<=1'b0;
end
else if(count==26'd50_000_000)
count<=1'b0;
else
count<=count+1'b1;
always @ (posedge clk or negedge rstn)
if(~rstn)
begin
led1_f<=1'b1;
state<=1'b0;
led10_f<=10'b11_1111_1111;
end
else if(count==25'd25_000_000 || count==26'd50_000_000)
begin
led1_f<=~led1_f;
if(count==26'd50_000_000)
begin
if(led10_f==10'b11_1111_1111 || led10_f==10'b00_0000_0000)
begin
if(state==3'b110 || state==3'b000)
state=3'b001; //not "<="
else state=state+1'b1; //not "<="
case(state)
3'b001: led10_f<=10'b11_1111_1110;
3'b010: led10_f<=10'b10_0000_0000;
3'b011: led10_f<=10'b11_1111_1110;
3'b100: led10_f<=10'b01_1111_1111;
3'b101: led10_f<=10'b00_0000_0001;
3'b110: led10_f<=10'b01_1111_1111;
default:led10_f<=10'h3ff;
endcase
end
else
case(state)
3'b001: led10_f<=led10_f<<1;
3'b010: led10_f<={1'b1,led10_f[9:1]};
3'b011: led10_f<={led10_f[8:0],1'b1};
3'b100: led10_f<=led10_f>>1;
3'b101: led10_f<={led10_f[8:0],1'b1};
3'b110: led10_f<={1'b1,led10_f[9:1]};
default:led10_f<=10'h3ff;
endcase
end
end
assign led1=led1_f;
assign led10=led10_f;
endmodule
这次遇到了个问题,如何使用阻塞性与非阻塞性过程赋值,问题出在注释处。
代码需要先改变变量state的值,然后根据state的值改变led10_f。如果使用非阻塞性赋值,没有等到state的值改变就改变led10_f,不能达到预定效果。
10.14 读取按键信号
利用8个按键控制8个LED的亮灭。按一下对应的LED点亮,再按一下灭。
代码:
module key_led(key,led);
input [7:0]key;
output [7:0]led;
reg [7:0]led1;
integer i;
always @ (key)
for(i=0;i<8;i=i+1)
if(key[i]==1'b0)
led1[i]<=~led1[i];
assign led=led1;
endmodule
由于没有进行消抖处理,实验中会有抖动现象。
下一步进行按键消抖。
10.14 按键消抖实验
按键在按下或者释放时会产生抖动,处于不稳定的状态。上一个实验直接读取按键值,产生了不稳定的现象。因此需要处理好这个抖动时间。下图为按键波形:
一般认为,按下时有20ms的不稳定时间。
消抖的方法是,在检测到有下降沿时锁存一个状态,然后在20ms后再锁存一个状态,然后对两个状态进行判断。
代码为;
module key_led(rstn,clk,key,led);
input rstn,clk;
input [7:0]key;
output [7:0]led;
reg [7:0]key1;
always @ (posedge clk or negedge rstn)
if(~rstn) key1<=8'hff;
else key1<=key;
reg [7:0]key2;
always @ (posedge clk or negedge rstn)
if(~rstn) key2<=8'hff;
else key2<=key1;
//check the negedge
wire [7:0]key_rst=key1&(~key2);
reg [19:0]count;
always @ (posedge clk or negedge rstn)
if(~rstn) count<=20'd0;
else if(key_rst!=1'b0) count<=20'd0;
else count<=count+1'b1;
reg [7:0]key3;
always @ (posedge clk or negedge rstn)
if(~rstn) key3<=8'hff;
else if(count==20'd1_000_000)
key3<=key;
reg [7:0]key4;
always @ (posedge clk or negedge rstn)
if(~rstn) key4<=8'hff;
else key4<=key3;
//check the states now and before 20ms
wire [7:0]key_f=key4&(~key3);
integer i;
reg [7:0]led_f;
always @ (posedge clk or negedge rstn)
if(~rstn) led_f<=8'hff;
else
for(i=0;i<8;i=i+1)
if(key_f[i]==1'b1)
led_f[i]<=~led_f[i];
assign led=led_f;
endmodule
前两个always语句是为了判断下降沿,然后产生延时,再在第四个always语句中取20ms后的状态,前一状态与后一状态取反相与,判断按键是否被按下。
经实验验证,这种方法可以很好的对按键进行消抖。
代码:
module sw_led(clk,sw,led);
input clk;
input[7:0]sw;
output[7:0]led;
reg[7:0]led_f;
always @ (posedge clk)
led_f<=sw;
assign led=led_f;
endmodule
代码比较简单,但在编译时出现问题:
这是由于Pin108默认为nCEO,即编程引脚,这样就会造成功能重复分配。
解决方法是将其修改为普通IO,assignments>device>device and pin options>dual-purpose pins:
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |