NIOS II——PIO寄存器分析及使用

本文介绍了如何使用4位PIO控制4个LED灯和2个按键,利用边沿捕获功能实现LED根据按键操作闪烁与停止。通过设置PIO方向、中断配置和边沿捕捉寄存器,实现在按键0按下时LED闪烁,按键1按下时LED停止。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4个led对应一个PIO口的4bits位宽或者4个PIO口;Bidir为双向(对应于外部,接IO口),一根信号线即可输出入,而InOut则有两根信号线,接内部逻辑;初始化值1111十六进制为f

四个寄存器:data、IRQ Generation(中断)、direction、edgecapture(边沿捕获)

任务:2个按键,当按键0按下时,LED灯开始闪烁;当按键1按下时,LED灯停止闪烁。

要求:使用一个PIO,设置为6位(驱动4个LED灯和2个按键),能够捕获下降沿、产生中断(边沿)、使能单独位的设置和清零、使能边沿捕获寄存器的单独位清零

步骤:

1.Qsys的PIO核设置

2.硬件verilog

module nios_pio_led(
	clk,
	rst_n,
	key,
	key_gnd
	led
);                //端口定义
	input clk;
	input rst_n;
	output key_gnd;
	inout [1:0]key;
	inout [3:0]led;
	
	assign key_gnd = 0;

    mysystem u0 (
        .clk_clk        (clk),        //     clk.clk
        .reset_reset_n  (rst_n),  //   reset.reset_n
        .pio_led_export (key,led)  // pio_led.export
    );
	 
 
endmodule

3.软件代码

软件比较逻辑

#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include <alt_types.h>

int main()
{
	alt_u8_led = 0;
	alt_u32 i;
	alt_u8 data, data_pre;     //存储按键读到的值
	alt_u8 led_en;            //led使能信号
	data = 0x3;               //0x3是两个按键为11 每四个二进制代表一个十六进制,2^1+2^0=3
	led_en = 0;
	
	IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_LED_BASE, 0x0f);  //设置低四位为输出,高两位为输入 (1111)=f 
	IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0);         //不使用中断,因此要关闭所有bit的中断
	
	
	
	while(1)
	{
		    data_pre = data; 
			data = IORD_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE);
			data = data >> 4;     //右移4位,没有按下时为00110000移位后为00000011,移到低位好判断
			if(data != data_pre)
			{
				if(data == 0x2 )  //0x2=0010说明按键0被按下了
				{
					led_en = 1;
				}
			}
			if(led_en == 1)
			{
				led = 0;
				IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, led);  //点亮LED灯
				i = 0;
				while(i<500000)  //延时功能,非明确延时,数值太小将无法看到灯的闪烁效果
				{
					//判断按键1是否按下
					 data_pre = data; 
					 data = IORD_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE);
					 data = data >> 4;     //右移4位,没有按下时为00110000移位后为00000011,移到低位好判断
					 if(data != data_pre)
						{
							if(data == 0x1 )  //0x1=0001说明按键1被按下了
								{
									led_en = 0;
								}
						}	
					i++;
				}
				led = 0x0f;  //关闭led灯
				IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, led);  //熄灭LED灯
				i = 0;
				while(i<500000)  //延时功能,非明确延时,数值太小将无法看到灯的闪烁效果
				{
						i++;
				}
			}
		
	}
  return 0;
}

用边沿捕获——硬件逻辑

原理:边沿捕获寄存器捕获一个边沿时,该寄存器会设置为1。

         Enable bit-clearing for edge capture register该选项打开,则可以单独清零每一位,否则清零时是清零所有位。

#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include <alt_types.h>

int main()
{
	alt_u8_led = 0;
	alt_u32 i;
	alt_u8 data, data_pre;     //存储按键读到的值
	alt_u8 led_en;            //led使能信号
	data = 0x3;               //0x3是两个按键为11 每四个二进制代表一个十六进制,2^1+2^0=3
	led_en = 0;
	
	IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_LED_BASE, 0x0f);  //设置低四位为输出,高两位为输入 (1111)=f 
	IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0);         //不使用中断,因此要关闭所有bit的中断
	IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE, 0x30);             //清零所有捕获位
	
	
	while(1)
	{
			data = IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE)
			data = data >> 4;     //右移4位,没有按下时为00110000移位后为00000011,移到低位好判断
			if(data & 0x1)   //按位与
			{
					led_en = 1;
					IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE, 0x30);             //清零所有捕获位
			}
			if(led_en == 1)
			{
				led = 0;
				IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, led);  //点亮LED灯
				i = 0;
				while(i<500000)  //延时功能,非明确延时,数值太小将无法看到灯的闪烁效果
				{
					//判断按键1是否按下
					data = IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE)
					data = data >> 4;     //右移4位,没有按下时为00110000移位后为00000011,移到低位好判断
					if(data & 0x2)   //按位与
					{
						led_en = 0;
						IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE, 0x30);             //清零所有捕获位
					}
					i++;
				}
				led = 0x0f;  //关闭led灯
				IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, led);  //熄灭LED灯
				i = 0;
				while(i<500000)  //延时功能,非明确延时,数值太小将无法看到灯的闪烁效果
				{
						i++;
				}
			}
		
	}
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值