官方链接:Arm Keil | Devices
1.本项目使用的是兆易创新 GD32F470IIH6 主控芯片,因此进入链接直接搜索到如下页面跳转到相应的页面搜索所使用的芯片型号且点击跳转到步骤2所示界面
2.点击GigaDevice,
3.点击CMSIS Packs,找到如下图所示的芯片型号,且点击75Device跳转到步骤4所示界面
4.选择Version History,选择一个你想要的版本下载即可,本项目例程使用的是3.0版本的芯片包
**GD官网链接:**http://www.gd32mcu.com/cn
1.点击资料下载下的应用软件
2.搜索栏搜索GD32F4xx,列表中找到如下图所示的文件下载
Examples
存放的是每个外设库的参考程序
Firmware
固件库核心文件
Template
官方固件库移植示例
Utilities
第三方固件驱动
注(本人使用的是VSCODE配合MDK一起开发)
2.使用mdk在Project文件夹下创建工程
2.1点击New μVidion Project(路径选取我们创建好的Project工程目录下)
工程名:GD32KeilPrj
2.2固件库文件移植
2.2.1找到此路径下的文件…/GD32F4xx_Firmware_Library_V3.0.4\Firmware\GD32F4xx_standard_peripheral
将其中的Include文件夹和Source文件夹移植到新建项目的FW目录下
2.2 .2 ARM\System目录下 应移植内容
…\CMSIS\GD\GD32F4xx\Include 将其中的gd32f4xx.h文件 system_gd32f4xx.h
…\CMSIS\GD\GD32F4xx\Source\ARM 下的对应的启动文件startup_gd32f450_470.s 依照各开发板找到对应的启动文件即可
…\CMSIS\GD\GD32F4xx\Source\system_ 目录下的gd32f4xx.c文件 system_gd32f4xx.c文件
GD32F4xx_Firmware_Library_V3.0.4\Template 下的gd32f4xx_it.c gd32f4xx_it.h gd32f4xx_libopt.h
/*******************************自己编写的gd32f470x_conf.h文件 此文件内容包含工程xxxx.h头文件*******************/
#ifndef _gd32f470_h_
#define _gd32f470_h_
/*********************************************************************************************************
* 包含头文件
*********************************************************************************************************/
#include "gd32f4xx_rcu.h"
#include "gd32f4xx_adc.h"
#include "gd32f4xx_can.h"
#include "gd32f4xx_crc.h"
#include "gd32f4xx_ctc.h"
#include "gd32f4xx_dac.h"
#include "gd32f4xx_dbg.h"
#include "gd32f4xx_dci.h"
#include "gd32f4xx_dma.h"
#include "gd32f4xx_exti.h"
#include "gd32f4xx_fmc.h"
#include "gd32f4xx_fwdgt.h"
#include "gd32f4xx_gpio.h"
#include "gd32f4xx_syscfg.h"
#include "gd32f4xx_i2c.h"
#include "gd32f4xx_iref.h"
#include "gd32f4xx_pmu.h"
#include "gd32f4xx_rtc.h"
#include "gd32f4xx_sdio.h"
#include "gd32f4xx_spi.h"
#include "gd32f4xx_timer.h"
#include "gd32f4xx_trng.h"
#include "gd32f4xx_usart.h"
#include "gd32f4xx_wwdgt.h"
#include "gd32f4xx_misc.h"
#include "gd32f4xx_enet.h"
#include "gd32f4xx_exmc.h"
#include "gd32f4xx_ipa.h"
#include "gd32f4xx_tli.h"
#endif
2.2.3 ARM/Systick目录下 应移植内容 最原始版本,不用移植此部分内容,
Systick定时器是一个常用的内置定时器,用于生成周期性的定时中断,通常用于实现基本的系统定时功能,,Systick定时器可以用于生成循环的中断,用于时间的计数,延时,定时等操作
主要用途
在这里我们重写Systick.c和Systick.h模块
/*********************************************************************************************************
* 模块名称:SysTick.h
* 摘 要:SysTick模块,包含SysTick模块初始化以及微秒和毫秒级延时函数
*********************************************************************************************************/
#ifndef _SYS_TICK_H_
#define _SYS_TICK_H_
/*****************************包含头文件 **********************************/
#include "gd32f470x_conf.h"
/*********************************************************************************************************
* API函数声明
*********************************************************************************************************/
void InitSysTick(void); //初始化SysTick模块
void DelayNus(__IO unsigned int nus); //微秒级延时函数
void DelayNms(__IO unsigned int nms); //毫秒级延时函数
#endif
/*********************************************************************************************************
* 模块名称:SysTick.c
* 摘 要:SysTick模块,包含SysTick模块初始化以及微秒和毫秒级延时函数
*********************************************************************************************************/
/*********************************************包含头文件***************************************************/
#include "SysTick.h"
/*********************************************************************************************************
* 私有变量定义
*********************************************************************************************************/
static __IO unsigned int s_iTimDelayCnt = 0;
/*********************************************************************************************************
* 私有函数声明
*********************************************************************************************************/
static void TimDelayDec(void); //延时计数
/*********************************************************************************************************
* 私有函数实现
*********************************************************************************************************/
/*********************************************************************************************************
* 函数名称:TimDelayDec
* 函数功能:延时计数
* 输入参数:void
* 输出参数:void
* 返 回 值:void
* 注 意:在SysTick中断服务函数SysTick_Handler中调用
*********************************************************************************************************/
static void TimDelayDec(void)
{
if(s_iTimDelayCnt != 0) //延时计数器的数值不为0
{
s_iTimDelayCnt--; //延时计数器的数值减1
}
}
/*********************************************************************************************************
* 函数名称:SysTick_Handler
* 函数功能:SysTick中断服务函数
* 输入参数:void
* 输出参数:void
* 返 回 值:void
*********************************************************************************************************/
void SysTick_Handler(void)
{
TimDelayDec(); //延时计数函数
}
/*********************************************************************************************************
* API函数实现
*********************************************************************************************************/
/*********************************************************************************************************
* 函数名称:InitSysTick
* 函数功能:初始化SysTick模块
* 输入参数:void
* 输出参数:void
* 返 回 值:void
* 创建日期:2022年01月01日
* 注 意:SystemCoreClock / 1000 1ms中断一次(计数1000次为1s,每计一次位1/1000s=1ms)
* SystemCoreClock / 4000 0.25ms中断一次(计数4000次为1s,每计一次位1/4000s=0.25ms)
* SystemCoreClock / 100000 10us中断一次(计数100000次为1s,每计一次位1/100000s=10us)
* SystemCoreClock / 1000000 1us中断一次(计数1000000次为1s,每计一次位1/1000000s=1us)
*********************************************************************************************************/
void InitSysTick( void )
{
if (SysTick_Config(SystemCoreClock / 1000U)) //配置系统滴答定时器1ms中断一次
{
while(1) //错误发生的情况下,进入死循环
{
}
}
}
/*********************************************************************************************************
* 函数名称:DelayNms
* 函数功能:毫秒级延时函数
* 输入参数:nms
* 输出参数:void
* 返 回 值:void
* 创建日期:2022年01月01日
* 注 意:
*********************************************************************************************************/
void DelayNms(__IO unsigned int nms)
{
s_iTimDelayCnt = nms; //将延时计数器s_iTimDelayCnt的数值赋为nms
SysTick->VAL = SysTick->LOAD; //避免第一个ms不准
while(s_iTimDelayCnt != 0) //延时计数器的数值为0时,表示延时了nms,跳出while语句
{
}
}
/*********************************************************************************************************
* 函数名称:DelayNus
* 函数功能:微秒级延时函数
* 输入参数:nus
* 输出参数:void
* 返 回 值:void
* 创建日期:2022年01月01日
* 注 意:
*********************************************************************************************************/
void DelayNus(__IO unsigned int nus)
{
unsigned int s_iTimCnt = nus; //定义一个变量s_iTimCnt作为延时计数器,赋值为nus
unsigned short i; //定义一个变量作为循环计数器
while(s_iTimCnt != 0) //延时计数器s_iTimCnt的值不为0
{
for(i = 0; i < 46; i++) //空循环,产生延时功能
{
}
s_iTimCnt--; //成功延时1us,变量s_iTimCnt减1
}
}
2.2.4 ARM/NVIC 目录下应移植内容 关于此部分将会在后期介绍到,代码如未曾涉及到中断,可不引入此目录下文件
/*********************************************************************************************************
* 模块名称:NVIC.h
* 摘 要:NVIC模块,包含NVIC中断分组设置
*********************************************************************************************************/
#ifndef _NVIC_H_
#define _NVIC_H_
void InitNVIC(void); //初始化NVIC模块
#endif
/*********************************************************************************************************
* 模块名称:NVIC.c
* 摘 要:NVIC模块,包含NVIC中断分组设置
*********************************************************************************************************/
/*********************************************************************************************************
* 包含头文件
*********************************************************************************************************/
#include "NVIC.h"
#include "gd32f470x_conf.h"
static void ConfigNVIC(void); //配置NVIC
/*********************************************************************************************************
* 函数名称:ConfigNVIC
* 函数功能:配置NVIC
*********************************************************************************************************/
static void ConfigNVIC(void)
{
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
}
/*********************************************************************************************************
* 函数名称:InitNVIC
* 函数功能:初始化NVIC模块
*********************************************************************************************************/
void InitNVIC(void)
{
ConfigNVIC(); //配置NVIC
}
2.3在工具栏中找到下图中框选到的模组
2.5点击图示魔法棒
按图示添加宏定义,
USE_STDPERIPH_DRIVER,GD32F470,USE_USB_FS
为什么要在这么添加这三个宏定义呢? 打开工程,ctrl+f 搜索 USE_STDPERIPH_DRIVER会跳出如下代码块
/* define marco USE_STDPERIPH_DRIVER */
#if !defined USE_STDPERIPH_DRIVER
#define USE_STDPERIPH_DRIVER
#endif
#ifdef USE_STDPERIPH_DRIVER
#include "gd32f4xx_libopt.h"
#endif /* USE_STDPERIPH_DRIVER */
我们再跳转到:gd32f4xx_libopt.h 文件中看看,会有如下代码
/*
Copyright (c) 2022, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#ifndef GD32F4XX_LIBOPT_H
#define GD32F4XX_LIBOPT_H
#if defined (GD32F450) || defined (GD32F405) || defined (GD32F407) || defined (GD32F470) || defined (GD32F425) || defined (GD32F427)
#include "gd32f4xx_rcu.h"
#include "gd32f4xx_adc.h"
#include "gd32f4xx_can.h"
#include "gd32f4xx_crc.h"
#include "gd32f4xx_ctc.h"
#include "gd32f4xx_dac.h"
#include "gd32f4xx_dbg.h"
#include "gd32f4xx_dci.h"
#include "gd32f4xx_dma.h"
#include "gd32f4xx_exti.h"
#include "gd32f4xx_fmc.h"
#include "gd32f4xx_fwdgt.h"
#include "gd32f4xx_gpio.h"
#include "gd32f4xx_syscfg.h"
#include "gd32f4xx_i2c.h"
#include "gd32f4xx_iref.h"
#include "gd32f4xx_pmu.h"
#include "gd32f4xx_rtc.h"
#include "gd32f4xx_sdio.h"
#include "gd32f4xx_spi.h"
#include "gd32f4xx_timer.h"
#include "gd32f4xx_trng.h"
#include "gd32f4xx_usart.h"
#include "gd32f4xx_wwdgt.h"
#include "gd32f4xx_misc.h"
#endif
#if defined (GD32F450) || defined (GD32F470)
#include "gd32f4xx_enet.h"
#include "gd32f4xx_exmc.h"
#include "gd32f4xx_ipa.h"
#include "gd32f4xx_tli.h"
#endif
#if defined (GD32F407) || defined (GD32F427)
#include "gd32f4xx_enet.h"
#include "gd32f4xx_exmc.h"
#endif
#endif /* GD32F4XX_LIBOPT_H */
搜索USE_USB_FS 前期初级项目,我们未曾用到usb,所以在项目工程中是无法检索到的,但不妨碍我们先添加这个宏定义
/*!
\file usb_conf.h
\brief USB core driver basic configuration
\version 2020-08-01, V3.0.0, firmware for GD32F4xx
*/
/*
Copyright (c) 2020, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#ifndef __USB_CONF_H
#define __USB_CONF_H
#include
#include "gd32f4xx.h"
//#include "gd32f450i_eval.h"
/* USB Core and PHY interface configuration */
/****************** USB FS PHY CONFIGURATION *******************************
* The USB FS Core supports one on-chip Full Speed PHY.
* The USE_EMBEDDED_PHY symbol is defined in the project compiler preprocessor
* when FS core is used.
*******************************************************************************/
#ifdef USE_USB_FS
#define USB_FS_CORE
#endif
#ifdef USE_USB_HS
#define USB_HS_CORE
#endif /* USE_USB_HS */
/*******************************************************************************
* FIFO Size Configuration in Device mode
*
* (i) Receive data FIFO size = RAM for setup packets +
* OUT endpoint control information +
* data OUT packets + miscellaneous
* Space = ONE 32-bits words
* --> RAM for setup packets = 10 spaces
* (n is the nbr of CTRL EPs the device core supports)
* --> OUT EP CTRL info = 1 space
* (one space for status information written to the FIFO along with each
* received packet)
* --> Data OUT packets = (Largest Packet Size / 4) + 1 spaces
* (MINIMUM to receive packets)
* --> OR data OUT packets = at least 2* (Largest Packet Size / 4) + 1 spaces
* (if high-bandwidth EP is enabled or multiple isochronous EPs)
* --> Miscellaneous = 1 space per OUT EP
* (one space for transfer complete status information also pushed to the
* FIFO with each endpoint's last packet)
*
* (ii) MINIMUM RAM space required for each IN EP TX FIFO = MAX packet size for
* that particular IN EP. More space allocated in the IN EP TX FIFO results
* in a better performance on the USB and can hide latencies on the AHB.
*
* (iii) TXn min size = 16 words. (n:Transmit FIFO index)
*
* (iv) When a TxFIFO is not used, the Configuration should be as follows:
* case 1: n > m and Txn is not used (n,m:Transmit FIFO indexes)
* --> Txm can use the space allocated for Txn.
* case 2: n < m and Txn is not used (n,m:Transmit FIFO indexes)
* --> Txn should be configured with the minimum space of 16 words
*
* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top
* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
*
* (vi) In HS case12 FIFO locations should be reserved for internal DMA registers
* so total FIFO size should be 1012 Only instead of 1024
*******************************************************************************/
#ifdef USB_FS_CORE
#define RX_FIFO_FS_SIZE 128
#define TX0_FIFO_FS_SIZE 64
#define TX1_FIFO_FS_SIZE 128
#define TX2_FIFO_FS_SIZE 0
#define TX3_FIFO_FS_SIZE 0
#endif /* USB_FS_CORE */
#ifdef USB_HS_CORE
#define RX_FIFO_HS_SIZE 512
#define TX0_FIFO_HS_SIZE 128
#define TX1_FIFO_HS_SIZE 372
#define TX2_FIFO_HS_SIZE 0
#define TX3_FIFO_HS_SIZE 0
#define TX4_FIFO_HS_SIZE 0
#define TX5_FIFO_HS_SIZE 0
#ifdef USE_ULPI_PHY
#define USB_ULPI_PHY_ENABLED
#endif
#ifdef USE_EMBEDDED_PHY
#define USB_EMBEDDED_PHY_ENABLED
#endif
// #define USB_HS_INTERNAL_DMA_ENABLED
// #define USB_HS_DEDICATED_EP1_ENABLED
#endif /* USB_HS_CORE */
#define USB_SOF_OUTPUT 1
#define USB_LOW_POWER 0
//ʹÓÃÄÚ²¿48MHz¾§Õñ
#define USE_IRC48M
//#define VBUS_SENSING_ENABLED
//#define USE_HOST_MODE
#define USE_DEVICE_MODE
//#define USE_OTG_MODE
#ifndef USB_FS_CORE
#ifndef USB_HS_CORE
#error "USB_HS_CORE or USB_FS_CORE should be defined!"
#endif
#endif
#ifndef USE_DEVICE_MODE
#ifndef USE_HOST_MODE
#error "USE_DEVICE_MODE or USE_HOST_MODE should be defined!"
#endif
#endif
#ifndef USE_USB_HS
#ifndef USE_USB_FS
#error "USE_USB_HS or USE_USB_FS should be defined!"
#endif
#endif
/* In HS mode and when the DMA is used, all variables and data structures dealing
with the DMA during the transaction process should be 4-bytes aligned */
#ifdef USB_HS_INTERNAL_DMA_ENABLED
#if defined (__GNUC__) /* GNU Compiler */
#define __ALIGN_END __attribute__ ((aligned (4)))
#define __ALIGN_BEGIN
#else
#define __ALIGN_END
#if defined (__CC_ARM) /* ARM Compiler */
#define __ALIGN_BEGIN __align(4)
#elif defined (__ICCARM__) /* IAR Compiler */
#define __ALIGN_BEGIN
#elif defined (__TASKING__)/* TASKING Compiler */
#define __ALIGN_BEGIN __align(4)
#endif /* __CC_ARM */
#endif /* __GNUC__ */
#else
#define __ALIGN_BEGIN
#define __ALIGN_END
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* __packed keyword used to decrease the data type alignment to 1-byte */
#if defined (__CC_ARM) /* ARM Compiler */
#define __packed __packed
#elif defined (__ICCARM__) /* IAR Compiler */
#define __packed __packed
#elif defined (__GNUC__) /* GNU Compiler */
#ifndef __packed
#define __packed __attribute__ ((__packed__))
#endif
#elif defined (__TASKING__) /* TASKING Compiler */
#define __packed __unaligned
#endif /* __CC_ARM */
#endif /* __USB_CONF_H */
其实 USE_STDPERIPH_DRIVER 表示的就是使用标准库的意思,GD32F470 表示我们使用的芯片型号 USE_USB_FS表示标准外设版USB驱动库 定义了主机的与外设的一个接口FIFO大小,以及接口匹配速度
D */
/* __packed keyword used to decrease the data type alignment to 1-byte */
#if defined (__CC_ARM) /* ARM Compiler */
#define __packed __packed
#elif defined (__ICCARM__) /* IAR Compiler */
#define __packed __packed
#elif defined (__GNUC__) /* GNU Compiler */
#ifndef __packed
#define __packed __attribute__ ((__packed__))
#endif
#elif defined (__TASKING__) /* TASKING Compiler */
#define __packed __unaligned
#endif /* __CC_ARM */
#endif /* __USB_CONF_H */
其实 USE_STDPERIPH_DRIVER 表示的就是使用标准库的意思,GD32F470 表示我们使用的芯片型号 USE_USB_FS表示标准外设版USB驱动库 定义了主机的与外设的一个接口FIFO大小,以及接口匹配速度
2.6添加相关文件的头文件到路径中