SmartFusion从FPGA到ARM(二)——MSS_GPIO外部中断和输入

文章目录

      • 前言
        • 预期效果
        • 0.MSS_GPIO相关的函数
        • 1.MSS_GPIO模式配置
        • 2.GPIO检测和控制实现
        • 3.FPGA工程编译和运行

系列教程: SmartFusion从FPGA到ARM系列教程

前言

关于片上MCU基本外设的使用,可以查看对应的头文件,里面有非常详细的使用说明。

在嵌入式开发中,一个GPIO通常有输入,输出,外部中断和复用功能。但是对于SmartFusion系列FPGA内部的MCU来说,GPIO只有输入输出和外部中断功能,并没有复用功能。上一篇文章,介绍了片上MSS,即ARM MCU的配置,并使用MCU的GPIO外设驱动了LED,本篇文章介绍MSS_GPIO配置成输入模式,直接读取输入和配置成外部中断。

固件库下载地址:Firmware_MSS_GPIO_Driver_v2.0.105
示例工程,可以参考:
SmartFusion从FPGA到ARM(二)——MSS_GPIO外部中断和输入_第1张图片

预期效果

  • MSS_GPIO_0配置成输出模式,驱动LED0,低电平点亮
  • MSS_GPIO_1配置成输出模式,驱动LED1,低电平点亮
  • MSS_GPIO_2配置成输入模式,外部拨码开关输入,输入状态直接控制LED0
  • MSS_GPIO_3配置成输入模式,双边沿触发中断,上升沿熄灭LED,下降沿点亮LED1。

所以最终实现的效果是:

  • GPIO_2输入低电平时,LED0点亮;GPIO_2输入高电平时,LED0熄灭。
  • GPIO_3从高电平变为低电平时,LED1点亮;GPIO_3从低电平变为高电平时,LED1熄灭

0.MSS_GPIO相关的函数

在进行正式的配置之前,先来了解一下MSS_GPIO的一些接函数吧。

GPIO的模式,支持以下几种,配置要和FPGA工程中MSS的配置保持一致 :

/* 输入模式 */
#define MSS_GPIO_INPUT_MODE              0x0000000002UL
/* 输出模式 */
#define MSS_GPIO_OUTPUT_MODE             0x0000000005UL
/* 输入输出模式 */
#define MSS_GPIO_INOUT_MODE              0x0000000003UL

中断触发方式支持高电平,低电平,上升沿,下降沿和双边沿触发:

#define MSS_GPIO_IRQ_LEVEL_HIGH			0x0000000000UL
#define MSS_GPIO_IRQ_LEVEL_LOW			0x0000000020UL
#define MSS_GPIO_IRQ_EDGE_POSITIVE		0x0000000040UL
#define MSS_GPIO_IRQ_EDGE_NEGATIVE		0x0000000060UL
#define MSS_GPIO_IRQ_EDGE_BOTH			0x0000000080UL

对于双向GPIO,支持输入、输出和高阻三种状态:

typedef enum mss_gpio_inout_state
{
    MSS_GPIO_DRIVE_LOW = 0,
    MSS_GPIO_DRIVE_HIGH,
    MSS_GPIO_HIGH_Z
} mss_gpio_inout_state_t;

下面来介绍几个常用的函数

/* 设置某一个GPIO的电平 */
void MSS_GPIO_set_output(mss_gpio_id_t port_id, uint8_t value);
/* 设置所有GPIO的电平 */
void MSS_GPIO_set_outputs(uint32_t value);
/* 获取所有GPIO的输入状态 */
uint32_t MSS_GPIO_get_inputs(void)
/* 获取所有GPIO的输出状态 */
uint32_t MSS_GPIO_get_outputs(void);
/* 设置双向GPIO的状态 */
void MSS_GPIO_drive_inout(mss_gpio_id_t port_id, mss_gpio_inout_state_t inout_state);
/* 使能中断 */
void MSS_GPIO_enable_irq(mss_gpio_id_t port_id);
/* 禁止中断 */
void MSS_GPIO_disable_irq(mss_gpio_id_t port_id);
/* 清除中断 */
void MSS_GPIO_clear_irq(mss_gpio_id_t port_id);

1.MSS_GPIO模式配置

这里的模式配置包括两方面,一个是FPGA工程中,MSS的配置,一个是ARM程序中模式的配置。

MSS的配置

SmartFusion从FPGA到ARM(二)——MSS_GPIO外部中断和输入_第2张图片

ARM程序中的配置:

/* GPIO_0 & GPIO_1 配置成输出模式 */
MSS_GPIO_config(MSS_GPIO_0, MSS_GPIO_OUTPUT_MODE);
MSS_GPIO_config(MSS_GPIO_1, MSS_GPIO_OUTPUT_MODE);

/* GPIO_2配置成输入模式*/
MSS_GPIO_config(MSS_GPIO_2, MSS_GPIO_INPUT_MODE);

/* GPIO_3配置成输入模式,双边沿触发中断 */
MSS_GPIO_config(MSS_GPIO_3, MSS_GPIO_INPUT_MODE| MSS_GPIO_IRQ_EDGE_BOTH);
/* 使能中断 */
MSS_GPIO_enable_irq(MSS_GPIO_3);

2.GPIO检测和控制实现

MSS_GPIO_2的状态控制GPIO_0上的LED:

while(1)
{
    /* 如果GPIO_2输入为0 */
    if(MSS_GPIO_get_inputs() & MSS_GPIO_2_MASK)
        MSS_GPIO_set_output(MSS_GPIO_0, 0); /* 点亮LED */
    else 
        MSS_GPIO_set_output(MSS_GPIO_0, 1); /* 熄灭LED */
}

其中MSS_GPIO_2_MASK已经在头文件中进行了定义:

#define MSS_GPIO_2_MASK         0x00000004UL

MSS_GPIO_3中断服务函数:

/* MSS_GPIO_3中断服务函数 */
void GPIO3_IRQHandler(void)
{
    /* 下降沿 */
    if(MSS_GPIO_get_inputs() & MSS_GPIO_3_MASK)
        MSS_GPIO_set_output(MSS_GPIO_1, 0);	/* 点亮LED */
    else    /* 上升沿 */
        MSS_GPIO_set_output(MSS_GPIO_1, 1); /* 熄灭LED */
    MSS_GPIO_clear_irq(MSS_GPIO_3);
}

3.FPGA工程编译和运行

FPGA工程MSS ENVM加载生成的Hex文件:

SmartFusion从FPGA到ARM(二)——MSS_GPIO外部中断和输入_第3张图片

编译,分配管脚,因为我的板子原理图中拨码开关没有接上下拉电阻,拨码开关导通是高电平,所以在管脚分配时,配置成了下拉输入。

SmartFusion从FPGA到ARM(二)——MSS_GPIO外部中断和输入_第4张图片
编译运行。

你可能感兴趣的:(Microsemi,Libero,FPGA,ARM,MSS_GPIO)