文章目录

  • 前言
  • 准备工作
  • 寄存器简介
    • GPIO配置PCR寄存器
    • GPIO控制寄存器
  • 库函数简介
    • PORT_SetPinConfig
    • PORT_SetPinMux
    • GPIO_PinInit
    • GPIO_WritePinOutput
    • GPIO_TogglePinsOutput
    • GPIO_ReadPinInput
  • RGB LED的初始化
    • led_driver.c文件内容
    • led_driver.h文件内容
  • 板载按键初始化
    • button_driver.c文件内容
    • button_driver.h文件内容
  • 主函数应用
  • 代码下载
  • 总结
  • 参考资料
  • 推荐阅读

前言

织女星开发板是OPEN-ISA社区为中国大陆地区定制的一款体积小、功耗超低和功能丰富的 RISC-V评估开发板,基于NXP半导体四核异构RV32M1主控芯片。

  • 两个RISC-V核:RI5CY + ZERO_RISCY。
  • 两个ARM核: Cortex-M4F + Cortex-M0+ 。

4个核被分为两个子系统,大核CM4F/RI5CY和小核CM0+/ZERO-RISCY,片上集成1.25 MB Flash 、384 KB SRAM,其中1 MB的Flash被大核所使用,起始地址0x0000_0000,另外的256 KB Flash被小核所使用,起始地址0x0100_0000。利用该开发板,用户可以快速建立一个使用 RV32M1 的 RISC-V应用和演示系统。详细的介绍可以参考: 真正的RISC-V开发板——VEGA织女星开发板开箱评测 ,本篇文章介绍如何基于RISC-V RI5CY/ZERO内核来点亮板载的RGB_LED/STS_LED、读取按键输入,演示GPIO的输入输出和外部中断功能。

准备工作

在进行以下操作之前,要确保开发环境已经搭建完成,而且能正常下载调试。

  • 织女星开发板RISC-V开发环境:Eclipse + riscv32 工具链 + OpenOCD调试工具
  • 织女星开发板SDK包:rv32m1_sdk_riscv
  • 织女星开发板的原理图
  • RV32M1参考手册

以上资料的获取、开发环境搭建和启动模式修改等教程,可以到官方中文论坛查找:www.open-isa.cn

或者是参考我分享的以下文章:

  • 真正的RISC-V开发板——VEGA织女星开发板开箱评测
  • 手把手教你搭建织女星开发板RISC-V开发环境
  • 织女星开发板启动模式修改
  • 织女星开发板调试器升级为Jlink固件
  • 织女星开发板RISC-V内核实现微秒级精确延时

寄存器简介

根据RV32M1参考手册GPIO章节的介绍,我们可以获得关于GPIO相关寄存器信息:

各GPIO组的基地址:

    GPIOA——4802_0000hGPIOB——4802_0040hGPIOC——4802_0080hGPIOD——4802_00C0hGPIOE——4100_F000h

GPIO配置PCR寄存器

这是一个32位的寄存器,每一个引脚都有对应的一个PORTx_PCRn,用来配置GPIO的以下功能:

  • 上下拉配置
  • 翻转速率控制
  • 开漏使能
  • 无源输入滤波器
  • 寄存器锁定
  • 复用功能设置

以PA0控制寄存器,PORTA_PCR0为例:

通过查看参考手册,可以了解到各Bit的功能:

  • ISF:1位,中断状态标志
  • IRQC:4位,配置中断方式和DMA功能
  • LK:1位,是否锁定PCR寄存
  • MUX:3位,复用功能配置
  • ODE:1位,推挽开漏配置
  • PFE:1位,滤波器配置
  • SRE:1位,翻转速率配置
  • PE:1位,上下拉使能
  • PS:1位,上下拉配置

详细的配置介绍可以查看参考手册。官方库fsl_port中的


PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config)
PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t mux)
PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, port_interrupt_t config)
PORT_SetPinDriveStrength(PORT_Type* base, uint32_t pin, uint8_t strength)

这些函数就是控制的这个PCR寄存器。

GPIO控制寄存器

