SmartFusion从FPGA到ARM(二)——MSS

    技术2023-11-06  125

    文章目录

    前言预期效果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 示例工程,可以参考:

    预期效果

    MSS_GPIO_0配置成输出模式,驱动LED0,低电平点亮MSS_GPIO_1配置成输出模式,驱动LED1,低电平点亮MSS_GPIO_2配置成输入模式,外部拨码开关输入,输入状态直接控制LED0MSS_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的配置

    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文件:

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

    编译运行。

    Processed: 0.010, SQL: 9