EDA实验-----4*4矩阵键盘与数码管显示测试(Quartus ‖)

目录

一、实验目的

二、实验仪器设备

三、实验原理

四、实验要求

五、实验步骤

六、实验报告

七、实验过程

1.矩阵键盘按键原理

2.数码管原理

3.分频器代码

 4.电路图连接

 5.文件烧录


 

一、实验目的

  1. 了解数码管的工作原理;
  2. 掌握4*4矩阵键盘和数码管显示的编程方法。
  3. 学会用于Verilog语言进行程序设计。

二、实验仪器设备

  1. PC机一台。
  2. FPGA实验开发系统一套。

三、实验原理

本实验通过扫描4*4矩阵键盘的值,在数码管上显示对应按钮的编号数据。矩阵键盘及数码管电路如下所示。

b5731399c96e4300b93feb6b8d6b7ab0.png

a2e0cec5e6b84f93b222318559042156.png 

四、实验要求

  1. 预习教材中的相关内容。
  2. 阅读并熟悉本次实验的内容。
  3. 完成实验内容。

五、实验步骤

  1. 启动 Quartus II 建立一个空白工程,选择的器件为 Altera 公司的 Cyclone 系列的 EP2C8Q240C8芯片,命名为 keyarray.qpf;
  2. 新建一个 Schematic File 文件,命名为 keyarray.bdf分别新建 3 个 Verilog HDL File 文件,分别命名为 seg_show.v、 divclk.v、 keyarraycontrol.v。输入程序代码并保存(对应源程序 8),然后进行综合编译。若在编译过程中发现错误,则找出错误并更正错误,直至编译成功为止。
  3. 从设计文件创建模块(FileàCreat UpdateàCreat Symbol Files for Current File) ,seg_show.v 生成名为 seg_show.bsf; divclk.v 生成名为 divclk.bsf; keyarraycontrol.v 生成名为keyarraycontrol.bsf;
  4. 在 keyarray.bdf 文件中,在空白处双击鼠标左键,在 Symbol 对话框左上角的 libraries 中,分别将 Project 下的 seg_show, divclk, keyarraycontrol 模块放在图形文件 keyarray.bdf 中,加入输入、输出引脚,双击每个引脚,进行引脚命名,并锁定管脚,将未使用的引脚设置为三态输入(一定要设置,否则可能会损坏芯片);

    12a080d545ca442a932eceeeca2128fa.png

  5. 将 keyarray.bdf 设置为顶层实体。对该工程文件进行全程编译处理,若在编译过程中出现错误,则找出错误并更正,直至编译通过为止;
  6. 将 USB-Blaster 下载电缆的两端分别连接到 PC 机的 USB 接口和 EDA 实验箱上的 JTAG 下载口上,打开电源,执行下载命令,把程序下载到 FPGA 器件中,此时,即可在 EDA 实验箱上通过按下相应的按键使蜂鸣器发出对应的音符声响。

完整的顶层模块原理图如图所示:308baaf78f574596add4486f5ddd43bb.png

六、实验报告

  1. 总结Verilog设计多路选择器使用的最基本与核心的语法知识。
  2. 对仿真的结果进行分析。
  3. 讨论自己在设计过程中遇到的问题、解决的过程以及收获体会。

七、实验过程

创建项目、创建Verilog文件、写代码、进行波形仿真、画出电路图、设置管脚和三态、烧录文件

1.矩阵键盘按键原理

在讲实验过程之前,先讲讲相关的原理,不知道原理的话就很难去写代码。

2fa17b571f7e4ce0857c707e4f0c422e.png

d20180ba4d504e73abdfeb3195f8812d.png

矩阵按键模块是先按行选取到某一行,然后再选列,跟矩阵选择某一个点的原理是一样的,如果按下这个按键的时候,此时两边的开关是接通的,这时候就会返回到一个矩阵按键回馈的信息,我们只需要去读取到这个信息,然后再根据行列的相关位置,把这个信息转换为相对于的数字返回即可。