主要包括控制GPIO输入输出控制,读取输入,控制输出,方向控制等。

寄存器描述和地址偏移量:

RV32M1的GPIO共有6个32位的控制寄存器,从字面意思可以直接知道每个寄存器的功能:

  • PDOR:数据输出寄存器,指定位写入0/1,输出0/1
  • PSOR:端口置位输出寄存器,指定位写1,置位输出1,写0状态不变
  • PCOR:端口复位输出寄存器,指定位写1,复位输出0,写0状态不变
  • PTOR:端口反转输出寄存器,指定位写1,反转输出,写0状态不变
  • PDIR:端口输入寄存器,读取指定位输入状态
  • PDDR:端口方向配置寄存器,指定位写0作为输入,写1作为输出

官方库中的fsl_gpio文件中实现的函数就是控制的这几个寄存器。


void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config)
void GPIO_WritePinOutput(GPIO_Type *base, uint32_t pin, uint8_t output)
void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask)
void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask)
void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask)

库函数简介

和其他的MCU一样,由于RV32M1的寄存器众多,为了方便使用,增强程序的可读性,官方开发了库函数,来实现对寄存器的控制,本质上还是操作的寄存器。GPIO控制的库主要由fsl_gpio和fsl_port两个文件组成,其中fsl_gpio主要是对GPIO的控制,如读取输入,控制输出,清除中断标志等,而fsl_port主要实现对GPIO工作的模式进行配置,如复用功能,上拉下拉,开漏推挽,中断触发方式,DMA功能等进行设置。

下面简单介绍几个常用的函数:

PORT_SetPinConfig

配置GPIO的复用功能,驱动能力,推挽开漏,上下拉,滤波器,翻转速率等功能,基于PCR寄存器实现。


port_pin_config_t config;config.driveStrength = kPORT_HighDriveStrength;       //驱动能力配置
config.mux = kPORT_MuxAsGpio;                      //通用GPIO
config.openDrainEnable = kPORT_OpenDrainDisable;   //推挽
config.passiveFilterEnable = kPORT_PassiveFilterDisable;//滤波器
config.pullSelect = kPORT_PullUp;                  //上拉
config.slewRate = kPORT_FastSlewRate;              //翻转速率PORT_SetPinConfig(PORTA, 22, &config);                //配置GPIOA22

PORT_SetPinMux

配置GPIO的复用功能,基于PCR寄存器实现。

//PA22作为普通GPIO使用
PORT_SetPinMux(PORTA, 22, kPORT_MuxAsGpio);//PA25作为UART1_RX功能
PORT_SetPinMux(PORTA, 25, kPORT_MuxAlt2);

具体复用为哪种功能,不同的引脚有不同的复用功能,对应的ALTn,可以查看参考手册RV32M1 Pinout介绍。

PORT_SetPinConfig已经包含了PORT_SetPinMux的功能,可以只使用PORT_SetPinConfig来GPIO功能的配置。PORT_SetPinMux函数不推荐和PORT_SetPinsConfig函数一起使用:

This function is NOT recommended to use together with the PORT_SetPinsConfig, because the PORT_SetPinsConfig need to configure the pin mux anyway (Otherwise the pin mux is reset to zero : kPORT_PinDisabledOrAnalog). This function is recommended to use to reset the pin mux

GPIO_PinInit

控制GPIO的输入输出方式,及默认输出电平,基于PDDR、PCOR、PSOR寄存器实现。


gpio_pin_config_t io_init;//配置输出/输出模式
io_init.outputLogic = 0;   //默认输出0
io_init.pinDirection = kGPIO_DigitalOutput;    //数字输出GPIO_PinInit(LED_RGB_GPIO, LED_RED_Pin, &io_init);    //LED引脚配置

GPIO_WritePinOutput

指定引脚输出高低电平,基于PCOR和PSOR寄存器实现。

 GPIO_WritePinOutput(GPIOA, 22, 1);  //PA22输出1

GPIO_TogglePinsOutput

指定引脚输出翻转,基于PTOR寄存器实现

 GPIO_TogglePinsOutput(GPIOA, 1 << 22);    //PA22输出翻转

