EFM32PG1B esos pozos sobre RTCC y EM4

EFM32PG1B esos pozos sobre RTCC y EM4

Pit 1: inicialización RTCC

 Todos estamos familiarizados con RTC. Por lo general, no lo uso aquí como la llamada función de cronometraje de año, mes y día. Generalmente uso RTC como el tiempo de activación del dispositivo. Entonces, ¿cómo inicializar el RTCC de EFM32PG1B? He resumido los siguientes puntos:
1. Selección del reloj
2. Selección del modo de conteo
3. Configuración del valor del conteo
4. Interrumpir la apertura
 Permítanme hablar sobre el primer punto: El árbol del reloj de EFM32 se sintió más complicado cuando comencé, pero en realidad fue cuidadoso Eche un vistazo, sentirá que su árbol de reloj es así. Sólo mira la foto.
Árbol de reloj RTCC
 Como se puede ver en la figura, hay tres fuentes de reloj RTCC: LFXO, LFRCO y ULFRCO. Los dos primeros son 32768 hz, el último 1000 hz. Aquí elegimos ULFRCO como la fuente de reloj de LFECLK, y luego habilitamos la fuente de reloj RTCC para hacerlo.En resumen, mire la imagen, siga las líneas y configure una por una.

	  CMU_ClockSelectSet(cmuClock_LFE, cmuSelect_ULFRCO);
	  CMU_ClockEnable(cmuClock_RTCC, true);

 Cuando se selecciona el reloj, llega al segundo punto: la elección del modo de conteo. Aquí, puede elegir el modo de conteo CNT normal. En este modo, el temporizador comparará RTCC_CNT con RTCC_CC [x] _CCV, y si son iguales, se activará la interrupción RTCC. Elegí el canal 1.

	  RTCC_Init_TypeDef rtccInit = RTCC_INIT_DEFAULT;
	  RTCC_CCChConf_TypeDef rtccInitCompareChannel = RTCC_CH_INIT_COMPARE_DEFAULT;
	  RTCC_ChannelInit(1, &rtccInitCompareChannel);
	  // Initialize and start counting
	  RTCC_Init(&rtccInit);
#define RTCC_INIT_DEFAULT                                                   \
{                                                                           \
  false,     /* Start counting when init done.                           */  \
  false,    /* Disable RTCC during debug halt.                          */  \
  false,    /* Disable precounter wrap on ch. 0 CCV value.              */  \
  false,    /* Disable counter wrap on ch. 1 CCV value.                 */  \
  rtccCntPresc_1, /* 977 us per tick.                                  */  \
  rtccCntTickPresc, /* Counter increments according to prescaler value. */  \
  false,    /* No RTCC oscillator failure detection.                    */  \
  rtccCntModeNormal, /* Normal RTCC mode.                               */  \
  false,    /* No leap year correction.                                 */  \
}
#define RTCC_CH_INIT_COMPARE_DEFAULT                                        \
{                                                                           \
  rtccCapComChModeCompare,     /* Select output compare mode.     */        \
  rtccCompMatchOutActionToggle, /* Create pulse on compare match.  */        \
  rtccPRSCh0,                  /* PRS channel 0 (not used).       */        \
  rtccInEdgeNone,              /* No edge detection.              */        \
  rtccCompBaseCnt,             /* Counter comparison base.        */        \
  0,                           /* No compare mask bits set.       */        \
  rtccDayCompareModeMonth      /* Don't care */                             \
}

 El tercer punto es la configuración del valor de conteo, es decir, la frecuencia con la que se activa la interrupción RTCC. Elegimos una fuente de reloj de frecuencia ultrabaja de 1 kHz, y cada CNT tarda 1 milisegundo en aumentar en 1. Entonces es relativamente simple, supongamos que necesito 30 segundos para activar una interrupción, luego:

	RTCC_CounterSet(0);//CNT清零
	RTCC_ChannelCCVSet(1, 30*1000-1);

 Todo está listo, solo el último paso: habilite las interrupciones requeridas, no hay contenido técnico, directamente en el código, aquí para enfatizar un punto, nuestro propósito de usar RTCC es despertar el dispositivo del estado EM4. Por lo tanto, ¡debe agregarse la siguiente oración! ! !

