/*!\brief setup the microcontroller system, initialize the system\param[in] none\param[out] none\retval none
*/
void SystemInit (void)
{/* FPU settings *//* 如果要使用户FPU,则在gd32e10x.h中定义__FPU_PRESENT ,看供应商提供的文档中有关于FPU设置的方法 */
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif/* reset the RCU clock configuration to the default reset state *//* Set IRC8MEN bit *//* 下面对复位和时钟单元的部分寄存器进行初始化。这里对RCU_CTL这个寄存器做置位,来启动IRC 8M RC振荡器系统启动的时候就默认用8M的RC振荡器来工作,至于后面时钟怎么选,后面再说。不过想一下前面汇编程序是在system init之前是怎么执行的?比如其中有堆栈的空间SPACE,这个SPACE是怎么做的当时都没有时钟,可能还是要了解一下启动过程 */RCU_CTL |= RCU_CTL_IRC8MEN;/* Reset CFG0 and CFG1 registers */RCU_CFG0 = 0x00000000U;RCU_CFG1 = 0x00000000U;/* Reset HXTALEN, CKMEN, PLLEN, PLL1EN and PLL2EN bits */RCU_CTL &= ~(RCU_CTL_PLLEN |RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);/* disable all interrupts */RCU_INT = 0x00ff0000U;/* reset HXTALBPS bit */RCU_CTL &= ~(RCU_CTL_HXTALBPS);//高速晶体振荡器(HXTAL)时钟旁路模式/* configure the system clock source, PLL Multiplier, AHB/APBx prescalers and Flash settings */system_clock_config();//这里我用的是PLL倍频出的48M,最终调用的system_clock_48m_irc8m,这里其实就是初始化PLL,等待PLL稳定下来提供稳定的时钟源//下面是重点,下面单独说
#ifdef VECT_TAB_SRAMnvic_vector_table_set(NVIC_VECTTAB_RAM,VECT_TAB_OFFSET);
#elsenvic_vector_table_set(NVIC_VECTTAB_FLASH,VECT_TAB_OFFSET);
#endif}
对于RCU部分,可以看下RCU在整个EFM32 芯片中的位置,通过AHB和ARM Cortex-M4进行通信
AHB(Advanced High performance Bus)系统总线,高级性能总线和APB(Advanced Peripheral Bus)外围总线
#ifdef VECT_TAB_SRAMnvic_vector_table_set(NVIC_VECTTAB_RAM,VECT_TAB_OFFSET);
#elsenvic_vector_table_set(NVIC_VECTTAB_FLASH,VECT_TAB_OFFSET);
#endif
VECT_TAB_SRAM
这里是关于NVIC的一些内容,NVIC (Nested Vectored Interrupt Controller).
这里从上面图中就可以看出NVIC是Cortex-M4内部集成的,注意它和我们经常用到的外部中断控制器EXIT的区别。
这里不多说,只说这里关于宏的选择:
在SPEC上我们看到关于NVIC的说明
对于硬件上boot0 和boot1的引脚电平,可以选择不同的引导源
注意这句话:片上SRAM存储空间的起始地址是0x2000 0000,当他被选择为引导源时,在应用程序初始化代码中,
你必须使用NVIC异常表和偏移寄存器来将向量表重定向到SRAM中。
这里看下我们硬件的选择
BOOT0是接地,电平是0,所以引导源是主FLash存储器,这个宏应该不要定义,看看代码确实没有定义。
在看代码本身
其中的宏:
/* constants definitions */
/* set the RAM and FLASH base address */
#define NVIC_VECTTAB_RAM ((uint32_t)0x20000000) /*!< RAM base address */
#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000) /*!< Flash base address */
RAM的地址被映射为0x20000000
FLash基地址是0x80000000
这里可以对应SPEC上
再看
/* Vector Table base offset */
#define VECT_TAB_OFFSET 0x0000 /* This value must be a multiple of 0x200. */
这个是你比如说flash上的偏移地址,前面说的基地址,如果你有bootloader,bootloader的空间是0x200,那么你这里就要把bootloader的偏移给加上,加上之后才是你的APP的最终基地址。
之前在开发的时候,这里默认写的是0x2000,但是我又没有bootloader,导致一直有问题,一旦设置中断就出现问题,但是我当时设置的是外部中断,不知道为什么影响到这里,外部的和内部的NVIC应该在一起的吧,我想
后续:
#include "gd32e10x.h" 这个头文件被包含在此Sytem_gd32e10x.c源文件中,注意其中的设置
有的宏是需要在编译器中或者代码中定义的,定义之后才能和你的板子匹配
比如说.h文件中的
/* define value of high speed crystal oscillator (HXTAL) in Hz */
#if !defined HXTAL_VALUE#ifdef GD32E103V_EVAL#define HXTAL_VALUE ((uint32_t)8000000) /*!< value of the external oscillator in Hz */#define HXTAL_VALUE_8M HXTAL_VALUE#elif defined(GD32E103R_START) || defined(GD32E103C_START) || defined(GD32E103T_START)#define HXTAL_VALUE ((uint32_t)25000000) /*!< value of the external oscillator in Hz */#define HXTAL_VALUE_25M HXTAL_VALUE#else#error "Please select the target board type used in your application (in gd32e10x.h file)"#endif
#endif /* high speed crystal oscillator value */
到底用哪个,需要仔细确认的!