正点原子开拓者 Nios II资料连载第四章PIO中断
liebian365 2024-10-27 13:21 26 浏览 0 评论
1)实验平台:正点原子开拓者FPGA 开发板
2)摘自《开拓者 Nios II开发指南》关注官方微信号公众号,获取更多资料:正点原子
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/index.html
第四章PIO中断
在前面的章节里,我们把PIO IP核的寄存器相关内容进行了详细的讲解,并以按键控制
LED灯为例,提到了PIO IP核的一个比较简单的应用。在这一章中,我们将对该IP核的一个十
分重要的功能——中断,进行详细地说明。由于这个功能的应用比较广泛,希望大家能够熟
练掌握相关的内容。
本章包括以下几个部分:
4.1 简介
4.2 实验任务
4.3 硬件设计
4.4 软件设计
4.5 下载验证
简介
在上一章我们给大家介绍了如何使用PIO IP核与外设通信,在这里我们将通过PIO IP核
的中断功能来讲解如何在Nios II开发过程中使用中断。
中断与 IRQ
PIO IP核有一个与中断相关的功能——IRQ,它的全称是interrupt request。单从英文
名来看,能够得知它是中断请求。那么什么是中断呢?在计算机相关方面,中断是指:在计
算机的运行过程中,由于系统内部或外部或现行程序本身出现紧急事件,计算机立即自动停
止正在运行的程序,并开始处理新的程序(中断程序),在处理完中断程序后返回原来的程
序接着运行,这一完整的过程。
PIO IP 核产生 IRQ 的宏观条件
在PIO IP核的输入端口,发生了硬件预先设置的中断触发事件,PIO IP核就会输出IRQ。
PIO IP 核产生 IRQ 的实际条件
触发IRQ的方式有两种:一种是电平触发(Level),当输入端口为高电平时触发;另一
种是边沿触发(Edge),当输入端口出现了上升沿或下降沿或者双沿中的一种(取决于硬件
的配置)。接下来讲解产生IRQ需要的具体条件。
1.产生电平触发 IRQ 需要的条件
(1)首先 PIO 核的端口需要是输入型的端口,也就是需要在配置界面的 Direction 一项中
选择 Input 选项;
(2)在 PIO IP 核中加入 IRQ 这个功能,也就是在 Interrupt 项中,选中 Generate IRQ 这一
选项;
(3)选中电平触发选项,即在 IRQ type(IRQ 类型)中选中 Level。
(4)使能中断。在硬件设置完成后,需要在软件中给中断屏蔽寄存器(interruptmask
Register)写 1。
图 4.1.1 电平触发IRQ的配置界面
配置完成后如图 4.1.1 所示,输入端口的位数根据大家的需求而定,图中的设置只是作
为一个例子。这里补充说明一下电平触发的 IRQ 工作的方式:
(1)当硬件设置成电平触发模式时,PIO IP 核的输入端口出现高电平,就能触发 IRQ;若
想要低电平触发 IRQ,需要在 Quartus II 工程的顶层,在输入端口前面加一个非门。本章的实
验里也用到了这种操作,我们会在后面 4.3 小节硬件设计部分提到这个应用。
(2)当 PIO IP 核某一个输入端口满足 IRQ 触发条件,PIO IP 核发出 IRQ 后,程序开始处理
中断函数。假如此时输入端口一直满足 IRQ 触发条件,那么程序在处理完中断函数后会再次进
入中断函数接着运行。直到触发条件不存在了,程序才能在处理完中断函数后回到主函数。
(3)若程序中有复数个中断函数,且中断函数之间还有优先级的区别,就可能发生这样
的情况:主程序正在处理某一个中断函数,这时突然触发一个优先级更高的 IRQ,那么主程序
会从当前处理的中断函数跳到优先级更高的中断函数。本章用不到复数的中断函数,所以这里
不做详细的讲解。
2.产生边沿触发 IRQ 需要的条件
(1)首先 PIO 核的端口需要是输入型的端口,也就是需要在配置界面的 Direction 一项中
选择 Input 选项;
(2)在 Edge capure register(边沿捕获寄存器)栏选中 Synchronously capture 选项。此时
可以在 Edge type 一栏选择触发电平,里面的选项有 RISING(上升沿)、FALLING(下降沿)、
ANY(任意边沿)。在 Edge capure register 栏还有 enable bit-clearing for edge capture register 选
项。选择了 enable bit-clearing for edge capture register 选项后,给 edge capture 寄存器单独的
位写 1 清中断;若是没有选择 enable bit-clearing for edge capture register 选项,则是写任意数
清中断。每触发一次边沿类型的 IRQ 后,需要给 edge capture 寄存器写 1 清一次中断,否则
PIO IP 核会一直输出 IRQ。
(3)在 PIO IP 核中加入 IRQ 这个功能,也就是在 Interrupt 项中,选中 Generate IRQ 这一
选项;
(4)选中边沿触发选项,即在 IRQ type(IRQ 类型)中选中 EDGE。
(5)使能中断。在硬件设置完成后,需要在软件中给中断屏蔽寄存器(interruptmask
Register)写 1。
图 4.1.2 边沿触发IRQ的配置界面
上升沿的触发模式配置完成后如图 4.1.2 所示,图中配置只是作为一个例子,实际配置
根据大家的需求来定。这里补充说明一下边沿触发的 IRQ 工作的方式:
(1)当硬件设置成边沿触发模式时,PIO IP 核的输入端口出现相应的边沿,就能触发 IRQ;
(2)当 PIO IP 核某一个输入端口满足 IRQ 触发条件,PIO IP 核发出 IRQ 后,程序开始处理
中断函数。在中断函数中一般包含给 edge capture 寄存器写 1 清中断的操作。假如此时输入端
口一直满足 IRQ 触发条件,那么程序在处理完中断函数后会再次进入中断函数接着运行。直到
触发条件不存在了,程序才能在处理完中断函数后回到主函数。
(3)若程序中有多个中断函数,且中断函数之间还有优先级的区别,就可能发生这样的
情况:主程序正在处理某一个中断函数,这时突然触发一个优先级更高的 IRQ,那么主程序会
从当前处理的中断函数跳到优先级更高的中断函数。
实验任务
本节实验任务是:在Qsys系统中加入PIO IP核,并通过按键中断控制流水灯的运行状态。没有按按键时,流水灯正常运行;当按键按下时,4个LED灯全部点亮。
硬件设计
创建 Quartus II 工程
首先要创建Quartus II工程,工程名为“pio_irq”。
创建 Qsys 系统
实验中要用到的IP 核有:clk(时钟)、nios II(处理器)、onchip_ram(片内存
储)、两个PIO、jtag_uart、sysid_qsys。其中只有PIO IP核和nios II IP核需要稍微讲解
一下,其他的IP核都是按照以前的配置方法进行设置,本节就主要讲如何配置PIO IP核和
nios II IP核。
在Qsys系统的Library中搜索PIO IP核,双击打开后可以看到如图 4.3.1所示的配置界
面。
图 4.3.1 PIO IP核配置界面
我们先设置与 LED 灯相关的 PIO。由于开发板上给用户用的 LED 灯共有 4 个,所以在 Basic
Settings 里,我们将 PIO 位宽设为 4,方向设为输出(Output)即可。其它设置如 Output Registere、
Edge capture register 等配置为默认设置,无需更改,点击 Finish 完成。修改完的 PIO IP 核界面
如图 4.3.2 所示。
图 4.3.2 与LED灯相关的PIO IP核设置界面
由于我们的实验任务是使用按键中断控制流水灯的运行状况,所以还要添加一个与按键相
关的 PIO IP 核。由于实验任务要求按键中断时,LED 灯全亮,其他情况下 LED 灯处于流水灯的
运行状态。所以,根据任务要求以及简介中提到的两种触发 IRQ 的方式,我们可以猜想:按键
按下时,程序一直在处理中断函数(让 LED 灯全亮),没有按下按键时,程序在处理主函数(运
行流水灯函数)。那么要用到的 IRQ 触发模式是电平类型的,并且这里只需要一个按键就能满
足实验要求。因此我们在 Basic Settings 里,将 PIO 位宽设为 1,方向设为输入(Input),将
Interrupt 一栏中的 Generate IRQ 选项选中,此时 IRQ type 自动选择为 LEVEL(电平)触发模式。
修改完的 PIO IP 核界面如图 4.3.3 所示。
图 4.3.3 与按键相关的PIO IP核设置界面
我们打开nios II IP核配置界面,因为这里只用了onchip_ram IP核存储代码和指令,所
以需要对相关的设置进行修改。如图 4.3.4所示,在Reset Vector处将Reset vector memory
处的选项选为onchip_ram,同时在Exception Vector处也将Exception vector memory处的选
项选为onchip_ram。需要注意的是, onchip_ram IP核之后,nios II IP核的Reset Vector
和Exception Vector选项中才会出现onchip_ram选项。
图 4.3.4 nios II IP核设置界面
添加完 IP 核后就可以开始连线,大家若是不熟悉怎么连线,可以照着下面完成的 Qsys 系
统界面图连。需要注意的是,要将 PIO IP 核的端口引出来,如图 4.3.5 所示。引出端口的方法
是双击图 4.3.5 中 IP 核的 Export 一栏的红框位置,然后修改名称,按下 Enter 键即可。
然后,点击 System→Assign Base Addresses 让系统自动分配地址,这里最好把 onchip_ram
的地址锁住,这是因为这个 IP 核里存储着指令,最好不要让其地址发生变动。锁住地址的方
法是先点击 IP 核,然后点击右键→Lock Base Address。我们还可以将各个 IP 核的名称修改
一下。最后就是生成系统了,操作可以按照“Hello,World”文档里的进行。
图 4.3.5 nios II IP核设置界面
集成 Qsys 系统
这一步依然可以按照“Hello,World”文档里的操作进行。
下面将Quartus II 工程中的顶层代码贴出来。
1 module Pio_irq(
2 input sys_clk ,
3 input sys_rst_n ,
4
5 input key ,
6 output [3:0] led
7 );
8
9 //wire define
10 wire clk_100M;
11
12 //锁相环
13 pll pll_inst (
14 .inclk0 (sys_clk),
15 .c0 (clk_100M)
16 );
17
18 //例化 Qsys 系统
19 irq u0 (
20 .clk_clk (clk_100M), // clk.clk
21 .reset_reset_n (sys_rst_n), // reset.reset_n
22 .pio_led_export (led), // pio_led.export
23 .pio_key_export (~key) // pio_key.export
24 );
25
26 endmodule
在代码的第23行,我们将key信号的值取反后,再送给跟key相关的PIO IP核。简介中曾
提到过这个问题:开发板上的按键按下时,输出低电平。而PIO IP核配置成电平触发IRQ模式
时,触发条件是高电平。所以才有了代码第23行的取反操作,这个取反操作实际上相当于在
PIO IP核前加了一个反相器。
编译和下载
这时,我们便能够进行编译查错了,我们可以通过Quartus II 软件菜单栏中的
【Processing】→【Start Compilation】来进行编译,也可以通过快捷栏中的快捷键进行编
译。
接下来我们就需要进行配置IO,分配管脚。首先,点击Quartus II 软件菜单栏中的
【Assignment】→【Device】,然后我们在Device 界面中找到【Device and Pin
Options…】进入图 4.3.6所示页面配置IO。将未使用引脚设置为高阻输入(As input tri
state),这样上电后FPGA 的所有不使用引脚都将进入高阻抗状态。
图 4.3.6 未使用引脚设置界面
接下来,将一些 IO 设置成普通 IO,通过双击红框位置,将一个个 Value 的值修改过来。
如图 4.3.7 所示。
图 4.3.7 IO设置界面
我们通过 Quartus II 软件菜单栏中的【Assignments】→【Pin Planner】选项分配引脚,如
图 4.3.8 所示。
图 4.3.8 引脚分配界面
最后我们再进行一次全编译,成功编译硬件系统后,将产生用于配置 FPGA 的 Pio_irq.sof
文件。下面我们就来说明一下将.sof 文件下载到 FPGA 目标器件的步骤。
(1)将下载器一端连接电脑,另一端与开发板上对应端口连接,最后连接电源线并打开
电源开关。
接下来我们下载程序。工程打开后通过点击工具栏中的“Programmer”图标打开下载界面,
通过“Add File”按钮选择 pio_irq\par\output_files 目录下的“pio_irq.sof”文件。开
发板电源打开后, 在程序下载界面点击“Hardware Setup”,在弹出的对话框中选择当前的
硬件连接为“USB-Blaster[USB-0]”。然后点击“Start”将工程编译完成后得到的 sof 文件
下载到开发板中。
至此,硬件部分设计完成,下面开始基于 Nios II SBT for Eclipse 的软件部分的设计。
软件设计
我们通过 Quartus II 软件菜单栏中的【Toos】→【Nios II SBT for Eclipse】,来启动 NiosII SBT
for Eclipse 软件。打开 Nios II SBT for Eclipse 软件后,会弹出 Workspace Launcher 页面。我们这
里将工作空间设置为 Pio_irq\qsys 路径下的 software 文件夹,如图 4.4.1 所示。
图 4.4.1 设置工作空间
设置好工作空间后,我们点击【OK】进入 Nios II SBT for Eclipse 软件主界面中,在该页面
我们通过单击菜单栏中的【File】→【New】→【Nios II Application and BSP from Template】,来
新建工程,如图 4.4.2 所示。
图 4.4.2 新建Nios II SBT for Eclipse 工程
单击【…】按钮来选择 Pio_irq\qsys\hardware 下的 Pio_irq.sopcinfo 文件,即指向当前硬
件设计系统。Nios II SBT for Eclipse 软件会自动识别 Qsys 系统中 CPU 的名称,所以 CPU name
一项会自动生成。接下来,要给 Nios II SBT for Eclipse 软件中的工程命名,这里的名称没有特
殊要求,我们这里名为 irq。然后将工程存放的位置修改为 Pio_irq\qsys\software\irq。注意
不要漏掉了“\irq”,不然生成系统的时候会报错。最后我们来看下 Project template 窗口,该
窗口中陈列的都是已经设计好的软件工程。我们可以从中选择一个,作为自己的工程的模板来
使用。当然也可以选择 Bland Project(空白工程),就需要自己写所有的代码。这里我们选择
的是 Hello World 模板工程,然后我们在它的基础上进行修改,这样比空白工程更加方便。
设置完工程后,直接点击【Finish】完成工程创建。然后,在 Nios II SBT for Eclipse 软件的左侧 Project Explorer 窗口中有两个工程:irq 和 irq _bsp。其中 irq 是 C/C++应用工程,而
irq_bsp 是描述 Qsys 系统硬件细节的系统库。打开 irq 工程里的 hello_world.c 文件,出现如
图 4.4.3 所示的图。
图 4.4.3 hello_world工程代码图
由代码可知,下载程序到开发板后会在窗口上输出 “Hello from Nios II!”。我们在这里要
先验证之前创建的 Qsys 系统是否能正常工作。验证方法是先编译 irq 工程,然后将工程模板程
序下载到开发板上,看是否能正常运行。方法是右键 irq 工程,点击 build project。Console 窗
口会报出下图这样的错误。
图 4.4.4 编译工程后的console窗口
在“Hello,World”实验中也出现了类似的错误,其原因是存储空间不够。所以这里也要像
“Hello,World”实验里一样,优化一下代码。方法是一样的,大家可以照着操作,这里就不再
赘述了。
优化完代码之后,再编译一次 led 工程,会出现以下的界面。这表示编译通过,可以将程
序下载到开发板上了。
图 4.4.5 编译通过后的console窗口
这时大家点击【Run As】→【Nios II Hardware】,然后点击【Target Connection】标签,然
后在 Target Connection 窗口中点击【Refresh Connections】按钮后。这时软件便会自动识别我
们开发板上的 Qsys 系统,并显示 Qsys 系统的相关信息。我们接着点击【Run】,软件会把 irq.elf
文件下载至开发板中运行起来。更加详细的图和文字描述,可以在“Hello,World”实验的下载
验证部分查看。
这时,若之前创建的 Qsys 系统无误,代码下载完成后在 Nios II console 窗口会显示“Hellofrom Nios II!”字符,如下图所示。
图 4.4.6 下载代码后的console窗口
验证完 Qsys 系统是否能正常运行之后,我们就可以开始软件部分的设计了。这时只需要
在当前的代码窗口修改代码就可以了。代码如下所示。
1 #include <stdio.h>
2 #include "system.h" //系统头文件
3 #include "altera_avalon_pio_regs.h" //pio 寄存器头文件
4 #include "sys/alt_irq.h" //中断头文件
5 #include "unistd.h" //延迟头文件
6
7 void IRQ_Init(); //中断初始化函数
8 void IRQ_Key_Interrupts(); //中断服务子程序
9
10 int main(void)
11 {
12 alt_u8 led,i; //有符号 8 位整数
13 IRQ_Init(); //初始化 PIO 中断
14 IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x0F); //初始化 LED 全亮
15 //流水灯
16 while(1)
17 {
18 for(i=0;i<4;i++)
19 {
20 led = 1 << i; //从低位到高位移位
21 IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, led);
22 usleep(100000); //延迟一段时间
23 }
24 }
25 }
26
27
28 void IRQ_Init()
29 {
30 IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_KEY_BASE, 0x01); // 使能中断
31 // 注册 ISR
32 alt_ic_isr_register(
33 PIO_KEY_IRQ_INTERRUPT_CONTROLLER_ID, // 中断控制器标号,从 system.h 复制
34 PIO_KEY_IRQ, // 硬件中断号,从 system.h 复制
35 IRQ_Key_Interrupts, // 中断服务子函数
36 0x0, // 指向与设备驱动实例相关的数据结构体
37 0x0); // flags,保留未用
38 }
39
40 void IRQ_Key_Interrupts()
41 {
42 IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x0f);//中断函数,让 LED 全亮
43 }
代码的第 10 行至第 25 行是主函数。主函数中第 13 行代码完成了初始化中断的功能,完
整的初始化中断函数在代码的第 28 行到第 38 行。在初始化中断的时候,需要使能中断,也就
是给中断屏蔽寄存器写 1,这个操作在代码的第 30 行完成。在代码的第 16 行至第 25 行,在
主函数中完成了流水灯的功能。也就是每间隔一段时间,给 PIO IP 核的输出端口,按照一定的
规律进行赋值。而这个 PIO IP 核是用来驱动 LED 灯发光的。代码的第 40 行至第 43 行是一个中
断函数,它实现的功能是让 4 个 LED 灯一起发光。
联系整个工程,我们可以得出:在一般情况下,程序一直在运行流水灯程序。当我们按下
按键且不松开时会一直触发 IRQ,程序因此会一直运行中断函数,让 4 个 LED 灯一起发光。当
我们松开按键后,程序则会回到主函数,接着运行流水灯程序。
修改完代码的窗口如下所示:
图 4.4.7 修改后的工程代码图
代码修改完成后,大家记得要点一下快捷菜单中的【Save】,或者菜单栏中的【File】→
【Save】,来保存修改后的程序。
下载验证
现在可以编译 irq 工程了。右键 irq 工程,点击 build project。稍等片刻,Console 窗口显示
的内容如下图所示,这表示工程编译成功。
图 4.5.1 编译工程后的console窗口图
这时大家右键 irq 工程,点击【Run As】→【Nios II Hardware】,代码就被下载到开发板上
了,此时开发板上的 4 个 LED 以流水灯的方式依次点亮,循环往复。然后按下 key1,流水灯停
止运行,4 个 LED 灯保持常亮;松开按键后,4 个 LED 继续以流水灯的方式运行。到这里,我
们本次利用 PIO 中断来控制 LED 灯运行状态的实验就结束了。
相关推荐
- 4万多吨豪华游轮遇险 竟是因为这个原因……
-
(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...
- “菜鸟黑客”必用兵器之“渗透测试篇二”
-
"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...
- 科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白
-
作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...
- 麦子陪你做作业(二):KEGG通路数据库的正确打开姿势
-
作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...
- 知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势
-
智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...
- 每日新闻播报(September 14)_每日新闻播报英文
-
AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...
- 香港新巴城巴开放实时到站数据 供科技界研发使用
-
中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...
- 5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper
-
本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...
- Qt动画效果展示_qt显示图片
-
今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...
- 如何从0到1设计实现一门自己的脚本语言
-
作者:dong...
- 三年级语文上册 仿写句子 需要的直接下载打印吧
-
描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...
- C++|那些一看就很简洁、优雅、经典的小代码段
-
目录0等概率随机洗牌:1大小写转换2字符串复制...
- 二年级上册语文必考句子仿写,家长打印,孩子照着练
-
二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)