GPIO_ReadPinInput

读取GPIO输入状态,基于PDIR寄存器实现

 in = GPIO_ReadPinInput(GPIOA, 22); //读取PA22输入状态

GPIO操作的函数还有很多,详细的介绍和实现可以直接查看库函数源码。

RGB LED的初始化

从原理图中我们可以得知,织女星开发板上共有4个用户可控制的LED,包括3个RGB LED和1个红色LED,均采用MOS来驱动,引脚输出高电平LED点亮,和GPIO的对应关系如下:

LED_RED——PTA24
LED_GREEN——PTA23
LED_BLUE——PTA22
LED_STS——PTE0

所以我们需要配置PTA22/PTA23/PTA24为普通推挽输出方式,然后输出高低电平就可以控制LED闪烁了。

led_driver.c文件内容


#include "led_driver.h"void LED_RGB_Init(void)
{gpio_pin_config_t io_init;port_pin_config_t config;//配置输出/输出模式io_init.outputLogic  = 0;io_init.pinDirection = kGPIO_DigitalOutput;config.driveStrength       = kPORT_HighDriveStrength;  //驱动能力config.lockRegister      = kPORT_LockRegister;       //PCR寄存器被锁定,不能再次改变config.mux                    = kPORT_MuxAsGpio;          //通用GPIOconfig.openDrainEnable         = kPORT_OpenDrainDisable;   //推挽输出config.passiveFilterEnable   = kPORT_PassiveFilterDisable;//滤波器config.pullSelect            = kPORT_PullUp;                 //上拉config.slewRate            = kPORT_FastSlewRate;       //翻转速率CLOCK_EnableClock(LED_RGB_Clk_Name);CLOCK_EnableClock(LED_STS_Clk_Name);     //GPIOE时钟必须一直开启CLOCK_EnableClock(kCLOCK_Rgpio1);            //GPIOE配置需要使能这个时钟/*以下两个函数都可以配置端口功能*/PORT_SetPinConfig(LED_RGB_Port, LED_RED_Pin, &config);      //配置功能更详细PORT_SetPinConfig(LED_RGB_Port, LED_GREEN_Pin, &config);PORT_SetPinConfig(LED_RGB_Port, LED_BLUE_Pin, &config);PORT_SetPinConfig(LED_STS_Port, LED_STS_Pin, &config);//    PORT_SetPinMux(LED_RGB_Port, LED_RED_Pin, kPORT_MuxAsGpio); //只能配置是否复用
//  PORT_SetPinMux(LED_RGB_Port, LED_GREEN_Pin, kPORT_MuxAsGpio);
//  PORT_SetPinMux(LED_RGB_Port, LED_BLUE_Pin, kPORT_MuxAsGpio);//  CLOCK_DisableClock(LED_RGB_Clk_Name);       //可以在配置完成之后关闭时钟,不影响使用GPIO_PinInit(LED_RGB_GPIO, LED_RED_Pin, &io_init);GPIO_PinInit(LED_RGB_GPIO, LED_GREEN_Pin, &io_init);GPIO_PinInit(LED_RGB_GPIO, LED_BLUE_Pin, &io_init);GPIO_PinInit(LED_STS_GPIO, LED_STS_Pin, &io_init);
}

要注意的是,时钟使能要放在GPIO配置之前,否则不能访问GPIO配置寄存器,在配置完成之后可以关闭时钟,也可以一直开启。其中GPIOE非常特殊,要想使用GPIOE,必须使能Rgpio1快速时钟,其他的GPIO配置不需要,这是因为GPIOE属于快速GPIO,和其他几组GPIO不是同一个总线。

CLOCK_EnableClock(kCLOCK_Rgpio1);            //GPIOE配置需要使能这个时钟

led_driver.h文件内容


