并行IO接口设计(计算机组成原理与接口技术实验)

实验任务

嵌入式计算机系统将独立按键以及独立开关作为输入设备,七段数码管作为输出设备。实现以下功能:

1) 点击BTNC 按键时,计算机读入一组16 位独立开关状态作为一个二进制数据,并将该二进制数的低8 位对应的二进制数值0 或1 显示到8 个七段数码管上。

2) 点击BTNU 按键时,计算机读入一组16 位独立开关状态作为一个二进制数据,并将该16 进制数据各位数字对应的字符0~F 显示到低4 位七段数码管上(高4 位七段数码管不显示)。

3) 点击BTND 按键时,计算机读入一组16 位独立开关状态作为一个二进制数据,并将该数据表示的无符号十进制数各位数字对应的字符0~9 显示到低5 位七段数码管上(高3 位七段数码管不显示)。

要求用程序控制和中断两种方式实现

程序控制:

#include "stdio.h"
#include "xil_io.h"
#include "xgpio_l.h"
int main()
{
	char button;//0x10,0x1,0x4

	Xil_Out8(0x40020004,0x13);		//设置按键为输入
	Xil_Out16(0x40000004,0xffff);	//设置开关为输入
	Xil_Out8(0x40010004,0x0);		//设置位码为输出
	Xil_Out8(0x4001000c,0x0);		//设置段码为输出
	while(1)
	{
		while((Xil_In8(0x40020000)&0x13)!=0)		//读按键输入
		{
			button = Xil_In8(0x40020000)&0x13;
			while((Xil_In8(0x40020000)&0x13)!=0);
			xil_printf("The pushed button's code is 0x%x\n",button);
			if(button == 0x1)						//按键C
			{
				char segtable[2]={0xc0,0xf9};	//段码表
				char segcode[8]={0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0};		//显示缓冲区
				short poscode[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};		//位码表
				while((Xil_In8(0x40020000)&0x13)==0)
				{
					for(int i=0;i<8;i++)
					{
						short key = Xil_In16(0x40000000);
						for(int digit_index=0; digit_index<8; digit_index++)
						{
							segcode[7-digit_index]=segtable[(key>>(digit_index))&0x1];
						}
						Xil_Out8(0x40010000,poscode[i]);
						Xil_Out8(0x40010008,segcode[i]);
						for(int j=0;j<10000;j++);			//延时控制
					}
				}

			}
			else if(button == 0x2)					//按键U
			{
				char segtable[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};	//段码表
				char segcode[4]={0xc0,0xc0,0xc0,0xc0};		//显示缓冲区
				short poscode[4]={0xf7,0xfb,0xfd,0xfe};		//位码表
				while((Xil_In8(0x40020000)&0x13)==0)
				{
					for(int i=0;i<4;i++)
					{
						short key = Xil_In16(0x40000000);
						for(int digit_index=0; digit_index<4; digit_index++)
						{
							segcode[3-digit_index]=segtable[(key>>(4*digit_index))&0xf];
						}
						Xil_Out8(0x40010000,poscode[i]);
						Xil_Out8(0x40010008,segcode[i]);
						for(int j=0;j<10000;j++);			//延时控制
					}
				}
			}
			else if(button == 0x10)					//按键D
			{
				char segtable[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};	//段码表
				char segcode[5]={0xc0,0xc0,0xc0,0xc0,0xc0};			//显示缓冲区
				short poscode[5]={0xef,0xf7,0xfb,0xfd,0xfe};		//位码表
				while((Xil_In8(0x40020000)&0x13)==0)
				{
					for(int i=0;i<5;i++)
					{
						unsigned short key = Xil_In16(0x40000000);
						for(int digit_index=0; digit_index<5; digit_index++)
						{
							segcode[4-digit_index]=segtable[key%10];
							key = key/10;
						}
						Xil_Out8(0x40010000,poscode[i]);
						Xil_Out8(0x40010008,segcode[i]);
						for(int j=0;j<10000;j++);			//延时控制
					}
				}
			}

		}

	}
	return 0;

}

中断:

