system_gd32e10x.c分析

/*!
    \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 */

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

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值