system_gd32e10x.c分析

Sela ·
更新时间:2024-09-21
· 852 次阅读

/*! \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_SRAM nvic_vector_table_set(NVIC_VECTTAB_RAM,VECT_TAB_OFFSET); #else nvic_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_SRAM nvic_vector_table_set(NVIC_VECTTAB_RAM,VECT_TAB_OFFSET); #else nvic_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 */

到底用哪个,需要仔细确认的!


作者:yangkunhenry



e1 system

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章