有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 皋陶 于 2020-10-22 21:25 编辑
前言
- 两个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参考手册
或者是参考我分享的以下文章:
寄存器简介
根据RV32M1参考手册GPIO章节的介绍,我们可以获得关于GPIO相关寄存器信息:
各GPIO组的基地址: - GPIOA——4802_0000h
- GPIOB——4802_0040h
- GPIOC——4802_0080h
- GPIOD——4802_00C0h
- GPIOE——4100_F000h
复制代码
这是一个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; //通用GPIO
- config.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; //通用GPIO
- config.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模式为通用GPIO
- 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 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; //通用GPIO
- config.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);
- #endif
- EnableIRQ(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;
- //按键按下为0
- if(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");
- #endif
- LED_RGB_Init();
- // Button_Init();
- ButtonInterruptInit();
- // LPMTR2_Init();
- // LPIT1_CH3_Init();
- while (1)
- {
- }
- }
复制代码
代码下载
织女星开发板VEGA_Lite支持从4个核启动,所以在进行程序下载之前,要确认当前的启动模式和当前的工程是对应的。如当前工程是使用RISC-V RI5CY核来驱动GPIO,那么就需要配置芯片启动模式为RI5CY核启动。否则会不能下载。关于启动模式的修改可以参考:织女星开发板启动模式修改
总结
RV32M1芯片的GPIOE与其他几组GPIO配置方法稍有不同,使用时要特别注意。
参考资料
完
|