RTCC_EM4WakeupEnable(true);//使能EM4唤醒

 Luego habilita la interrupción

	RTCC_IntClear(RTCC_IF_CC1);
	RTCC_IntEnable(RTCC_IEN_CC1);
	NVIC_ClearPendingIRQ(RTCC_IRQn);
	NVIC_EnableIRQ(RTCC_IRQn);
	RTCC_Enable(true);

 La anterior es la configuración inicial de todos los RTCC La configuración anterior es para despertar del estado EM4.

Pit 2: inicialización del modo de bajo consumo de energía EM4

 Me he enfrentado a esto durante varios días, porque hay muy poca información sobre esta placa en Internet. La única información también dice que la activación de esta serie de chips en modo EM4 solo se puede hacer a través de Pin interrupt. Pero de acuerdo con el manual de referencia, el reloj RTCC y la interrupción pueden activarse y activarse en EM4. Así que no dije nada, solo míralo poco a poco.
Inserte la descripción de la imagen aquí
 Por cierto, EM4 tiene dos modos: EM4H y EM4S. No necesitamos apagar el dispositivo, por lo que un bajo consumo de energía es suficiente, elija EM4H.
 ¿Cuáles son los pasos de inicialización? En realidad, es relativamente simple. Solo se necesita un registro: EMU_EM4CTRL se refiere al
significado específico de cada bit en la figura siguiente.
Inserte la descripción de la imagen aquí

  	//进入EM4模式
  	EMU_EM4Init_TypeDef em4Init = EMU_EM4INIT_DEFAULT;
  	EMU_EM4Init(&em4Init);
#define EMU_EM4INIT_DEFAULT                                                                \
{                                                                                          \
  false,                             /* Retain LFXO configuration upon EM4 entry */        \
  false,                             /* Retain LFRCO configuration upon EM4 entry */       \
  false,                              /* Retain ULFRCO configuration upon EM4 entry */      \
  emuEM4Hibernate,                     /* Use EM4 shutoff state */                           \
  emuPinRetentionDisable,            /* Do not retain pins in EM4 */                       \
}

Es simple

Pit 3: habilitación del modo EM4

 Esta es la razón por la que me enfrenté durante varios días. La razón es que era vago. En este paso, usé directamente la función de biblioteca sin mirar el contenido de la función de biblioteca, lo que me llevó a muchos desvíos.

void EMU_EnterEM4H(void)
{
    
    
  BUS_RegBitWrite(&EMU->EM4CTRL, _EMU_EM4CTRL_EM4STATE_SHIFT, 1);
  EMU_EnterEM4();
}

 El problema radica en la subfunción EMU_EnterEM4 ();
 esta función puede tener algunos errores en el dispositivo, y se han agregado algunas declaraciones que son inútiles para el proyecto, como:
__disable_irq ();
esta oración causó directamente que mi interrupción RTCC fallara. Juega un papel, el dispositivo se convierte en ladrillo después de ingresar al modo de suspensión EM4, debe encenderse nuevamente para POR.
 De hecho, es muy sencillo ingresar EM4. Sigue siendo el registro EMU_EM4CTRL. El 17:16 de este registro se encarga de esto. Solo necesita escribir estos dos bits secuencialmente en 2, 3, 2, 3, 2, 3, 2, 3 y 2. Okay

  int i;
  uint32_t em4seq2 = (EMU->EM4CTRL & (~0x30000))
                     | (2 << 16);
  uint32_t em4seq3 = (EMU->EM4CTRL & (~0x30000))
                     | (3 << 16);
  EMU_Unlock();
  for (i = 0; i < 4; i++)
  {
    
    
    EMU->EM4CTRL = em4seq2;
    EMU->EM4CTRL = em4seq3;
  }
  EMU->EM4CTRL = em4seq2;

 Eso es todo, ¡espero que ayude! ! ! Mi estilo nunca ha sido filosófico, por lo que aquellos que deseen filosofar solo pueden usar mi código como referencia. El conocimiento real debe ser explorado por uno mismo, no sea filosófico.

Supongo que te gusta

Origin blog.csdn.net/m0_38127906/article/details/107238902
Recomendado
Clasificación