#ifndef __LED_DRIVER_H__
#define __LED_DRIVER_H__#include "fsl_gpio.h"
#include "fsl_port.h"
#include "fsl_clock.h"/*
LED_RGB_BLUE    - A22
LED_RGB_GREEN   - A23
LED_RGB_RED     - A24
LED_STS         - E0
*/#define LED_RED_Pin       24
#define LED_GREEN_Pin   23
#define LED_BLUE_Pin    22#define LED_RGB_Port      PORTA
#define LED_RGB_GPIO        GPIOA
#define LED_RGB_Clk_Name    kCLOCK_PortA#define LED_STS_Pin     0
#define LED_STS_Port        PORTE
#define LED_STS_GPIO        GPIOE
#define LED_STS_Clk_Name    kCLOCK_PortE#define LED_STS_ON          GPIO_WritePinOutput(LED_STS_GPIO, LED_STS_Pin, 1)
#define LED_STS_OFF         GPIO_WritePinOutput(LED_STS_GPIO, LED_STS_Pin, 0)
#define LED_STS_TOGGLE      GPIO_TogglePinsOutput(LED_STS_GPIO, 1 << LED_STS_Pin)#define LED_RED_ON           GPIO_WritePinOutput(LED_RGB_GPIO, LED_RED_Pin, 1)
#define LED_RED_OFF         GPIO_WritePinOutput(LED_RGB_GPIO, LED_RED_Pin, 0)
#define LED_RED_TOGGLE      GPIO_TogglePinsOutput(LED_RGB_GPIO, 1 << LED_RED_Pin)#define LED_GREEN_ON     GPIO_WritePinOutput(LED_RGB_GPIO, LED_GREEN_Pin, 1)
#define LED_GREEN_OFF       GPIO_WritePinOutput(LED_RGB_GPIO, LED_GREEN_Pin, 0)
#define LED_GREEN_TOGGLE    GPIO_TogglePinsOutput(LED_RGB_GPIO, 1 << LED_GREEN_Pin)#define LED_BLUE_ON            GPIO_WritePinOutput(LED_RGB_GPIO, LED_BLUE_Pin, 1)
#define LED_BLUE_OFF        GPIO_WritePinOutput(LED_RGB_GPIO, LED_BLUE_Pin, 0)
#define LED_BLUE_TOGGLE     GPIO_TogglePinsOutput(LED_RGB_GPIO, 1 << LED_BLUE_Pin)void LED_RGB_Init(void);#endif

头文件中通过宏定义的方式实现了LED的亮灭和翻转控制。

板载按键初始化

按键部分硬件原理图,按下为低电平。

button_driver.c文件内容


