Loading

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;
}
posted @ 2023-04-15 22:45  记录学习的Lyx  阅读(249)  评论(0编辑  收藏  举报