[米联客-安路飞龙DR1-FPSOC] SDK入门篇连载-04 GPIO PS/PL中断实验

软件版本:Anlogic -TD5.9.1-DR1_ES1.1

操作系统:WIN10 64bit

硬件平台:适用安路(Anlogic)FPGA

实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板

板卡获取平台:https://milianke.tmall.com/

登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

目录

1 概述

2 系统框图

3 GPIO中断处理

4 硬件电路分析

5 搭建SOC系统工程

5.1 GPIO配置

5.2 GPIO PL定义

5.3编译并导出平台文件

6 搭建SOC系统工程

6.1 创建Platform工程

6.2 创建gpio_intr APP工程

7 程序分析

7.1 GPIO位号定义

7.2 中断处理方法

8 方案演示

8.1 硬件准备

8.2 实验结果


1 概述

当正常的程序在运行的时候,中断资源可以打断正在运行的程序,让CPU进入中断函数进行一些事务的处理。使用中断处理可以实现多任务的实时处理,可以提高多任务处理的效率。

本文实验目的:

1:掌握理解中断输入的应用场合

2:PS PSIO的中断寄存器功能定义

3:掌握FDPSIO中断功能的使用

2 系统框图

PSIO一般会分配到固定的外设,包括FLASH、EMMC、TFCARD、UART、USB2.0、ETH以太网。GPIO也可以单独配置成普通的PSIO,如果IO不够用也可以通过PLIO扩展更多IO。

3 GPIO中断处理

中断检测逻辑监控 GPIO输入信号。中断触发器可以是正边缘、负边缘、低电平或高电平。使用GPIOINTTYPE LEVEL、GPIO INT POLARITY 和 GPIO INTEN 对触发灵敏度进行编程。

如果检测到中断,则中断检测逻辑将 GPI0 的 GPIO INTSTATUS 状态置 1。如果 GPIO 中断是边缘敏感的,则中断状态被检测逻辑锁存。通过向 GPIO_PORTA_EOI寄存器写入1来清除中断锁存,然后再通过向 GPIO PORTA EOI寄存器写入0来使能中断。对于电平敏感中断,为了清除中断信号,必须清除中断输入到 GPIO 的中断源。或者,软件可以使用 GPIO INTMASK 寄存器屏蔽输入。

4 硬件电路分析

硬件接口和子卡模块请阅读“附录1”

配套工程的FPGA PIN脚定义路径为soc_prj/uisrc/04_pin/ fpga_pin.adc

5 搭建SOC系统工程

详细的搭建过程这里不再重复,对于初学读者如果还不清楚如何创建SOC工程的,请学习“01Vitis Soc开发入门”这篇文章。

本文中的PS设置内容是新增加的GPIO PS以及GPIO PL部分,关于DDR、PSIO、CPU时钟等设置请参考“01Vitis Soc开发入门”这篇文章。

5.1 GPIO配置

01Vitis Soc开发入门”这篇文章中已经对特定功能的PSIO做了设置,只有剩余的PSIO可以用于其他的自定义功能。以下设置未分配功能的PSIO,以及需要扩展的GPIO PL IO的数量。

5.2 GPIO PL定义

设置好后,右击选择Create Design Port,我们需要两个PL 按键输入

设置IO名称、IO类型、IO位宽

module system_top
(

input [1:0] PL_KEY
);

system I_system (.pl_gpio_in(PL_KEY));

endmodule

5.3编译并导出平台文件

以下步骤简写,有不清楚的看第1篇《01 Soc开发入门》文章。

导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:fpga_prj.hpf的文件。根据硬件平台文件fpga_prj.hpf来创建需要Platform平台。

6 搭建SOC系统工程

创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo。 

6.1 创建Platform工程

创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo《01 Soc开发入门》文章。 

6.2 创建gpio_intr APP工程

7 程序分析

gpio_intr.C文件

#include "al_gpio_hal.h"

#define PL_KEY1   54
#define PL_KEY2   55
#define PS_KEY1   50
#define AL_GPIO_DEVICE_ID  0
#define BANK_INTR_VALUE    0x3
#define BANK_TYPE_REG      0x3
#define BANK_POLARUTY_REG  0x0
#define BANK_BOTHEDGE_REG  0x0
//#define BANK_INTR
#define PIN_INTR