#include "button_driver.h"
#include "delay.h"
#include "led_driver.h"//按键使用普通输入GPIO方式
void Button_Init(void)
{gpio_pin_config_t io_init;port_pin_config_t config;io_init.outputLogic  = 0;io_init.pinDirection = kGPIO_DigitalInput;config.mux                     = kPORT_MuxAsGpio;             //通用GPIOconfig.lockRegister         = kPORT_LockRegister;          //PCR寄存器被锁定,不能再次改变config.pullSelect          = kPORT_PullUp;                    //上拉config.slewRate             = kPORT_FastSlewRate;          //翻转速率config.lockRegister       = kPORT_LockRegister;          //PCR寄存器被锁定,不能再次改变config.passiveFilterEnable     = kPORT_PassiveFilterEnable;   //滤波器CLOCK_EnableClock(BTN_SW2_Clk_Name);CLOCK_EnableClock(BTN_SW3_Clk_Name);
//  CLOCK_EnableClock(BTN_SW4_Clk_Name);
//  CLOCK_EnableClock(BTN_SW5_Clk_Name);CLOCK_EnableClock(kCLOCK_Rgpio1);           //GPIOE配置需要使能这个时钟//以下两个函数功能一样PORT_SetPinConfig(BTN_SW2_Port, BTN_SW2_Pin, &config);PORT_SetPinConfig(BTN_SW3_Port, BTN_SW3_Pin, &config);PORT_SetPinConfig(BTN_SW4_Port, BTN_SW4_Pin, &config);PORT_SetPinConfig(BTN_SW5_Port, BTN_SW5_Pin, &config);// PORT_SetPinMux(BTN_SW2_Port, BTN_SW2_Pin, kPORT_MuxAsGpio); //设置IO模式为通用GPIO
//  PORT_SetPinMux(BTN_SW3_Port, BTN_SW3_Pin, kPORT_MuxAsGpio); //设置IO模式为通用GPIO
//  PORT_SetPinMux(BTN_SW4_Port, BTN_SW4_Pin, kPORT_MuxAsGpio); //设置IO模式为通用GPIO
//  PORT_SetPinMux(BTN_SW5_Port, BTN_SW5_Pin, kPORT_MuxAsGpio); //设置IO模式为通用GPIOGPIO_PinInit(BTN_SW2_GPIO, BTN_SW2_Pin, &io_init);GPIO_PinInit(BTN_SW3_GPIO, BTN_SW3_Pin, &io_init);GPIO_PinInit(BTN_SW4_GPIO, BTN_SW4_Pin, &io_init);GPIO_PinInit(BTN_SW5_GPIO, BTN_SW5_Pin, &io_init);
}//按键使用外部中断初始化函数
void ButtonInterruptInit(void)
{gpio_pin_config_t io_init;port_pin_config_t config;io_init.outputLogic  = 0;io_init.pinDirection = kGPIO_DigitalInput;config.mux                     = kPORT_MuxAsGpio;             //通用GPIOconfig.lockRegister         = kPORT_LockRegister;          //PCR寄存器被锁定,不能再次改变config.pullSelect          = kPORT_PullUp;                    //上拉config.slewRate             = kPORT_FastSlewRate;          //翻转速率config.lockRegister       = kPORT_LockRegister;          //PCR寄存器被锁定,不能再次改变config.passiveFilterEnable     = kPORT_PassiveFilterEnable;   //滤波器CLOCK_EnableClock(BTN_SW2_Clk_Name);CLOCK_EnableClock(BTN_SW3_Clk_Name);
//  CLOCK_EnableClock(BTN_SW4_Clk_Name);
//  CLOCK_EnableClock(BTN_SW5_Clk_Name);CLOCK_EnableClock(kCLOCK_Rgpio1);           //GPIOE配置需要使能这个时钟//以下两个函数功能一样PORT_SetPinConfig(BTN_SW2_Port, BTN_SW2_Pin, &config);PORT_SetPinConfig(BTN_SW3_Port, BTN_SW3_Pin, &config);PORT_SetPinConfig(BTN_SW4_Port, BTN_SW4_Pin, &config);PORT_SetPinConfig(BTN_SW5_Port, BTN_SW5_Pin, &config);//设置中断触发方式PORT_SetPinInterruptConfig(BTN_SW2_Port, BTN_SW2_Pin, kPORT_InterruptFallingEdge);   //下降沿触发中断PORT_SetPinInterruptConfig(BTN_SW3_Port, BTN_SW3_Pin, kPORT_InterruptFallingEdge);PORT_SetPinInterruptConfig(BTN_SW4_Port, BTN_SW4_Pin, kPORT_InterruptFallingEdge);PORT_SetPinInterruptConfig(BTN_SW5_Port, BTN_SW5_Pin, kPORT_InterruptFallingEdge);#if defined(CPU_RV32M1_ri5cy)//RI5CY Core GPIOE需要使能以下两个函数, ZERO Core不用INTMUX_Init(INTMUX0);INTMUX_EnableInterrupt(INTMUX0, 0, PORTE_IRQn);
#endifEnableIRQ(BTN_SW2_IRQ);EnableIRQ(BTN_SW3_IRQ);
//  EnableIRQ(BTN_SW4_IRQ);
//  EnableIRQ(BTN_SW5_IRQ);GPIO_PinInit(BTN_SW2_GPIO, BTN_SW2_Pin, &io_init);GPIO_PinInit(BTN_SW3_GPIO, BTN_SW3_Pin, &io_init);GPIO_PinInit(BTN_SW4_GPIO, BTN_SW4_Pin, &io_init);GPIO_PinInit(BTN_SW5_GPIO, BTN_SW5_Pin, &io_init);
}void PORTA_IRQHandler(void)
{GPIO_ClearPinsInterruptFlags(BTN_SW2_GPIO, 1U << BTN_SW2_Pin);LED_STS_TOGGLE;LOG("sw2 is pressed \r\n");
}//GPIOE外部中断函数
void PORTE_IRQHandler(void)
{uint32_t flag;flag = GPIO_GetPinsInterruptFlags(BTN_SW3_GPIO);GPIO_ClearPinsInterruptFlags(BTN_SW3_GPIO, 1U << BTN_SW3_Pin);GPIO_ClearPinsInterruptFlags(BTN_SW4_GPIO, 1U << BTN_SW4_Pin);GPIO_ClearPinsInterruptFlags(BTN_SW5_GPIO, 1U << BTN_SW5_Pin);if(flag & (1 << BTN_SW3_Pin)) //SW3产生中断{LED_RED_TOGGLE;LOG("sw3 is pressed \r\n");}else if(flag & (1 << BTN_SW4_Pin)){LED_GREEN_TOGGLE;LOG("sw4 is pressed \r\n");}else if(flag & (1 << BTN_SW5_Pin)){LED_BLUE_TOGGLE;LOG("sw5 is pressed \r\n");}
}//轮询方式获取按键状态
uint8_t GetKey(void)
{uint8_t key = 1;//按键按下为0if(BTN_SW2_IN && BTN_SW3_IN && BTN_SW4_IN && BTN_SW5_IN){Delay_ms(10);if(!BTN_SW2_IN)key = 2;else if(!BTN_SW3_IN)key = 3;else if(!BTN_SW4_IN)key = 4;else if(!BTN_SW5_IN)key = 5;while(!(BTN_SW2_IN && BTN_SW3_IN && BTN_SW4_IN && BTN_SW5_IN));}return key;
}

