在NIOS II 2的博客中工程基础上更改。上次已经注明了关于Qsys中中断怎么设置,此次只是记录eclipse中如何修改程序。
1、quartus工程,PIO高四位是按键
2、Qsys中配置
3、eclipse中修改
#include "alt_irq.h" 程序加入这个中断头文件
首先打开中断,我们的KEY是高四位,所以下面语句
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE,0xf0); //0:关闭中断,1打开中断。打开所有四个KEY中断
打开alt_irq.h文件,在右侧边栏我们能看到这个文件里边所有函数,其中alt_ic_isr_register为一个内部中断注册函数
ic_id的值在如下位置,为PIO_LED_IRQ_INTERRUPT_CONTROLLER_ID。当然直接写0也是可以的
irq是中断号,看上图中断号是PIO_LED_IRQ,当然也可以直接写0.为什么是0,因为我们在Qsys中给的中断号是0
4、定义中断服务函数,看到中断服务函数如下这样定义
alt_isr_func key_isr(void)
{
}
5、程序如下。不按下按键四个灯一起闪烁,按下按键,一个灯亮,其余灭
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
alt_u8 led_en1;
alt_isr_func key_isr(void)
{
alt_u8 data;
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE,0x00); //关闭所有中断,保护现场
data=IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE); //读边沿捕获寄存器
if(data&0x10) //捕获到KEY1有上升沿
{
led_en1=0x00;
}
else if(data&0x20) //捕获到KEY2有上升沿
{
led_en1=0x01;
}
else if(data&0x40) //捕获到KEY3有上升沿
{
led_en1=0x02;
}
else if(data&0x80) //捕获到KEY4有上升沿
{
led_en1=0x03;
}
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE,0xf0); //清零边沿捕获寄存器捕获位
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE,0xf0); //打开中断
return 0;
}
int main(void) {
alt_u32 i;
alt_u8 data;
data=0; //上电默认是0,根据自己电路图实际写入这个值
char *p;
alt_ic_isr_register (PIO_LED_IRQ_INTERRUPT_CONTROLLER_ID, //ID
PIO_LED_IRQ, //中断号
key_isr, //中断服务函数
p, //传参
0); //输出
IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_LED_BASE,0x0f); //高四位输入,低四位输出
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE,0xf0); //0:关闭中断,1打开中断。打开所有四个KEY中断
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE,0xf0); //上电清零边沿捕获寄存器捕获位
led_en1=0x55;
while(1)
{
if(led_en1==0x00)
{
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x07); //熄灭LED灯
i=0;
while(i<500000)
{i++;}
}
else if(led_en1==0x01)
{
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x0b); //熄灭LED灯
i=0;
while(i<500000)
{i++;}
}
else if(led_en1==0x02)
{
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x0d); //熄灭LED灯
i=0;
while(i<500000)
{i++;}
}
else if(led_en1==0x03)
{
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x0e); //熄灭LED灯
i=0;
while(i<500000)
{i++;}
}
else
{
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x0f); //熄灭LED灯
i=0;
while(i<500000)
{i++;}
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x00); //熄灭LED灯
i=0;
while(i<500000)
{i++;}
}
}
return 0;
}
注意:主循环里边每个延时给的时间都不能太短了,否则按键中断有问题