#include "xil_io.h"
#include "stdio.h"
#include "xgpio_l.h"
#include "xintc_l.h"
#include "xtmrctr_l.h"
#define RESET_VALUE 10000
void Seg_TimerCounterHandler();
void BtnHandler();
void SwitchHandler();
void My_ISR()__attribute__((interrupt_handler));//总中断服务雅序
char segtable[16] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
char segcode[8]={0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0};//缓冲区
short poscode[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
int j = 0;
int k = 0;
int main()
{
	Xil_Out32(XPAR_AXI_GPIO_1_BASEADDR+XGPIO_TRI2_OFFSET,0x0);//设段码输出方式
    Xil_Out32(XPAR_AXI_GPIO_1_BASEADDR+XGPIO_TRI_OFFSET,0x0);//设位码为输出方式
    Xil_Out32(XPAR_AXI_GPIO_2_BASEADDR+XGPIO_TRI_OFFSET,0x13);//设地BUTTON方输入方式
    Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_TRI_OFFSET,0xffff);//设地Switch方输入方式
    Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_IER_OFFSET,XGPIO_IR_CH1_MASK);//打开开关中断
    Xil_Out32(XPAR_AXI_GPIO_2_BASEADDR+XGPIO_IER_OFFSET,XGPIO_IR_CH1_MASK);//打开按键中断
    Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_GIE_OFFSET,XGPIO_GIE_GINTR_ENABLE_MASK);//允许GPIO0中断输出
    Xil_Out32(XPAR_AXI_GPIO_2_BASEADDR+XGPIO_GIE_OFFSET,XGPIO_GIE_GINTR_ENABLE_MASK);//允许GPIO2中断输出
    Xil_Out32(XPAR_AXI_TIMER_0_BASEADDR+XTC_TCSR_OFFSET,Xil_In32(XPAR_AXI_TIMER_0_BASEADDR+XTC_TCSR_OFFSET)&~XTC_CSR_ENABLE_TMR_MASK);//写TCSR,停止计数器
    Xil_Out32(XPAR_AXI_TIMER_0_BASEADDR+XTC_TLR_OFFSET,RESET_VALUE);//写TLR,预置计数初值
    Xil_Out32(XPAR_AXI_TIMER_0_BASEADDR+XTC_TCSR_OFFSET,Xil_In32(XPAR_AXI_TIMER_0_BASEADDR+XTC_TCSR_OFFSET)|XTC_CSR_LOAD_MASK);//装载计数初值
    Xil_Out32(XPAR_AXI_TIMER_0_BASEADDR+XTC_TCSR_OFFSET,(Xil_In32(XPAR_AXI_TIMER_0_BASEADDR+XTC_TCSR_OFFSET)&~XTC_CSR_LOAD_MASK)|XTC_CSR_ENABLE_TMR_MASK|XTC_CSR_AUTO_RELOAD_MASK|XTC_CSR_ENABLE_INT_MASK|XTC_CSR_DOWN_COUNT_MASK);//开始计时运行,自动装载,允许中断,减计数

    Xil_Out32(XPAR_AXI_INTC_0_BASEADDR+XIN_IAR_OFFSET,0xffffffff);
    Xil_Out32(XPAR_AXI_INTC_0_BASEADDR+XIN_IER_OFFSET,XPAR_AXI_GPIO_2_IP2INTC_IRPT_MASK|XPAR_AXI_GPIO_0_IP2INTC_IRPT_MASK|XPAR_AXI_TIMER_0_INTERRUPT_MASK);//对中断控制器进行中断控制源使能
    Xil_Out32(XPAR_AXI_INTC_0_BASEADDR+XIN_MER_OFFSET,XIN_INT_MASTER_ENABLE_MASK|XIN_INT_HARDWARE_ENABLE_MASK);

    //微处理器开中断
    microblaze_enable_interrupts();
    return 0;

}
void My_ISR()
{

	int status;
	status=Xil_In32(XPAR_AXI_INTC_0_BASEADDR+XIN_ISR_OFFSET);//续敢ISR中断状态寄存器
	if((status&XPAR_AXI_TIMER_0_INTERRUPT_MASK)==XPAR_AXI_TIMER_0_INTERRUPT_MASK)
		Seg_TimerCounterHandler();//定时器中断服务程序
	else if((status&XPAR_AXI_GPIO_2_IP2INTC_IRPT_MASK)==XPAR_AXI_GPIO_2_IP2INTC_IRPT_MASK)
	{
	    BtnHandler();//按键中断服务程序
	    SwitchHandler();
	}
	else if((status&XPAR_AXI_GPIO_0_IP2INTC_IRPT_MASK)==XPAR_AXI_GPIO_0_IP2INTC_IRPT_MASK)
		SwitchHandler();
	Xil_Out32(XPAR_AXI_INTC_0_BASEADDR+XIN_IAR_OFFSET,status);//写IAR中断响应寄存器

}

void Seg_TimerCounterHandler()

{

	Xil_Out32(XPAR_AXI_GPIO_1_BASEADDR+XGPIO_DATA_OFFSET,poscode[j+(8-k)]);
	Xil_Out32(XPAR_AXI_GPIO_1_BASEADDR+XGPIO_DATA2_OFFSET,segcode[j]);
	j++;
	if(j>=k)
	{
		j=0;
	}
	Xil_Out32(XPAR_AXI_TIMER_0_BASEADDR+XTC_TCSR_OFFSET,Xil_In32(XPAR_AXI_TIMER_0_BASEADDR+XTC_TCSR_OFFSET));//满总中断

}

void BtnHandler()

{
	int btncode;
	btncode=Xil_In32(XPAR_AXI_GPIO_2_BASEADDR+XGPIO_DATA_OFFSET);
	xil_printf("The pushed button's code is 0x%x\n",btncode);
	if(btncode==0x1)
	{
		k=8;
	}
	else if(btncode==0x2)
	{
		k=4;
	}
	else if(btncode==0x10)
	{
		k=5;
	}
	Xil_Out32(XPAR_AXI_GPIO_2_BASEADDR+XGPIO_ISR_OFFSET,Xil_In32(XPAR_AXI_GPIO_2_BASEADDR+XGPIO_ISR_OFFSET));
}

void SwitchHandler()
{
	xil_printf("switch");
	unsigned short key=Xil_In16(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_DATA_OFFSET);
	if(k==8)
	{
		for(int digit_index=0; digit_index<8; digit_index++)
		{
			segcode[7-digit_index]=segtable[(key>>(digit_index))&0x1];
		}
	}
	else if(k==4)
	{
		for(int digit_index=0; digit_index<4; digit_index++)
		{
			segcode[3-digit_index]=segtable[(key>>(4*digit_index))&0xf];
		}
	}
	else if(k==5)
	{
		for(int digit_index=0; digit_index<5; digit_index++)
		{
			segcode[4-digit_index]=segtable[key%10];
			key = key/10;
		}
	}

	Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_ISR_OFFSET,Xil_In32(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_ISR_OFFSET));

}

说明:使用软件为Vivado 2018.3,使用的开发板为Nexys4 DDR

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值