按键配置为上拉输入模式,同样如果使用GPIOE作为通用GPIO输入,还需要使能Rgpio1时钟

CLOCK_EnableClock(kCLOCK_Rgpio1);            //GPIOE配置需要使能这个时钟

如果使用GPIOE的外部中断功能,还需要使能INTMUX


#if defined(CPU_RV32M1_ri5cy)//RI5CY Core GPIOE需要使能以下两个函数, ZERO Core不用INTMUX_Init(INTMUX0);INTMUX_EnableInterrupt(INTMUX0, 0, PORTE_IRQn);
#endif

button_driver.h文件内容


#ifndef __BUTTON_DRIVER_H__
#define __BUTTON_DRIVER_H__#include "fsl_gpio.h"
#include "fsl_port.h"
#include "fsl_intmux.h"/** SW2 - A0* SW3 - E12* SW4 - E8* SW5 - E9* *///按下为低电平#define BTN_SW2_GPIO    GPIOA
#define BTN_SW3_GPIO    GPIOE
#define BTN_SW4_GPIO    GPIOE
#define BTN_SW5_GPIO    GPIOE#define BTN_SW2_Pin        0
#define BTN_SW3_Pin     12
#define BTN_SW4_Pin     8
#define BTN_SW5_Pin     9#define BTN_SW2_Port   PORTA
#define BTN_SW3_Port    PORTE
#define BTN_SW4_Port    PORTE
#define BTN_SW5_Port    PORTE#define BTN_SW2_IRQ        PORTA_IRQn
#define BTN_SW3_IRQ     PORTE_IRQn
#define BTN_SW4_IRQ     PORTE_IRQn
#define BTN_SW5_IRQ     PORTE_IRQn#define BTN_SW2_Clk_Name  kCLOCK_PortA
#define BTN_SW3_Clk_Name    kCLOCK_PortE
#define BTN_SW4_Clk_Name    kCLOCK_PortE
#define BTN_SW5_Clk_Name    kCLOCK_PortE#define BTN_SW2_IN  GPIO_ReadPinInput(BTN_SW2_GPIO, BTN_SW2_Pin)
#define BTN_SW3_IN  GPIO_ReadPinInput(BTN_SW3_GPIO, BTN_SW3_Pin)
#define BTN_SW4_IN  GPIO_ReadPinInput(BTN_SW4_GPIO, BTN_SW4_Pin)
#define BTN_SW5_IN  GPIO_ReadPinInput(BTN_SW5_GPIO, BTN_SW5_Pin)/*
#define BTN_SW2_IN  ReadGPIO(BTN_SW2_GPIO, BTN_SW2_Pin)
#define BTN_SW3_IN  ReadGPIO(BTN_SW3_GPIO, BTN_SW3_Pin)
#define BTN_SW4_IN  ReadGPIO(BTN_SW4_GPIO, BTN_SW4_Pin)
#define BTN_SW5_IN  ReadGPIO(BTN_SW5_GPIO, BTN_SW5_Pin)
*/void Button_Init(void);
uint8_t GetKey(void);
void ButtonInterruptInit(void);#endif

