Nios II 外部中断 EP2C5V5
声明:本文为灵. yāo编写,版权所有,欢迎学习讨论,如需转载请标明出处http://www.cnblogs.com/China_memory
nios II 外部中断
贴出来和大家分享一下,文中借鉴来自互联网和书籍
硬件平台:康草EP2C5-V5
FPGA :EP2C5Q208C8N
SDRAM:K4S641632k
Flash:JS28F640
4位led,输入0时亮
1位按键,有上拉,平时为高电平状态
软件平台:Microsoft Windows xp Professional sp3(深度D版)
Quartus II 10.0 SP1 Build: 262
Nios II IDE 10.0 SP1 Build: 262
一、搭建硬件平台
按照Nios 流水灯实验,新建工程,新建sopc系统,在完成流水灯sopc系统的基础上增加一个PIO,用作外部中断输入按键,一个Nios 处理器可支持32个外部中断
1.添加外部中断PIO
将其Basic配置为输入(input only)
Next>
input 关闭Egde Capture Register,打开Interrupt Generate IRQ 设置为 Leve 高电平触发
Finish
然后按照Nios 流水灯 分配地址 ,分配中断号。
无错Generate成功后,在Quartus 新建的.bdf中添加 not非门 和 in_port_to_the_key引脚,其它全部都和上个Nios 流水灯工程一样。
然后分配引脚,也只需要加上关于外部中断按键的引脚。
#Setup.tcl
# Setup pin setting for EP2C5 main board
# nios External_interrupt key
set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED"
set_global_assignment -name ENABLE_INIT_DONE_OUTPUT OFF
#key
#key0 External_interrupt
set_location_assignment PIN_97 -to in_port_to_the_key
最后Start Compilation。
成功,下载到fpga实验板,硬件部分就完成了。
二、软件部分
先介绍一下有关Nios II外部中断的内容
使用Nios II 中断时和使用其它处理器一样,要先允许中断,就是要将PIO相应的Interruptmask 中断屏蔽寄存器置一。
Nios 还有个重要的就是要中断注册。
以下为引用http://www.61eda.com/Services/peixun/Altera/200802/609.html 作者:61EDA
与用户编程相关API函数有:
1、 alt_irq_register();
alt_irq_register()是向系统ISR注册用户ISR的API函数。其原形为:
int alt_irq_register( alt_u32 id,void *context,void (* isr)(void *, alt_u32))
id 代表被服务的中断向量号;
context 是运行参数指针,将来作为第一个参数传给用户ISR;
Isr 是一个函数指针,指向用户ISR入口;
如果注册成功,函数返回0,并允许全局中断及被服务中断;不成功返回非0值。
2、 alt_irq_disable();
Alt_irq_disable()用来禁止某个中断服务。原形为:
Int alt_irq_disable(alt_u32 id)
Id 为对应的中断号;
返回值为0;
3、 alt_irq_enble();
alt_irq_enable()与alt_irq_disable()对应,用来开启某个中断服务。原形为:
int alt_irq_enable(alt_u32 id)
4、 alt_irq_disable_all();
alt_irq_disable_all()用于关闭全局中断,原形为:
alt_irq_context alt_irq_disable_all(void)
返回值为中断控制寄存器的值。
5、 alt_irq_enable_all();
Alt_irq_enable_all()用于开启全局中断,原形为:
void alt_irq_enable_all( alt_irq_context context)
context 代表中断控制寄存器的值。
用户定义的用户ISR程序要符合统一的原形定义,即:
void isr(void * context, alt_u32 id)
函数名没特别的要求,与一般函数一样。入口参数与返回值要严格按标准形式定义,否则系统ISR将不能正确的对其调用。
我们只需用到alt_irq_register()。
新建一个模板工程,设置优化等等,然后Ctrl+B初次编译一下,产生system.h文件
良好的编程习惯,在根目录下新建inc文件夹,在其内新建sopc.h定义有关led和key PIOcore的寄存器。
#ifndef SOPC_H_
#define SOPC_H_
#include "system.h"
typedef struct
{
unsigned int DATA;
unsigned int DIRECTION;
unsigned int INTERRUPT_MASK;
unsigned int EDGE_CAPTURE;
}PIO_STR;
#define _LED
#ifdef _LED
#define LED ((PIO_STR *)LED_BASE)
#endif/*_LED*/
#define _KEY
#ifdef _KEY
#define KEY ((PIO_STR *)KEY_BASE)
#endif/*_KEY*/
#endif/*SOPC_H_*/
在根目录下新建main文件夹,新建一mian.c
#include "../inc/sopc.h"
#include "sys/alt_irq.h"//有关中断
#include <stdio.h>
char key_flag=0;
void ISR_key(void * context,unsigned long id)//中断服务函数
{
key_flag = ~key_flag;
}
int init_key(void)//中断注册函数
{
KEY->INTERRUPT_MASK = 1;//允许中断
return alt_irq_register(KEY_IRQ,NULL,ISR_key);//中断注册
}
int main()
{
char i,j;
j=3;
if(!init_key())
printf("Nios II外部中断注册成功!\n");
else
printf("Nios II外部中断注册失败!\n");
while(1)
{
if(key_flag)
{ LED->DATA = 15;
i=0;
}
else
{
LED->DATA = 0;
i=1;
}
if(i!=j)
{
if(!i)
printf("Nios II 的 led 灯全灭!\n");
else
printf("Nios II 的 led 灯全亮!\n");
}
j=i;
}
return 0;
}
保存
然后Build Project
run as Nios hardware
看到了Console栏内提示“Nios II 的 led 灯全亮!”,EP2C5上灯全亮。
按下中断按键后,EP2C5上灯全亮。Console栏内提示“Nios II 的 led 灯全灭!”
或者还可以试试Debug。
欢迎讨论。