Verilog代码(读取到矩阵按键按下的位置,输出相对于的数字):

module keyarraycontrol(clk,rst,row,col,keydata);
input				clk;
input 				rst;
input	[3:0]		row;
output	reg[3:0]	col;
output 	reg[3:0]	keydata;
reg  keyint;

reg [19:0] cnt;      
//分频获得键盘扫描频率                  
always @ (posedge clk, negedge rst) 
  if (!rst) 
    cnt <= 0; 
  else 
    cnt <= cnt + 1'b1; 
//将计数的最高位赋给key_clk 
wire key_clk = cnt[19];                // (2^20/50M = 21)ms  
//设定扫描状态判断参数
parameter NO_KEY_PRESSED = 6'b000_001;  // 如果没有按键按下的时候
parameter SCAN_COL0      = 6'b000_010;  // 按下第一行按键
parameter SCAN_COL1      = 6'b000_100;  // 按下第二行按键
parameter SCAN_COL2      = 6'b001_000;  // 按下第三行按键
parameter SCAN_COL3      = 6'b010_000;  // 按下第四行按键
parameter KEY_PRESSED    = 6'b100_000;  // 有按键按下状态

reg [5:0] current_state, next_state;    // 当前状态,,,下一个状态

always @ (posedge key_clk, negedge rst) 
  if (!rst) 
    current_state <= NO_KEY_PRESSED; 
  else 
    current_state <= next_state; 