通过GPIO读取函数来获取按键输入状态,或者是通过中断标志来判断输入状态。

主函数应用

使用外部中断方式读取按键输入状态。


#include "main.h"extern uint32_t SystemCoreClock;int main(void)
{BOARD_BootClockRUN();  //ϵͳʱ֓ŤփUART0_Init();Delay_Init();LOG("SystemCoreClock: %ld \r\n", SystemCoreClock);#if defined(CPU_RV32M1_ri5cy)LOG("RV32M1 RISC-V RI5CY Core Demo \r\n");
#elif defined(CPU_RV32M1_zero_riscy)LOG("RV32M1 RISC-V ZERO Core Demo \r\n");
#endifLED_RGB_Init();
//  Button_Init();ButtonInterruptInit();// LPMTR2_Init();// LPIT1_CH3_Init();while (1){}
}

代码下载

织女星开发板VEGA_Lite支持从4个核启动,所以在进行程序下载之前,要确认当前的启动模式和当前的工程是对应的。如当前工程是使用RISC-V RI5CY核来驱动GPIO,那么就需要配置芯片启动模式为RI5CY核启动。否则会不能下载。关于启动模式的修改可以参考:织女星开发板启动模式修改

  • RI5CY驱动GPIO源码下载:RI5CY_GPIO_Demo.rar
  • ZERO驱动GPIO源码下载:ZERO_GPIO_Demo.rar

总结

RV32M1芯片的GPIOE与其他几组GPIO配置方法稍有不同,使用时要特别注意。

参考资料

  • MCUXpresso SDK API参考手册
  • RV32M1_Vega_Develop_Environment_Setup.pdf
  • RV32M1数据手册
  • RV32M1参考手册
  • 织女星开发板快速入门指南.pdf

推荐阅读

  • 真正的RISC-V开发板——VEGA织女星开发板开箱评测
  • 手把手教你搭建织女星开发板RISC-V开发环境
  • 织女星开发板启动模式修改
  • 织女星开发板调试器升级为Jlink固件
  • 织女星开发板RISC-V内核实现微秒级精确延时

  • 个人博客:www.wangchaochao.top
  • 我的公众号:mcu149

