我的流水灯实验——作业1(下)
实验目的: 完成经典的流水灯实验 实验内容: 根据版主51FPGA的教程,学习流水灯实验,之后完成作业,并提供视频演示。 源代码如下:
//`define homework 0
module led_water(sys_clk, sys_rstn, led);
input sys_clk; input sys_rstn; output [7:0] led; reg [7:0] led; reg [24:0] delay_cnt;always @ (posedge sys_clk or negedge sys_rstn)
begin if(!sys_rstn) delay_cnt <= 25'd0; else begin if(delay_cnt == 25'd2499999) delay_cnt <= 25'd0; else delay_cnt <= delay_cnt + 1'b1; end end always @(posedge sys_clk or negedge sys_rstn) begin if(!sys_rstn) led <= 8'b11111111; else begin if(delay_cnt == 25'd2499999) begin `ifdef homework led <= led >> 1; `else led <= led << 1; `endif if(led == 8'b00000000) led <= 8'b11111111; end else led <= led; end end endmodule 实验结果: 达到实验预期要求,简单而漂亮的流水灯正在运行。简单视频如下:作业: 此次作业采用预编译的选择编译形式,只需要把第一行预定义去掉即为作业要求——流水灯向左显示。
由于数码管买错了,因为数码管实验不得不暂停。但是时间是不等人的,因此先进行下面的实验,即按键实验。 实验目的: 按键录入信息,主要为数字量的输入。 实验内容: 根据版主的教程,来编写相应的实验。
`define experiment2
`ifdef experiment1
module keypress(sys_clk, sys_rstn, key_in, led_out);
input sys_clk;
input sys_rstn;
input key_in;
output led_out;
reg led_out;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
led_out <= 1'b1;
else if(!key_in)
led_out <= ~led_out;
else
led_out <= led_out;
end
endmodule
`endif
`ifdef experiment2
module keypress(sys_clk, sys_rstn, key_in, led_out);
input sys_clk;
input sys_rstn;
input key_in;
output led_out;
reg led_out;
reg [19:0] delay_cnt;
wire key_scan;
wire key_low;
reg key_samp;
reg key_samp_r;
reg key_rst;
reg key_rst_r;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
key_samp <= 1'b1;
else
key_samp <= key_in;
end
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
key_samp_r <= 1'b1;
else
key_samp_r <= key_samp;
end
assign key_scan = key_samp_r & (~key_samp);
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
delay_cnt <= 20'h0;
else if(key_scan)
delay_cnt <= 20'h0;
else
delay_cnt <= delay_cnt + 1'b1;
end
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
key_rst <= 1'b1;
else if(delay_cnt == 20'hfffff)
key_rst <= key_in;
end
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
key_rst_r <= 1'b1;
else
key_rst_r <= key_rst;
end
assign key_low = key_rst_r & (~key_rst);
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
led_out <= 1'b1;
else if(key_low)
led_out <= ~led_out;
else
led_out <= led_out;
end
endmodule
`endif 实验结果: 实验一、按键则LED灯反转,无消抖。我们看到随着按键的按下,LED灯有一个短暂的微亮的过程,即由于抖动的存在,LED灯进行了多次反转,因此,亮度出现短暂微亮。当然,也不是每次都能正常的反转,有的时候是亮几次,然后随着按键的抬起,灯的亮度几乎是随机状态。 实验二、添加了消抖功能果然不一样了。每次按键都能正常返回预定的数据。即,按一次LED灯就反转一 次。 作业: 由于数码管未能正确匹配,因此,作业要稍后再完成了。
一波三折的数码管实验
由于时间有些紧,加之换货的路途遥远,不过,还好,找到一个闲置的,于是抓紧实验,可是过程又是如此的一波三折……
实验目的: 点亮这信息丰富的4位8位段码LED灯。使其依次显示4位的0至F。 实验内容: 依据51FPGA版主的教程编写如下代码:module led_display(sys_clk, sys_rstn, sm_seg, sm_bit);
input sys_clk; input sys_rstn; output [7:0] sm_seg; output [7:0] sm_bit; reg [7:0] sm_seg; wire [7:0] sm_bit; reg [3:0] disp_dat; reg [25:0] delay_cnt; always @(posedge sys_clk or negedge sys_rstn) begin if(!sys_rstn) delay_cnt <= 26'd0; else begin if(delay_cnt == 26'd49999999) delay_cnt <= 26'd0; else delay_cnt <= delay_cnt + 1'b1; end end always @(posedge sys_clk or negedge sys_rstn) begin if(!sys_rstn) disp_dat <= 4'd0; else begin if(delay_cnt == 26'd49999999) disp_dat <= disp_dat + 1'b1; else disp_dat <= disp_dat; end end always @(disp_dat) begin case(disp_dat) 4'h0 : sm_seg = 8'hc0; 4'h1 : sm_seg = 8'hf9; 4'h2 : sm_seg = 8'ha4; 4'h3 : sm_seg = 8'hb0; 4'h4 : sm_seg = 8'h99; 4'h5 : sm_seg = 8'h92; 4'h6 : sm_seg = 8'h82; 4'h7 : sm_seg = 8'hf8; 4'h8 : sm_seg = 8'h80; 4'h9 : sm_seg = 8'h90; 4'ha : sm_seg = 8'h88; 4'hb : sm_seg = 8'h83; 4'hc : sm_seg = 8'hc6; 4'hd : sm_seg = 8'ha1; 4'he : sm_seg = 8'h86; 4'hf : sm_seg = 8'h8e; endcase end assign sm_bit = 8'b00000000; endmodule 实验结果: 成功编译后下载至fpga内,则依次显示,与预期效果一致。请大家稍后看视频,检查我的成果。 实验感受: 遭遇第一折,编译成功后,下载至芯片内,发现LED显示残缺,第一反应,代码wrong!仔细查找,并无error。再查找原理图,对照物料清单,发现使用的为共阳极的LED数码管,而其编号却为共阴极的,至此,发现数码管购买错误,不得不暂停实验。 遭遇第二折,偶然发现还有一个闲置的LED数码管,恰好为共阳极的,于是兴奋的直接拿过来。为了节省开支,我焊了一个座,这样数码管就可以插拔了,可是,接口使用的为2.54mm的,而数码管的引脚为细引脚,这样造成了接触不良,要么这边的亮,要么那边的亮。唉,为了省钱再想办法。原因是细,那么我将其弄成一个小小的曲度,这样就增大了接触面积,果然问题得到解决。 遭遇第三折,不再闪,不再接触不良。却有一位灯不亮。因为只有一位灯,考虑极可能为片选虚焊造成。找出原理图,第三位对应的为R97与Q5.拿起电烙铁进行补焊。重新上电,激动人心的时刻终于到来。四位数码管终于可以正常亮了。module simple_fsm(sys_clk, sys_rstn, sm_seg, sm_bit, key1);
input sys_clk; input sys_rstn; input key1; output [7:0]sm_seg; output [7:0]sm_bit; reg [7:0] sm_seg; wire [7:0] sm_bit; reg [3:0] disp_dat; reg [25:0] delay_cnt; reg [1:0] state; parameter Start = 2'b01, Stop = 2'b10; always @(posedge sys_clk or negedge sys_rstn) begin if(!sys_rstn) begin delay_cnt <= 26'd0; /* 默认状态 */ state <= Stop; end else case(state) Stop: begin if(key1) state <= Start; end Start: begin if(!key1) state <= Stop; if(delay_cnt == 26'd49999999) delay_cnt <= 26'd0; elsedelay_cnt <= delay_cnt + 1'b1;
end default: state <= Start; endcase end always @(posedge sys_clk or negedge sys_rstn) begin if(!sys_rstn) disp_dat <= 4'd0; else begin if(delay_cnt == 26'd49999999) disp_dat <= disp_dat + 1'b1; else disp_dat <= disp_dat; end end always @(disp_dat) begin case(disp_dat) 4'h0 : sm_seg = 8'hc0; 4'h1 : sm_seg = 8'hf9; 4'h2 : sm_seg = 8'ha4; 4'h3 : sm_seg = 8'hb0; 4'h4 : sm_seg = 8'h99; 4'h5 : sm_seg = 8'h92; 4'h6 : sm_seg = 8'h82; 4'h7 : sm_seg = 8'hf8; 4'h8 : sm_seg = 8'h80; 4'h9 : sm_seg = 8'h90; 4'ha : sm_seg = 8'h88; 4'hb : sm_seg = 8'h83; 4'hc : sm_seg = 8'hc6; 4'hd : sm_seg = 8'ha1; 4'he : sm_seg = 8'h86; 4'hf : sm_seg = 8'h8e; endcase end assign sm_bit = 8'b00001111; endmodule 实验结果: 与预期的结果一致,按下Key2键后,显示暂停,松开后,显示继续。 视频稍后奉上。数码段码管在实际生活中应用广泛,主要因为其价格低廉,性能稳定,在低成本的应用项目里被广泛采用。今天这个实验为动态扫描式操作数码管,为以后使用数码管显示提供接口模块。
实验目的:今天这个实验为动态扫描式操作数码管,为以后使用数码管显示提供接口模块。能够完成按位显示任意数字与字母或者图案。
实验内容:此部分内容自己研究了半天,后来发现版主 51FPGA 已经在教程里面进行了说明。在对其代码进行了细致分析后,最终还是采用以版主的代码为基础,在其上进行修改与扩充的方式。代码内容如下:
/****************************************Copyright (c)****************************************************
** jobszheng@vip.sohu.com
**
**--------------File Info---------------------------------------------------------------------------------
** File Name: led_dynamic.v
** Last modified Date: 2013-03-30 10:07
** Last Version:
** Description: 使用动态扫描的方式来显示数码管,参考自51fpga
**
**--------------------------------------------------------------------------------------------------------
** Created By: Jobs Zheng
** Created date: 2013-03-30 10:07
** Version: v1.0
** Descriptions: The original version 初始版本
**
*********************************************************************************************************/
module led_dynamic(sys_clk, sys_rstn, sm_seg, sm_bit);
input sys_clk;
input sys_rstn;
output [7:0] sm_seg;
output [7:0] sm_bit;
reg [7:0] sm_seg;
reg [7:0] sm_bit;
reg [4:0] dataout_buf;
reg [2:0] disp_dat;
reg [15:0] delay_cnt;
always @ (posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
delay_cnt <= 16'd0;
else
begin
if(delay_cnt == 16'd49999)
delay_cnt <= 16'd0;
else
delay_cnt <= delay_cnt + 1'b1;
end
end
always @ (posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
disp_dat <= 4'd0;
else
begin
if(delay_cnt == 16'd49999)
disp_dat <= disp_dat + 1'b1;
else
disp_dat <= disp_dat;
end
end
always @ (disp_dat)
begin
case(disp_dat)
3'b000:
sm_bit = 8'b11111110;
3'b001:
sm_bit = 8'b11111101;
3'b010:
sm_bit = 8'b11111011;
3'b011:
sm_bit = 8'b11110111;
3'b100:
sm_bit = 8'b11101111;
3'b101:
sm_bit = 8'b11011111;
3'b110:
sm_bit = 8'b10111111;
3'b111:
sm_bit = 8'b01111111;
default :
sm_bit = 8'b11111110;
endcase;
end
always @(sm_bit)
begin
case(sm_bit)
8'b11111110:
dataout_buf = 17;
8'b11111101:
dataout_buf = 17;
8'b11111011:
dataout_buf = 16;
8'b11110111:
dataout_buf = 0;
8'b11101111:
dataout_buf = 11;
8'b11011111:
dataout_buf = 5;
8'b10111111:
dataout_buf = 17;
8'b01111111:
dataout_buf = 17;
default :
dataout_buf = 8;
endcase
end
always @(dataout_buf)
begin
case(dataout_buf)
5'h0: sm_seg = 8'hc0;
5'h1: sm_seg = 8'hf9;
5'h2: sm_seg = 8'ha4;
5'h3: sm_seg = 8'hb0;
5'h4: sm_seg = 8'h99;
5'h5: sm_seg = 8'h92;
5'h6: sm_seg = 8'h82;
5'h7: sm_seg = 8'hf8;
5'h8: sm_seg = 8'h80;
5'h9: sm_seg = 8'h90;
5'ha: sm_seg = 8'h88;
5'hb: sm_seg = 8'h83;
5'hc: sm_seg = 8'hc6;
5'hd: sm_seg = 8'ha1;
5'he: sm_seg = 8'h86;
5'hf: sm_seg = 8'h8e;
5'd16: sm_seg = 8'hf1; /* 字母 ‘j’ */
default:
sm_seg = 8'hff;
endcase
end
endmodule
实验结果:上电,使用jtag下载后,得到预期的效果。甚是欣喜。
实验感受:
不知道由于什么原因,开始的时候发现数码管的显示位是倒序,即最右边为位0。于是,通过更改pin的分布来进行更正。可以修改后,发现显示结果成了残缺的显示。查看代码未见异常,遂陷入痛苦的沉思中……
突然,一灵感过来“是不是我将位选与片选的引脚弄混了”,于是再次仔细查看代码与对应关系,发现果然是引脚位选与片选错了,我将位选的顺序反序相连了,因此才有了残码的显示。更改回位选,再将修改了片选位,终于得到了预期的效果“jobs” ——我的logo
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 | |
【分享评测,赢取加热台】使用8051单片机驱动WS2812被打赏40分 |