AL_S32 AlGpio_Hal_Intr_Example()
{
    AL_GPIO_HalStruct *GPIO;
    AL_S32 i = 0;

    /* 1、Test AlGpio_Hal_Init */
    AL_S32 ret = AlGpio_Hal_Init(&GPIO, AL_GPIO_DEVICE_ID, AL_NULL);

    if (ret == AL_OK) {
        AL_LOG(AL_LOG_LEVEL_INFO, "[TEST] APU AlGpio_Hal_Init success");
    }
    else {
        AL_LOG(AL_LOG_LEVEL_INFO, "[TEST] APU AlGpio_Hal_Init failed");
    }

    /* 2、Test InputRead EXT register */
    for(i = 0; i < 6; i++) {
        AL_LOG(AL_LOG_LEVEL_INFO, "GPIO Pin %d input data value is 0x%x", PL_KEY1, AlGpio_Hal_ReadPinInput(GPIO,PL_KEY1));
    }

    /* 3、Test intr */
#ifdef PIN_INTR
    AlGpio_Hal_IntrPinCfg(GPIO, PL_KEY1, GPIO_INTR_TYPE_EDGE_FALLING);
    AlGpio_Hal_IntrPinCfg(GPIO, PL_KEY2, GPIO_INTR_TYPE_EDGE_BOTH);
  //  AlGpio_Hal_IntrPinCfg(GPIO, PS_KEY1, GPIO_INTR_TYPE_EDGE_RISING);
    AlSys_MDelay(5000);
#else
    AlGpio_Hal_IntrBankCfg(GPIO, AL_GPIO_BANK2, BANK_INTR_VALUE, BANK_TYPE_REG, BANK_POLARUTY_REG, BANK_BOTHEDGE_REG);
#endif

    AlIntr_SetLocalInterrupt(AL_FUNC_ENABLE);

    while(1);

    return AL_OK;
}

AL_S32 main(void) {
    AL_LOG(AL_LOG_LEVEL_INFO, "[TEST]AlGpio_Hal_Test start");
    AlGpio_Hal_Intr_Example();

    return AL_OK;
}

7.1 GPIO位号定义

#define PL_KEY1   54
#define PL_KEY2   55
#define PS_KEY1   50

经过上节课的学习,该部分想必已经掌握,不再赘述。

7.2 中断处理方法

于上节课相同,同样是采用的两种方法来触发中断,与上节课不同的是两种方法不能同时使用,通过#define定义来调整。当你需要使用哪种中断方式时,注销掉另一种即可。注:修改完成后,需要重新编译。

//#define BANK_INTR
#define PIN_INTR

方法一:直接通过Bank控制中断,代码如下:

AlGpio_Hal_IntrBankCfg(GPIO,AL_GPIO_BANK2, BANK_INTR_VALUE, BANK_TYPE_REG, BANK_POLARUTY_REG, BANK_BOTHEDGE_REG);

此函数功能为配置 bank 的中断,包括方向、类型和使能寄存器。这里我们使能两个GPIO PL作为中断。

同时我们需要了解3个宏定义分别是

typedef enum
{
    GPIO_INTR_LEVEL   =  0x0,
    GPIO_INTR_EDGE    =  0x1,
} 
AL_GPIO_IntrTypeEnum;
typedef enum
{
    GPIO_INTR_LOW     =  0x0,
    GPIO_INTR_HIGH    =  0x1,
} 
AL_GPIO_IntrPolarityEnum;
typedef enum
{
    GPIO_INTR_Single    =  0x0,
    GPIO_INTR_Both      =  0x1,
} 
AL_GPIO_IntrBothEdgeEnum;

依次对应的是AlGpio_Hal_IntrBankCfg函数中的BANK_TYPE_REG BANK_POLARUTY_REG BANK_BOTHEDGE_REG而我们程序中的定义是

#define BANK_TYPE_REG      0x3
#define BANK_POLARUTY_REG  0x0
#define BANK_BOTHEDGE_REG  0x0

综上,我们该函数设定的含义是GPIO Bank2中的0x3使能作为中断,类型为:边缘触发、低电平触发、每次触发1次。稍后我们可以验证一下是否跟我们的预期一致。

方法二:通过位号控制中断,代码如下:

    AlGpio_Hal_IntrPinCfg(GPIO, PL_KEY1, GPIO_INTR_TYPE_EDGE_FALLING);
    AlGpio_Hal_IntrPinCfg(GPIO, PL_KEY2, GPIO_INTR_TYPE_EDGE_BOTH);
 //   AlGpio_Hal_IntrPinCfg(GPIO, PS_KEY1, GPIO_INTR_TYPE_EDGE_RISING);
    AlSys_MDelay(5000);

根据原理图,当PL KEY按下后为低电平,所以我们设置两个按键为低电平触发以及高低电平触发。也就是PL_KEY1按下后松开,触发1次中断,PL_KEY2按下后松开,触发2次中断,PS_KEY1按下时,触发1次中断。(经过测试发现如果PS KEY与PL KEY混用的情况下,会出现反馈0x0的情况)

8 方案演示

8.1 硬件准备

本实验需要用到JTAG下载器、USB转串口外设,另外需要把SW1模式开关设置到JTAG模式

8.2 实验结果

由于添加了PL端按键资源,所以Debug时需要将TD生成的soc_prj/soc_prj_Runs/best_result/soc_prj.bit文件同时添加进来,在debug前会先下载PL端资源后启动SOC部分。

BANK_INTR:

每次KEY1和KEY2按键按下的时候,均会产生1个中断

PIN_INTR:

每次KEY1按键按下的时候,会产生1个中断,KEY2按键按下的时候,会产生2个中断

  • 20
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值