Nios II之PIO中断
PIO中断应用
Quartus软件中集成了Qsys工具,用于搭建SOPC系统,其前身是SOPC Builder。在Qsys中有一个PIO核的组件,PIO在SOPC系统中用的非常多,LCD、按键、LED、数据采集等等都可以使用PIO组件。PIO可以在Qsys中设置外部中断。如图所示,设置5位按键,勾选边缘捕获,边沿类型为下降沿,中断类型设置为边沿触发。
查官方手册,如下图所示。地址偏移量为0的是数据寄存器。
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x00); //写数据
//等同于IOWR(PIO_LED_BASE, 0, 0x00) IOWR(base, offset, data)
向边沿捕获寄存器中写1表示清空。地址偏移量为2的寄存器是中断寄存器,当其中某一位置为1时,表示相应的端口开启中断。
//等同于IOWR(base, 3, 0x1f)
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_KEY_BASE, 0x1f); //清零所有的捕获位
//等同于IOWR(base, 2, 0x1f)
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_KEY_BASE, 0x1f); //打开按键中断
按下按键led灯闪烁,按下另一个按键led熄灭。
main.c
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#include "unistd.h"
alt_u8 led_en;
//按键中断函数
alt_isr_func key_isr(void)
{
alt_u8 data;
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_KEY_BASE, 0x00); //关闭按键中断
data = IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_KEY_BASE); //捕获下降沿
if(data & 0x01) //key1
{
usleep(50000); //按键消除抖动
if(data & 0x01)
led_en = 1;
}
else if(data & 0x02) //key2
{
usleep(50000);
if(data & 0x02)
led_en = 0;
}
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_KEY_BASE, 0x1f); //清零所有的捕获位
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_KEY_BASE, 0x1f); //开按键中断
return 0;
}
int main(void)
{
alt_u8 led = 0;
alt_u32 i;
led_en = 0;
char *p;
//注册中断
alt_ic_isr_register(PIO_KEY_IRQ_INTERRUPT_CONTROLLER_ID,
PIO_KEY_IRQ,
key_isr,
p,
0);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_KEY_BASE, 0x1f); //清零所有的捕获位 0001 1111 1:清空
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_KEY_BASE, 0x1f); //打开按键中断
while(1)
{
if(led_en == 1) //led闪烁
{
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x00);//点亮8位LED灯
i = 0;
while(i<500000)
{
i++;
}
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0xff);//熄灭LED灯
i = 0;
while(i<500000)
{
i++;
}
}
}
return 0;
}