// 
always @ * 
  case (current_state) 
    NO_KEY_PRESSED :  //
        if (row != 4'hF) 
          next_state = SCAN_COL0; 
        else 
          next_state = NO_KEY_PRESSED; 
    SCAN_COL0 :                         // 
        if (row != 4'hF) 
          next_state = KEY_PRESSED; 
        else 
          next_state = SCAN_COL1; 
    SCAN_COL1 :                         // 
        if (row != 4'hF) 
          next_state = KEY_PRESSED; 
        else 
          next_state = SCAN_COL2;     
    SCAN_COL2 :                         // 
        if (row != 4'hF) 
          next_state = KEY_PRESSED; 
        else 
          next_state = SCAN_COL3; 
    SCAN_COL3 :                         //
        if (row != 4'hF) 
          next_state = KEY_PRESSED; 
        else 
          next_state = NO_KEY_PRESSED; 
    KEY_PRESSED :                       // 
        if (row != 4'hF) 
          next_state = KEY_PRESSED; 
        else 
          next_state = NO_KEY_PRESSED;                 
  endcase 
reg [3:0] col_val, row_val;             // 


always @ (posedge key_clk, negedge rst) 
  if (!rst) 
  begin 
    col<= 4'h0; 
    keyint<=0; 
  end 
  else 
    case (next_state) 
      NO_KEY_PRESSED :                  // 
      begin 
        col <= 4'h0; 
        keyint <= 0;       // 
      end 
      SCAN_COL0 :                       // 
        col <= 4'b1110; 
      SCAN_COL1 :                       
        col <= 4'b1101; 
      SCAN_COL2 :                       // 
        col <= 4'b1011; 
      SCAN_COL3 :                       // 
        col <= 4'b0111; 
      KEY_PRESSED :                     // 
      begin 
        col_val<= col;        // 得到列的值
        row_val<= row;        // 得到行的值
        keyint <= 1;          // 
      end 
    endcase 

always @ (posedge key_clk, negedge rst) 
  if (!rst) 
    keydata <= 16'h0000; 
  else 
    if (keyint) 
      case ({col_val, row_val}) 
        8'b1110_1110 : keydata <= 8'd0; 
        8'b1110_1101 : keydata <= 8'd4; 
        8'b1110_1011 : keydata <= 8'd8;  
        8'b1110_0111 : keydata <= 8'd12;  
         
        8'b1101_1110 : keydata <= 8'd1;
        8'b1101_1101 : keydata <= 8'd5;
        8'b1101_1011 : keydata <= 8'd9; 
        8'b1101_0111 : keydata <= 8'd13;
         
        8'b1011_1110 : keydata <= 8'd2; 
        8'b1011_1101 : keydata <= 8'd6;  
        8'b1011_1011 : keydata <= 8'd10; 
        8'b1011_0111 : keydata <= 8'd14; 
         
        8'b0111_1110 : keydata <= 8'd3;
        8'b0111_1101 : keydata <= 8'd7;
        8'b0111_1011 : keydata <= 8'd11;
        8'b0111_0111 : keydata <= 8'd15; 
        default:  keydata <= keydata;        
      endcase 
     else
		keydata <= keydata; 
endmodule

2.数码管原理

a9fa396583f94ec78dd1558ef394d994.png

数码管分为共阴和共阳两种,通过选择器的高低电平去判断选取到的位数,所以数码管的读取是先选择位,然后再去显示亮的灯。下图所示,下面的74HC573芯片是用于选位处理的(这个芯片必须接地或者接上低电平才可以正常工作),由于上面的U1也是同一个芯片,所以这里先进行选位的时候要先把上面的那个芯片锁住,然后下面的芯片工作,这里我们不难看出这是一个共阴的数码管,每一个数码管的选位都是连接到阴极处的(接地),所以选位的时候只需要去进行连接到地,那就可以实现通电。选完位之后,就开始选段,所以这时候要锁住下面的芯片,让上面的工作,这个数码管的选段是根据某一个段通入高电平才会亮,其每一段对应的电平位置是 hgfedcba,比如通入8个电平: 0000 0110,那么就会显示数字1,因为只有b和c段亮了。

b5731399c96e4300b93feb6b8d6b7ab0.png

数码管生成器模拟软件:数码管 代码 生成器 (treee.com.cn)

Verilog代码(获取到相对于的数字,然后在数码管静态显示出来): 


module seg(clk, data, sel_lock, seg_lock, gpio);	
input clk;			
input[3:0] data;
output reg sel_lock;
output reg seg_lock;
output [7:0] gpio;		

reg [7:0] gpio;	
reg [3:0] disp_dat;		
reg  cnt;			
reg [12:0] cnt2;

always@(posedge clk)		
		//cnt2 = cnt2 + 1;
		//if (cnt <1000)
	begin
		cnt = cnt + 1;	
		cnt2 = cnt2 + 1;
		if (cnt)
		begin
			sel_lock = 1'b1;
			seg_lock = 1'b0;		
			gpio = 8'h00;
			#20 sel_lock = 1'b0;
			seg_lock = 1'b1;	
		end
		else
		begin
			sel_lock = 1'b0;
			seg_lock = 1'b1;		
			
			disp_dat = data;		
			case(disp_dat)		
				
					4'h0:gpio=8'h3f;	//0 0011 1111
					4'h1:gpio=8'h06;	//1 0000 0110
					4'h2:gpio=8'h5b;	//2
					4'h3:gpio=8'h4f;	//3
					4'h4:gpio=8'h66;	//4
					4'h5:gpio=8'h6d;	//5
					4'h6:gpio=8'h7d;	//6
					4'h7:gpio=8'h07;	//7
					4'h8:gpio=8'h7f;	//8
					4'h9:gpio=8'h6f;	//9
					4'ha:gpio=8'h77;	//a
					4'hb:gpio=8'h7c;	//b
					4'hc:gpio=8'h39;	//c
					4'hd:gpio=8'h5e;	//d
					4'he:gpio=8'h79;	//e
					4'hf:gpio=8'h71;	//f
			
					
			endcase
			
			#20 sel_lock = 1'b1;
			seg_lock = 1'b0;
		end
end
endmodule	
				

3.分频器代码

module divclk(inclk,outclk);
	input inclk;
	output outclk;
	reg outclk;
	reg [16:0] cnt;
	initial
		begin
			cnt=0;
			outclk=0;
		end
	
	always @(posedge inclk)
		begin
			cnt=cnt+1;
			if (cnt==0)
				outclk = outclk+1;
		end
endmodule 

 4.电路图连接

写好了Verilog代码,就进行分析错误,分析无误后,我们就对这些代码生成子模块文件。然后就创建block文件开始连接电路图,电路图以及管脚配置如下:7965bcb8120242cbbafe06f67ddef94b.png

 5.文件烧录

弄好了之后就是最后一步操作了,把没用到的管脚设置三态,然后烧录文件。

点击Assignment, Device

72fc4c7b723a4590974b9fe2e43a9c73.png

然后点击这里,设置管脚。 

ab08cd8cd2a5450983f6f094f87f0865.png 选择第一个就行了,就是把多余的管脚设置三态。a779aee811ee4689a875b6f7b7ec78af.png

 然后就是编译运行文件,运行无误。8fda9f81c00f49318748cc490cbd77b8.png

点击此处,烧录文件。 

ea76d796dcb248c3b5125fdc9a9d0662.png 

这里我们会看到,下面有一个芯片,这个也就是我们写好了的sof文件,然后就是通过你的电脑接口去连接到开发板,如果你看到上面有一个No Hardware的时候,你点击旁边的按钮进行接口设置,设置为USB接口即可(USB线连接了你的开发板就会自动显示出来的)。最后点击start就可以进行烧录了。 

以上就是本期的全部内容了,我们下一次见!

分享一张壁纸:9537723833a24b41bace354bce482686.png

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/166292.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

原理Redis-IntSet

IntSet IntSet是Redis中set集合的一种实现方式&#xff0c;基于整数数组来实现&#xff0c;并且具备长度可变、有序等特征。 结构如下&#xff1a; typedef struct intset {uint32_t encoding; /* 编码方式&#xff0c;支持存放16位、32位、64位整数*/uint32_t length; /* 元素…

ICCV2023 Tracking paper汇总(二)(多目标跟随、单目标跟随等)

十六、Integrating Boxes and Masks: A Multi-Object Framework for Unified Visual Tracking and Segmentation paper&#xff1a; https://openaccess.thecvf.com/content/ICCV2023/papers/Xu_Integrating_Boxes_and_Masks_A_Multi-Object_Framework_for_Unified_Visual_ICC…

机器视觉系统中的工业镜头的参数

光学倍率 β 焦距 f F值&#xff08;光圈&#xff09;Fno. 数值孔径 NA 工作距离 WD 视场&#xff08;视场角&#xff0c;视野&#xff09; 景深DOF 分辨率、分辨力 MTF 畸变

6 Redis的慢查询配置原理

1、redis的命令执行流程 redis的慢查询只针对步骤3 默认情况下&#xff0c;慢查询的阈值是10ms

Jmeter做接口测试

1.Jmeter的安装以及环境变量的配置 Jmeter是基于java语法开发的接口测试以及性能测试的工具。 jdk&#xff1a;17 (最新的Jeknins&#xff0c;只能支持到17) jmeter&#xff1a;5.6 官网&#xff1a;http://jmeter.apache.org/download_jmeter.cgi 认识JMeter的目录&#xff1…

【开源】基于Vue.js的创意工坊双创管理系统

项目编号&#xff1a; S 049 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S049&#xff0c;文末获取源码。} 项目编号&#xff1a;S049&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 管理员端2.2 Web 端2.3 移动端 三、…

PgSQL技术内幕-Bitmap Index Scan

PgSQL技术内幕-Bitmap Index Scan 1、简介 Bitmap索引扫描是对索引扫描的一个优化&#xff0c;通过建立位图的方式将原来的随机堆表访问转换成顺序堆表访问。主要分为两点&#xff1a;1&#xff09;管理每个Bitmap的hash slot没用完时&#xff0c;每个Bitmap代表每个heap页中满…

【计算思维】蓝桥杯STEMA 科技素养考试真题及解析 4

1、下列哪个选项填到填到下图空缺处最合适 A、 B、 C、 D、 答案&#xff1a;D 2、按照如下图的规律摆放正方形&#xff0c;第 5 堆正方形的个数是 A、13 B、14 C、15 D、16 答案&#xff1a;D 3、从右面观察下面的立体图形&#xff0c;看到的是 A、 B、 C、 D、 答…

ClickHouse数据一致性

查询CK手册发现&#xff0c;即便对数据一致性支持最好的Mergetree&#xff0c;也只是保证最终一致性&#xff1a; 我们在使用 ReplacingMergeTree、SummingMergeTree 这类表引擎的时候&#xff0c;会出现短暂数据不一致的情况。 在某些对一致性非常敏感的场景&#xff0c;通常有…

电子学会C/C++编程等级考试2022年03月(一级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…

你知道什么是SaaS吗?

你知道什么是SaaS吗&#xff1f; 云服务架构的三个概念 PaaS 英文就是 Platform-as-a-Service&#xff08;平台即服务&#xff09;PaaS&#xff0c;某些时候也叫做中间件。就是把客户采用提供的开发语言和工具&#xff08;例如Java&#xff0c;python, .Net等&#xff09;开…

测试Bard和ChatGPT关于双休的法规和推理

Bard是试验品&#xff0c;chatgpt是3.5版的。 首先带着问题&#xff0c;借助网络搜索&#xff0c;从政府官方网站等权威网站进行确认&#xff0c;已知正确答案的情况下&#xff0c;再来印证两个大语言模型的优劣。 想要了解的问题是&#xff0c;在中国&#xff0c;跟法定工作…

莹莹API管理系统源码附带两套模板

这是一个API后台管理系统的源码&#xff0c;可以自定义添加接口&#xff0c;并自带两个模板。 环境要求 PHP版本要求高于5.6且低于8.0&#xff0c;已测试通过的版本为7.4。 需要安装PHPSG11加密扩展。 已测试&#xff1a;宝塔/主机亲测成功搭建&#xff01; 安装说明 &am…

原理Redis-动态字符串SDS

动态字符串SDS Redis中保存的Key是字符串&#xff0c;value往往是字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。 不过Redis没有直接使用C语言中的字符串&#xff0c;因为C语言字符串存在很多问题&#xff1a; 获取字符串长度的需要通过运算非二进制安全…

基于深度学习的恶意软件检测

恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…

【面试经典150 | 算术平方根】

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;数学表达式方法二&#xff1a;二分法 其他语言python3 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并…

【Flink 问题集】The generic type parameters of ‘Collector‘ are missing

错误展示&#xff1a; Exception in thread "main" org.apache.flink.api.common.functions.InvalidTypesException: The return type of function main(CollectionDemo.java:33) could not be determined automatically, due to type erasure. You can give type in…

Redux-状态管理组件

一、简介 react中的状态只属于某个组件。而Redux是一个全局管理js状态的架构&#xff0c;让组件通信更加容易。 之前是状态在所有组件间传递&#xff0c;而redux通过store来实现这个功能。 Redux特性&#xff1a; 1.Single source Of truth&#xff0c;通过store唯一维护状态…

基于单片机16路抢答器仿真系统

**单片机设计介绍&#xff0c; 基于单片机16路抢答器仿真系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的16路抢答器仿真系统是一种用于模拟和实现抢答竞赛的系统。该系统由硬件和软件两部分组成。 硬件方面&am…

Java21新增特性

版本介绍 Java 21是Java平台的一个新版本&#xff0c;于2023年9月19日由Oracle公司正式发布。这个版本包含了数千个性能、稳定性和安全性更新&#xff0c;以及几十个新功能和增强。其中&#xff0c;15个增强被赋予了自己的JDK增强提案&#xff08;JEP&#xff09;&#xff0c;…