análisis 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

}

Para la parte RCU, puede ver la posición de la RCU en todo el chip EFM32 y comunicarse a través de AHB y ARM Cortex-M4

Bus de sistema AHB (Advanced High Performance Bus) , bus de rendimiento avanzado y bus periférico 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

Aquí hay algo de contenido sobre NVIC, NVIC (Controlador de interrupción vectorial anidado).

En la figura anterior, se puede ver que NVIC está integrado internamente en Cortex-M4. Preste atención a la diferencia entre este y el controlador de interrupción externo EXIT que usamos a menudo.

No hay mucho que decir aquí, solo la elección de macros aquí:

En SPEC vimos la descripción de NVIC

 

 

 

 

 

Para el nivel de pin de boot0 y boot1 en el hardware, se pueden seleccionar diferentes fuentes de arranque

 

Tenga en cuenta esta oración: la dirección de inicio del espacio de almacenamiento SRAM en el chip es 0x2000 0000, cuando se selecciona como fuente de inicio, en el código de inicialización de la aplicación,

Debe utilizar la tabla de excepciones NVIC y el registro de compensación para redirigir la tabla de vectores a SRAM.

Echemos un vistazo a nuestra selección de hardware.

 

 

BOOT0 está conectado a tierra y el nivel es 0, por lo que la fuente de inicio es la memoria FLash principal.Esta macro no debe definirse, vea si el código no está definido.

Mirando el código en sí

Entre las macros:

 

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

La dirección de RAM se asigna como 0x20000000

La dirección de la base de flash es 0x80000000

Esto puede corresponder a SPEC

 

Mirar de nuevo

/ * Desplazamiento de la base de la tabla de vectores * /

#define VECT_TAB_OFFSET 0x0000 / * Este valor debe ser un múltiplo de 0x200. * /

Esta es la dirección de desplazamiento de su flash, por ejemplo, la dirección base mencionada anteriormente. Si tiene un cargador de arranque y el espacio del cargador de arranque es 0x200, entonces debe agregar el desplazamiento del cargador de arranque aquí, y luego será suyo La dirección base final de la APLICACIÓN.

Cuando estaba desarrollando antes, el valor predeterminado era 0x2000, pero no tenía un cargador de arranque, lo que causaba problemas todo el tiempo. Una vez que establecía la interrupción, habría problemas. Sin embargo, configuré la interrupción externa en ese momento. No sé por qué afectó esto. Creo que el NVIC interno debería estar unido

 

Seguimiento:

#include "gd32e10x.h" Este archivo de encabezado se incluye en este archivo fuente Sytem_gd32e10x.c, preste atención a la configuración

Algunas macros deben definirse en el compilador o el código, y luego pueden combinarse con su placa.

Por ejemplo, en el archivo .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 */

¡Cuál usar debe confirmarse cuidadosamente!

Supongo que te gusta

Origin blog.csdn.net/yangkunhenry/article/details/104859374
Recomendado
Clasificación