微机原理实验三
并行I/O接口实验
姓名: 学号: 班级:
一、 实验目的
1. 掌握GPIOIP核的工作原理和使用方法
2. 掌握中断控制方式的IO接口设计原理
3. 掌握中断程序设计方法
4. 掌握IO接口程序控制方法:中断方式、查询方式、延时方式
二、 实验任务
按键输入,并显示到console
用中断、查询两种方式实现按键输入,将结果显示到console窗口。
三、 硬件电路
AXI总线IrqAXI INTCIntr1AXIInterrupt总线接口MicroBlazeAXI总线接口Intr0AXI总线接口GPIOInterrupt8位switchAXI总线接口GPIO4位button
四、 硬件实现步骤
1. 创建一个最小系统,启动XPS,并打开xmp工程文件。
2. 添加和配置GPIO IP核。
3. 添加和配置AXI Interrupt Controller IP核。
4. 产生外部GPIO连接。
引脚约束
五、 中断方式、查询方式
1. 中断方式设计思路 主程序开放microBlaze INTC,GPIO中断,不停地检测输出标志是否为1,是则输出数据到console,并将输出标志设置为0。中断服务程序读取数据(或输出数据)并设立输出标志位为1。
通过中断方式读入开关的状态,由于按键仅短暂的时间维持高电平,并且还具有抖动,因此需在中断服务程序内读入按键状态,并且为消除按键回弹产生的中断,需在中断服务程序内部暂时关闭中断,并且延时一段时间再打开中断。
2. 查询方式设计思路
主程序不停地读取GPIO和ISR寄存器,当对应位为1时,读取GPIO的数据寄存器并输出到console(xil_printf函数实现,头文件为”stdio.h”),并写ISR相应位。数据寄存器的读取通过函数Xil_In实现,而ISR相应状态为的写通过函数Xil_Out实现。
六、 软件实现流程
1. 中断方式主程序实现
对各个设备进行初始化,并且开放相应的中断,注册中断服务程序以及开关状态显示等。然后通过读取中断标志进入相应中断服务程序处理中断,并在console打印相关信息。
2. 查询方式程序实现
通过不断地读取GPIO和ISR寄存器,当状态发生变化时读取数据寄存器并输出到console,并写ISR相应位。
七、 软件源代码
1. 中断方式源代码
#include\"xparameters.h\" #include\"xgpio.h\" #include\"xintc.h\" #include\"stdio.h\" voidInitialize(); voidDelay_50ms();
voidPushBtnHandler(void *CallBackRef); voidSwitchHandler(void *CallBackRef); XGpio Btns,Dips;//按键BTNS外设变量 XIntc intCtrl;//定义一个XINTC外设变量 int pshBtn,pshDip; int state1,state2; intmain() {
Initialize();
xil_printf(\"\\r\\nRunning GpioInputInterrupt!\\r\\n\"); while(1)
{ }
return 0 ; }
voidInitialize() {
XGpio_Initialize(&Dips,XPAR_DIP_DEVICE_ID); XGpio_SetDataDirection(&Dips,1,0xff);
XGpio_Initialize(&Btns,XPAR_BUTTON_DEVICE_ID); //初始化按键实例,设定其为输入方式
XGpio_SetDataDirection(&Btns,1,0xff);
XIntc_Initialize(&intCtrl,XPAR_AXI_INTC_0_DEVICE_ID); //intCtr1实例
XGpio_InterruptEnable(&Btns,1);
XGpio_InterruptGlobalEnable(&Btns);//GPIO中断使能 XGpio_InterruptEnable(&Dips,1); XGpio_InterruptGlobalEnable(&Dips);
XIntc_Enable(&intCtrl,XPAR_AXI_INTC_0_BUTTON_IP2INTC_IRPT_INTR); XIntc_Enable(&intCtrl,XPAR_AXI_INTC_0_DIP_IP2INTC_IRPT_INTR);//中断控制器的中断源使能
XIntc_Connect(&intCtrl,XPAR_AXI_INTC_0_BUTTON_IP2INTC_IRPT_INTR,
microblaze_enable_interrupts(); //允许处理器处理中断
microblaze_register_handler((XInterruptHandler)XIntc_InterruptHandl
(XInterruptHandler)PushBtnHandler,(void*)0);
(XInterruptHandler)SwitchHandler,(void*)0); //注册中断服务函数
XIntc_Connect(&intCtrl,XPAR_AXI_INTC_0_DIP_IP2INTC_IRPT_INTR,
if(pshBtn) { }
if(pshDip) { }
xil_printf(\"Switch Interrupt Trigger!!!the state is pshDip=0;
xil_printf(\"Button Interrupt Trigger!!!the state is pshBtn=0;
0x%X\\n\\r\",state1);
0x%X\\n\\r\",state2);
er,(void*)&intCtrl);
XIntc_Start(&intCtrl,XIN_REAL_MODE);//启动中断控制器 }
voidDelay_50ms() { int i;
for(i=0;i<5000000;i++); }
voidPushBtnHandler(void *CallBackRef) {
state1=XGpio_DiscreteRead(&Btns,1);//按键状态值读取 pshBtn=1;
XGpio_InterruptDisable(&Btns,1); // 暂时禁止button中断 Delay_50ms();
XGpio_InterruptClear(&Btns,1); //清除中断标志位 XGpio_InterruptEnable(&Btns,1);//再次开放按键中断 }
voidSwitchHandler(void *CallBackRef) {
state2=XGpio_DiscreteRead(&Dips,1); pshDip=1;
XGpio_InterruptClear(&Dips,1); }
2. 查询方式源代码
/*
* chaxun.c *
* Created on: 2015-12-1 * Author: Administrator */
#include\"xparameters.h\" #include\"stdio.h\" #include\"xil_io.h\" #include\"xil_types.h\"
#define btn_data 0x40000000//数据寄存器地址 #define btn_ctr 0x40000004//控制寄存器地址 #define btn_status 0x40000120//中断状态寄存器
void Delay_50ms();
short pshBtn; int main(void) {
short btn;
xil_printf(\"\\r\\nRunning GpioInput Test!\\n\\r\"); Xil_Out8(btn_ctr,0xff); pshBtn=0x00; while(1) {
pshBtn=Xil_In8(btn_status); if(pshBtn) {
btn=Xil_In8(btn_data); Xil_Out8(btn_status,0x01);
xil_printf(\"Button Pushed!!!the state is 0x%X\\n\\r\ Delay_50ms(); pshBtn=0x00; } } return 0; }
void Delay_50ms() { int i;
for(i=0;i<5000000;i++); }
八、 实验小结
本次实验要求用中断和查询的方式实现IO接口程序控制。
先是创建一个最小系统,然后添加和配置GPIO IP核,再添加和配置AXI Interrupt Controller IP核,然后用自己编写的程序实现按键的显示。 我在这个过程中熟悉了最小系统的建立,还有IP核的配置,但我本身编程能力比较弱,所以我在咨询了同学关于中断和查询代码的实现的问题后,终于能成功地实现按键输入的显示了。虽然付出很多,但收获也是巨大。
因篇幅问题不能全部显示,请点此查看更多更全内容