织女星开发板使用RISC-V核驱动GPIO相关推荐

  1. 织女星开发板RISC-V核通过SPI协议驱动ARDUINO LCD模块(显示)

    前言 第一次写这个博客,算是新手吧,刚好有这个机会,手边有VEGA的开发板和Arduino的LCD模块,做了点小东西,想和大家分享一下. 一开始只是想着通过SPI协议初始化LCD屏幕,然后发个字符串就 ...

  2. 织女星开发板RISC-V核通过SPI协议驱动ARDUINO LCD模块(触屏)

    前言 之前写了一个通过SPI协议初始化LCD屏幕并显示字符串和图片的文章,这次再尝试一下触屏的功能. 准备工作 1,焊接织女星开发板J1,J2,J3,J4的双排母座,以便与LCD屏通信.前段时间免费申 ...

  3. 织女星开发板能移植linux吗,织女星开发板启动模式修改——从ARM M4核启动

    前言 刚开始玩织女星开发板的时候,想先从熟悉的ARM核入手,连上Jlink,打开MDK版本的Demo程序,编译OK,却检测不到芯片,仔细看了一下文档,原来RV32M1芯片默认从RISC-V核启动,如果 ...

  4. mssql 无法启动调试器 数据为空_织女星开发板启动模式修改——从ARM M4核启动

    织女星开发板启动模式修改--从ARM M4核启动 前言 刚开始玩织女星开发板的时候,想先从熟悉的ARM核入手,连上Jlink,打开MDK版本的Demo程序,编译OK,却检测不到芯片,仔细看了一下文档, ...

  5. 真正的RISC-V开发板——VEGA织女星开发板开箱评测

    文章目录 前言 关于RISC-V架构 关于VEGA织女星开发板 基于FPGA实现的RISC-V开发板 基于RISC-V芯片实现的开发板 开箱爆照 板载资源简介 主控芯片RV32M1简介 支持的开发工具 ...

  6. NXP恩智浦VEGA织女星开发板免费申请!

    前言 大概两周前申请了一块NXP恩智浦的开发板,今天终于收到了!在这里推荐给大家,官方网站刚上线一个月左右,目前申请的人还不算多,感兴趣的朋友可以申请一个,体验一下这个四核性能怪兽.大厂就是大气,包装 ...

  7. 织女星开发板RISC-V内核实现微秒级精确延时

    文章目录 前言 关于LPIT0 ZERO核的SysTick定时器 delay.c文件 delay.h文件 实际验证 驱动IIC接口OLED 总结 参考资料 历史精选 前言 收到VEGA织女星开发板也有 ...

  8. 织女星开发板调试器升级为Jlink固件

    文章目录 前言 准备工作 升级操作 升级Jlink驱动 板载接口的说明 历史精选 前言 为了能使用板载的FreeLink调试器来调试RISC-V内核,我们需要把默认的CMSIC-DAP固件,升级为JL ...

  9. UT-Exynos4412开发板三星ARM四核旗舰开发平台android4.0体验-12音频输入输出功能调试

    经过2012年的等待,四核的开发平台终于跟广大嵌入从业人员见面了,下面让我们来看下UT-Exynos 4412 开发板的详细参数吧,共广大嵌入式开发人员参考. 一.UT-Exynos 4412开发板高 ...

最新文章

  1. 十天精通CSS3(11)
  2. 《磨难之间》——刻意设计,缺失核心
  3. 1704:baoge的洗漱难题[黄]
  4. http请求中乱码------编码的转换
  5. 反射在工厂模式中的使用
  6. 破解vba工程密码——VBA代码
  7. python纵向输出字符串,python-字符串方法,格式化输出
  8. 业务部门战略规划与支撑部门战略规划
  9. zb怎么做渲染图_ZBrush渲染效果使用图文教程
  10. 什么是项目风险?如何做好项目风险管理
  11. Linux中tar和scp
  12. 2018年高德地图POI全国数据下载
  13. VS2005如何加载Word组件(详细步骤)
  14. 彻底弄懂@Controller 、@Service、@Component
  15. leetcode---1758.生成交替二进制字符串的最少操作数
  16. 利用WPF建立自己的3d gis软件(非axhost方式)(二)基础状态切换
  17. Windows找不到文件wt.exe怎么办?
  18. Win11自带画图软件怎么显示标尺?
  19. 黑马程序员——常用类
  20. 毕设-基于LoRa的智能农业大棚

热门文章

  1. python支付宝支付_python 调用支付宝支付
  2. java中instanceof是什么意思_instance函数中文是什么意思(Java中instanceof有什么作用)...
  3. Java网站安全攻与守(惊魂24小时)
  4. 谈谈软件测试 QA、QC、QM的关系与区别
  5. solidity合约访问其他合约的mapping
  6. 初试树莓派在2.2寸QVGA SPI TFT LCD上显示图片
  7. KeeFarce工具抓取Keepass密码攻击复现及其行为监测
  8. 设置input 不可编辑的方法
  9. 魅蓝2 android os,魅蓝note2的原生android系统刷机包
  10. 10.设计模式之桥接模式