这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 上一修订版 两侧同时换到之后的修订记录 | ||
gpio输入实验_识别按键输入 [2019/12/21 11:22] zhangzheng |
gpio输入实验_识别按键输入 [2020/07/02 11:41] zgf [二、 实验设备及平台] |
||
---|---|---|---|
行 1: | 行 1: | ||
- | [[http://www.cnblogs.com/xiaomagee/p/7283131.html]] | + | |
+ | | **银杏科技有限公司旗下技术文档发布平台** |||| | ||
+ | |技术支持电话|**0379-69926675-801**||| | ||
+ | |技术支持邮件|Gingko@vip.163.com||| | ||
+ | |技术论坛|http://www.eeschool.org||| | ||
+ | ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | ||
+ | | V1.0 | 2020-07-01 | gingko | 初次建立 | | ||
+ | |||
+ | |||
+ | ===== 实验二:GPIO输入实验——识别按键输入 ===== | ||
+ | ==== 一、 实验目的与意义 ==== | ||
+ | |||
+ | - 了解按键的特征和应用。 | ||
+ | - 掌握FPGA引脚的配置方法。 | ||
+ | - 掌握QuartusII集成开发环境的使用。 | ||
+ | - 掌握Verilog语言模块化的编程方式。 | ||
+ | ==== 二、 实验设备及平台 ==== | ||
+ | |||
+ | - iCore4 双核心板[[https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22598974120.15.5923532fsFrHiE&id=551864196684|点击购买]]。 | ||
+ | - Blaster(或相同功能)仿真器[[https://item.taobao.com/item.htm?id=554869837940|点击购买]]。 | ||
+ | - Micro USB线缆。 | ||
+ | - QuartusII开发平台。 | ||
+ | - 装有WIN XP(及更高版本)系统的计算机。 | ||
+ | ==== 三、 实验原理 ==== | ||
+ | * FPGA的所有I/O控制块允许每个I/O引脚单独配置为输入口,不过这种配置是系统自动完成的。当I/O口被设置为输入口使用时,该I/O将直接使三态缓冲区的控制端接地,使得该I/O对外呈高阻态,这样该I/O引脚即可作为输入引脚使用。正确分配并锁定引脚后,一旦按键有变化,即可在检测到按键输入的情况下切换LED的状态。驱动示意图如下: | ||
+ | {{ :icore4:icore4_fpga_2_1.png?direct |图2-1}} | ||
+ | ==== 四、 代码讲解 ==== | ||
+ | |||
+ | * 本实验例程分为三个模块,分别是顶层模块、复位模块和按键控制模块。 | ||
+ | - 顶层模块:主要实现各子模块之间的信息交互及与外部信息交互。 | ||
+ | - 复位模块:产生全局复位信号。 | ||
+ | - 按键控制模块:实现按键切换led的功能。 | ||
+ | * 如图2-2所示为本例程三个模块在QuartusII界面中所处的位置。双击即可打开对应的模块。 | ||
+ | {{ :icore4:icore4_fpga_2_2.png?direct |图2-2}} | ||
+ | 1、顶层模块代码讲解: | ||
+ | <code verilog> | ||
+ | //--------顶层模块主要实现各子模块之间的信息交互及与外部信息交互----// | ||
+ | module key( | ||
+ | input clk_25m, | ||
+ | input key, | ||
+ | output fpga_ledr, | ||
+ | output fpga_ledg, | ||
+ | output fpga_ledb | ||
+ | ); | ||
+ | //--------wire型变量定义,实现模块与模块之间的信号连线------------// | ||
+ | wire rst_n; | ||
+ | |||
+ | //---------例化复位模块产生全局复位信号,其中u1为例化名-----------// | ||
+ | rst_n u1( | ||
+ | .clk_25m(clk_25m), | ||
+ | .rst_n(rst_n) | ||
+ | ); | ||
+ | //------------例化按键控制信号,实现按键切换led的功能------------// | ||
+ | key_ctrl u2( | ||
+ | .clk_25m(clk_25m), | ||
+ | .rst_n(rst_n), | ||
+ | .key(key), | ||
+ | .fpga_ledr(fpga_ledr), | ||
+ | .fpga_ledg(fpga_ledg), | ||
+ | .fpga_ledb(fpga_ledb) | ||
+ | ); | ||
+ | |||
+ | endmodule | ||
+ | </code> | ||
+ | |||
+ | 2、复位模块讲解: | ||
+ | <code Verilog> | ||
+ | module rst_n( | ||
+ | input clk_25m, | ||
+ | output rst_n | ||
+ | ); | ||
+ | |||
+ | //--------------生成复位信号的计数器,采用时序逻辑语言描述----------// | ||
+ | reg [3:0]cnt_rst; | ||
+ | reg rst_r; | ||
+ | |||
+ | always@(posedge clk_25m) | ||
+ | if(cnt_rst == 4'd15) | ||
+ | begin | ||
+ | cnt_rst <= 4'd15; | ||
+ | rst_r <= 1'd1; | ||
+ | end | ||
+ | else cnt_rst <= cnt_rst + 1'd1; | ||
+ | |||
+ | assign rst_n = rst_r; | ||
+ | endmodule | ||
+ | </code> | ||
+ | |||
+ | 3、按键控制模块讲解(篇幅原因,不再贴出全部代码讲解,完整代码见例程): | ||
+ | <code verilog> | ||
+ | //--------------按键消抖动,提取按键状态----------// | ||
+ | always @(posedge clk_25m or negedge rst_n) | ||
+ | if (!rst_n) | ||
+ | begin | ||
+ | key_r <= 1'd0; | ||
+ | low_cnt <= 18'd0; | ||
+ | hig_cnt <= 18'd0; | ||
+ | end | ||
+ | //----------检测按键状态为高时,延时10ms,把按键状态提取出来 ------// | ||
+ | else if(key) | ||
+ | begin | ||
+ | low_cnt <= 18'd0; | ||
+ | if (hig_cnt == ms_10) | ||
+ | begin | ||
+ | key_r <= key; | ||
+ | hig_cnt <= hig_cnt; | ||
+ | end | ||
+ | else hig_cnt <= hig_cnt + 1'd1; | ||
+ | end | ||
+ | |||
+ | reg [1:0]led_cnt; //led_cnt为led状态标志,不同值表示不同led状态 | ||
+ | reg ledr,ledg,ledb; | ||
+ | //----------------按键下降沿控制led状态切换--------------------// | ||
+ | always@(negedge key_state or negedge rst_n) | ||
+ | if (!rst_n) | ||
+ | begin | ||
+ | led_cnt <= 2'd0; | ||
+ | end | ||
+ | else if (led_cnt == 2'd2) | ||
+ | begin | ||
+ | led_cnt <= 2'd0; | ||
+ | end | ||
+ | else led_cnt <= led_cnt + 1'd1; | ||
+ | //------------------led状态切换的状态机-----------------------// | ||
+ | always@(posedge clk_25m or negedge rst_n) | ||
+ | |||
+ | //----- led_cnt=0,红灯亮,led_cnt=1,绿灯亮led_cnt=2,蓝灯亮----// | ||
+ | else case(led_cnt) | ||
+ | 2'd0: | ||
+ | begin | ||
+ | ledr <= 1'd0; | ||
+ | ledg <= 1'd1; | ||
+ | ledb <= 1'd1; | ||
+ | end | ||
+ | 2'd1: | ||
+ | begin | ||
+ | ledr <= 1'd1; | ||
+ | ledg <= 1'd0; | ||
+ | ledb <= 1'd1; | ||
+ | end | ||
+ | 2'd2: | ||
+ | begin | ||
+ | ledr <= 1'd1; | ||
+ | ledg <= 1'd1; | ||
+ | ledb <= 1'd0; | ||
+ | end | ||
+ | </code> | ||
+ | ==== 五、 实验验证 ==== | ||
+ | {{ :icore4:icore4_fpga_2_3.png?direct |图2-3}} | ||
+ | - 双击打开例程里的QuartusII工程文件,如图2-3所示。 | ||
+ | - 按照前面实验指导书所讲,对该工程文件进行相关配置,编译及引脚锁定后(例程里已经配置好),将配置文件下载至icore4双核心工控板观察实验现象。 | ||
+ | - 实验现象为:与FPGA芯片相连的红、绿、蓝三个led灯,先是短暂的全灭,随后红灯亮起,而后依次按下icore4双核心工控板上的FPGA按键,可以观察到红、绿、蓝三个led灯依次亮灭,即实现了按键切换led灯的功能。 | ||
+ |