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

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;
}

1. PIO Core可配置的四种I/O端口模式: PIO Core可配置为输入、输出、双向和无的四种I/O端口模式。其中,输入模式表示该端口只能接收输入信号;输出模式表示该端口只能输出信号;双向模式表示该端口既可以输入也可以输出信号;无模式表示该端口不进行输入输出操作。 2. PIO Core中方向寄存器、中断屏蔽寄存器和沿捕获寄存器的作用: 方向寄存器用于控制PIO Core的I/O端口模式;中断屏蔽寄存器用于屏蔽或允许中断信号;沿捕获寄存器用于检测输入信号的电平变化,以触发中断信号。 3. 简述PIO的中断操作: PIO Core在检测到输入信号的电平变化时,会触发中断信号,并将中断请求信号发送给处理器。处理器响应中断请求后,会执行中断服务程序进行处理。 4. 若用PIO扫描控制4*8矩阵键盘,应如何配置PIO,给出键盘扫描程序的流程图: 首先,将PIO Core配置为输出模式,控制键盘的行信号输出;然后,将PIO Core配置为输入模式,检测键盘的列信号输入。具体流程如下所示: ![PIO扫描控制4*8矩阵键盘流程图](https://i.imgur.com/4bzuhwV.png) 5. 简述Uart Core的发送逻辑和接受逻辑的功能: Uart Core的发送逻辑通过将发送数据存储在发送数据寄存器中,然后将发送数据序列化后发送出去。接收逻辑通过检测接收数据寄存器中的接收数据,将其反序列化后存储在接收数据缓冲区中。 6. Uart Core状态寄存器中TRDY和RRDY位的作用: TRDY位表示发送缓冲区是否为空,可以开始发送新的数据;RRDY位表示接收缓冲区是否有新的数据,可以读取接收到的数据。 7. 举例说明Uart Core控制寄存器的作用: Uart Core控制寄存器可以设置串口的波特率、数据位数、停止位数、校验位和流控制等参数,并控制发送和接收操作的启停。 8. 简述Uart Core除数寄存器的作用: Uart Core除数寄存器用于设置串口的波特率。它将输入时钟频率和波特率作为参数,计算出用于串口通信的时钟周期数,并控制串口发送和接收时钟的频率。 9. 简述基于Uart Core的查询发送和查询接收流程: 查询发送流程:先检查TRDY位是否为1,如果为1则将需要发送的数据写入发送数据寄存器中,等待发送完成后再进行下一次查询操作;如果为0,则继续等待TRDY位为1。 查询接收流程:先检查RRDY位是否为1,如果为1则读取接收数据寄存器中的数据,并将其存储到接收数据缓冲区中;如果为0,则继续等待RRDY位为1。 10. 简述Timer Core的功能与特点: Timer Core主要用于定时器和计数器的应用。它具有可编程的时钟频率、可配置的计数模式和比较模式,可以实现定时、计数和触发等功能。其特点是具有较高的精度和稳定性,并且可以通过编程灵活地控制定时器和计数器的工作模式。 11. Timer Core状态寄存器的作用: Timer Core状态寄存器用于表示定时器和计数器的当前状态,包括计数值、比较值、溢出标志等。 12. Timer Core控制寄存器的作用: Timer Core控制寄存器用于控制定时器和计数器的工作模式,包括时钟频率、计数模式、比较模式、中断使能等。 13. 简述如何利用Timer Core实现“看门狗”功能: 利用Timer Core实现“看门狗”功能的方法是,将Timer Core配置为定时器模式,并设置一个比较值。然后在程序中定期清空Timer Core的计数值,如果计数值未能在规定时间内被清空,则Timer Core会触发中断并执行“看门狗”处理程序,例如重新启动系统或进行紧急处理等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值